th1-sgb  th1_ob

TH1 "ob" (Output Buffering) API

The "ob" API mimics the PHP output buffering fairly closely, providing these features:

  • Redirect output from puts and friends to a buffer. Any output which goes through the C-level Th1_Output() function gets captured this way.
  • Fetch the buffer as a string or discard it (as you wish).
  • Supports nesting buffering arbitrarily deep, but each level which gets opened must also be closed by the scripter.

To add it to an interpreter, the library must have been built with TH1_ENABLE_OB defined (to any value) and the client must call th1_register_ob(), passing it his interpreter instance. Note that th1_register_ob() is only declared and defined if TH1_ENABLE_OB is defined (which it is, by default, in th1.h).

Example usage:

(note the <TH1> tags - this input is intended for Th1_Render(), not Th1_Eval(). The former filters "text documents" with embedded TH1 and the latter runs "plain" script code.)

<th1>
puts "this is unbuffered"
ob push # or: ob start (same thing)
# all output until the next ob start|end gets collected
# in a buffer...
</th1>

this is buffered

<th1>
puts "current buffer level = " [ob level] "\n"
puts "this part is also collected in the buffer."

# Collect the buffer's contents:
set buf [ob get pop]
# That is equivalent to:
#  set buf [ob get]
#  ob pop

puts "\nThis is not buffered, but we buffered: $buf\n"
</th1>

The functions are summarized below...

ob push|start

push and start are aliases ("start" comes from the PHP API, but "push" is probably more natural to those working with th1).

ob start pushes a level of buffering onto the buffer stack, such that future calls which generate output through the th1-internal mechanism will have it transparently redirected to the current buffer.

It is important that every call to ob start be followed up (eventually) by either ob end or ob get end.

ob pop|end

pop and end are aliases ("end" comes from the PHP API, but "pop" is probably more natural to those working with th1).

This discards any current buffered contents and reverts the output state to the one it had before the previous ob start. i.e. that might be another buffering level or it might be the th1-normal output mechanism.

ob clean

This discards the current contents of the current buffer level but does not change the buffer stack level.

ob get

This fetches the current contents as a string. It optionally accepts either end (or its alias pop) or clean, in which cases it behaves like either ob end|pop or ob clean, respectively, in addition to returning the buffer contents. i.e. ob get clean will fetch the contents and clean up the buffer, but does not change the buffering level, whereas ob get end|pop pops the buffer off the stack after fetching its contents.

ob level

Returns the current buffering level (0 if not buffering).

ob flush

It is not expected that this will be useful all that often, but for the cases where it is, here's how it works: this behaves as if we fetched the buffer state (ob get), reverted TH1 to its previous output mechanism, push the buffer state to TH1, revert TH1 back to the current buffering state, and then clear the current buffer contents (like ob clean). This does not change the buffering level, though it temporarily behaves as if it does.

In other words, this function pushes the current buffer contents to the next-lower output mechanism (which may be another ob buffering level, it might be be fwrite(stdout), or whatever output mechanism the library user installed for the interpreter).