Difference between revisions of "Buffers in LuaTeX"

From Wiki
Jump to navigation Jump to search
(Describe the buffers.* commmands)
 
(Extended section to discuss how to access buffer names from lua based on mailing list thread.)
Line 39: Line 39:
 
* <code>buffers.exists(b)</code>: Returns the name of the buffer if it exists, or else <code>nil</code>.
 
* <code>buffers.exists(b)</code>: Returns the name of the buffer if it exists, or else <code>nil</code>.
 
* <code>buffers.collectcontent(names, seperator)</code>: Returns the contents of the buffers in <code>names</code>, seperated by <code>seperator</code> (<code>'\n'</code> by default). Names can be either a table, or a comma-seperated string (surrounding braces are automatically removed &mdash; see <code>parsers.settings_to_array</code> in <code>util-prs.lua</code>.
 
* <code>buffers.collectcontent(names, seperator)</code>: Returns the contents of the buffers in <code>names</code>, seperated by <code>seperator</code> (<code>'\n'</code> by default). Names can be either a table, or a comma-seperated string (surrounding braces are automatically removed &mdash; see <code>parsers.settings_to_array</code> in <code>util-prs.lua</code>.
 +
 +
== Accessing buffer names ==
 +
 +
From the [https://mailman.ntg.nl/pipermail/ntg-context/2019/093692.html mailing list]:
 +
 +
It's not easy to access buffer names from ConTeXt because ConTeXt stores the buffers in a local variable <code>cache</code> which is an upvalue for all the other functions. However, you can use the Lua <code>debug</code> library to access upvalues. The <code>buffers.erase</code> function only has a single upvalue which is <code>cache</code>, making it easy to extract all the buffer names from that. However, you can't get them in the order of declaration because <code>cache</code> 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:
 +
 +
<code>context --debug test.tex</code>
 +
 +
MWE:
 +
 +
<texcode>
 +
\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
 +
</texcode>

Revision as of 02:02, 8 January 2019

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