4

I am learning ConTeXt. One of the reasons that brought me in is the idea of buffers. So far, I was using datatool package to obtain similar functionalities (with the overhead cost involved).

I wonder, if there is an command, or option, that would allow to append content to already used buffer other than saving the buffer with \savebuffer as .tex file and then \input it again.

I hope I am stating the problem clearly. Hopefully MWE will illustrate that too:

MWE:

\starttext

\definebuffer[MyBuffer]
\startbuffer[MyBuffer]
First part of buffer content.
\stopbuffer

\savebuffer[MyBuffer]
[mybuffer.tex]

Used here:

\getbuffer[MyBuffer]

\blank

\startbuffer[MyBuffer]
\input \jobname-mybuffer.tex

Adding more:

The additional stuff.
\stopbuffer

Now all together:

\getbuffer[MyBuffer]

\stoptext

If there is not, I would like to know if it is possible to have luacode that would deal with those saved buffers (deal=remove them) to not clutter project directory.

Thank you in advance for any help with this.

1 Answer 1

6

When you label a buffer, it is already accessible to \getbuffer[label]. \definebuffer has other purposes. To answer your questions I suggest two ways:

A nice approach from the mailing list

The following example does a better handling of buffers.append. I've just adapted it from the mailing list. It defines \startappendbuffer and \stopappendbuffer so it's more comfortable to use:

\startluacode
    userdata = userdata or { }
    function userdata.addTempToBuffer(buffername)
        buffers.append(
            buffername,
            '\n' .. buffers.getcontent('APPENDTEMP')
        )
    end
\stopluacode

\def\startappendbuffer[#1]%
{\def\stopappendbuffer%
      {\ctxlua{userdata.addTempToBuffer('#1')}}
   \dostartbuffer[APPENDTEMP][startappendbuffer][stopappendbuffer]}

\starttext

\startbuffer[x]
Hola
\stopbuffer

\startlines
\getbuffer[x]
\stoplines

\startappendbuffer[x]
\input knuth
\stopappendbuffer

\startlines
\getbuffer[x]
\stoplines

\stoptext

A naïve approach: wrap buffers.append

There's already a Lua function to append content to a buffer, i.e. buffers.append(buffer, text) (see buffers in LuaTeX). So we're going to wrap it using \ctxlua, which serves to call Lua functions in TeX:

%#1 is the name of the buffer
%#2 is the content to append
\unprotect
\def\appendtobuffer#1#2{\ctxlua{buffers.append("#1", \!!bs#2\!!es)}}
\protect
\starttext 

\startbuffer[lol]
\dorecurse{6}{hello! }
\stopbuffer
\getbuffer[lol]
\appendtobuffer{lol}{\startformula e^{i\pi}+1=0\stopformula \input knuth}
\getbuffer[lol]
\stoptext

Notice the use of \!!bs and \!!es so your content is passed as a string to Lua. I'd use it if I want to add simpler, shorter snippets of text because, as Henri Menke points out (thanks! 😊), it doesn't handle line breaks and expands its content, which is troublesome in special cases, among other unexpected effects.

6
  • Your first solution works OK, but with the second one (more elaborate) I am getting error about TeX capacity exceeded. What might have caused that? Commented Jul 25, 2020 at 16:28
  • Sorry, there was a typo. I'm gonna fix it now
    – user220367
    Commented Jul 25, 2020 at 16:34
  • I am merely copying code from your answer to separate file and compiling it itself, before using it in actual project. I have an error log: (That was too long). EDIT: OK, thank you very much! Commented Jul 25, 2020 at 16:36
  • Try the second again. There was a missing brace I accidentally removed.
    – user220367
    Commented Jul 25, 2020 at 16:37
  • 2
    The naïve approach is, in fact, too naïve since it will fully expand the content first and not treat linebreaks correctly. You should promote the other approach instead and put it first. Commented Jul 26, 2020 at 3:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .