Buffers in LuaTeX

From ConTeXt wiki

A bit about buffers

Buffers are named chunks of text, saved by ConTeXt to be retrieved by the user later. They are usually defined as follows:

% Start a buffer with a custom name
\startbuffer[Marie]
This is the text in the buffer 'Marie'
\stopbuffer

% Define the \start...\stopPierre environment
\def\startPierre
    {\dostartbuffer[Pierre][startPierre][stopPierre]}

% Give \stopPierre some meaning if you want to do something with the buffer right away.
%\def\stopPierre
%   {\getbuffer[Pierre]}}

\startPierre
This is the text in the buffer 'Pierre'.
\stopPierre
\getbuffer[Pierre] % Print typeset contents

\startPierre
Now this is the text in the buffer 'Pierre', instead.
\stopPierre
\typebuffer[Pierre] % Print verbatim contents

The LuaTeX buffers.* commands

These commands were all found in the source code: buff-ini.lua

  • buffers.getcontent(b): Get the contents of the buffer b, or the empty string if the buffer does not exist.
  • buffers.raw(b): Synonym for buffers.getcontent(b).
  • buffers.getlines(b): Equivalent to splitlines(buffers.getcontent(b)).
  • buffers.erase(b): Delete the buffer b (not just its contents).
  • buffers.assign(b, text, catcodes): Set the contents of buffer b to text, using catcodetable catcodes
  • buffers.append(b, text): Append text to buffer b.
  • buffers.exists(b): Returns the name of the buffer if it exists, or else nil.
  • buffers.collectcontent(names, seperator): Returns the contents of the buffers in names, seperated by seperator ('\n' by default). Names can be either a table, or a comma-seperated string (surrounding braces are automatically removed — see parsers.settings_to_array in util-prs.lua.

Accessing buffer names

From the mailing list:

It's not easy to access buffer names from ConTeXt because ConTeXt stores the buffers in a local variable cache which is an upvalue for all the other functions. However, you can use the Lua debug library to access upvalues. The buffers.erase function only has a single upvalue which is cache, making it easy to extract all the buffer names from that. However, you can't get them in the order of declaration because cache is a hashmap and not an array. Moreover, ConTeXt is usually in sandboxing mode. To get access to the debug library you have to run ConTeXt with:

context --debug test.tex

MWE:

\starttext

\startbuffer[ex1]
Buffer 1
\stopbuffer

\startbuffer[ex2]
Buffer 2
\stopbuffer

\startluacode
local _, cache = debug.getupvalue(buffers.erase,1)
local names = {}
for name,_ in pairs(cache) do
    names[#names+1] = name
end
context(table.concat(names,", "))
\stopluacode
% Prints ex2, ex1 (but specific order is not guaranteed)

\stoptext