Difference between revisions of "Buffers in LuaTeX"
(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 — 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 — 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 bufferb
, or the empty string if the buffer does not exist.buffers.raw(b)
: Synonym forbuffers.getcontent(b)
.buffers.getlines(b)
: Equivalent tosplitlines(buffers.getcontent(b))
.buffers.erase(b)
: Delete the bufferb
(not just its contents).buffers.assign(b, text, catcodes)
: Set the contents of bufferb
totext
, using catcodetablecatcodes
buffers.append(b, text)
: Appendtext
to bufferb
.buffers.exists(b)
: Returns the name of the buffer if it exists, or elsenil
.buffers.collectcontent(names, seperator)
: Returns the contents of the buffers innames
, seperated byseperator
('\n'
by default). Names can be either a table, or a comma-seperated string (surrounding braces are automatically removed — seeparsers.settings_to_array
inutil-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