Difference between revisions of "Buffers in LuaTeX"

From Wiki
Jump to navigation Jump to search
(Describe the buffers.* commmands)
 
m (category again)
 
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
== A bit about buffers ==
 
== 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:
+
Buffers are named chunks of text, saved by ConTeXt to be retrieved by the user later. They are meant for storing information not being typeset, yet. Typeset material is stored in [[TeX Boxes|Boxes]]. Buffers are usually defined as follows:
 
<texcode>
 
<texcode>
 
% Start a buffer with a custom name
 
% Start a buffer with a custom name
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>
 +
 +
[[Category:ConTeXt]] [[Category:Basics]]

Latest revision as of 09:00, 9 March 2021

A bit about buffers

Buffers are named chunks of text, saved by ConTeXt to be retrieved by the user later. They are meant for storing information not being typeset, yet. Typeset material is stored in Boxes. Buffers 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