TransWikia.com

Ways to grab and store larger amount of text

TeX - LaTeX Asked by mbork on September 19, 2020

A standard way to grab and store a short text (say, a title of a document) is to use something like

deftitle#1{def@title{#1}}.

But if the content to be stored is longer (say, an abstract}, I guess it is considered more elegant to specify it by something like

begin{abstract}
  ...
end{abstract}

on the user side.

So, the question is: what techniques are available to do something like this? (Some that spring to my mind immediately are: use a vbox, use delimited arguments, use the environ LaTeX package, use ConTeXt grabbufferdata (if I am not mistaken as to the name of that macro)…)

I’d be delighted to see all kinds of answers, for various engines (Knuthian vanilla TeX, eTeX, luaTeX) and formats (plain TeX, LaTeX2e, LaTeX3, ConTeXt).

6 Answers

Straight LaTeX2e:

newsavebox{myabstractbox}
newenvironment{myabstract}{lrbox{myabstractbox}}{endlrbox}

Extract the contents with

usebox{myabstractbox}

Answered by Lev Bishop on September 19, 2020

In ConTeXt, grabbufferdata is a low-level command that is only useful to module writers. At user level, buffers should be used to grab and store contents. For example, store the contents using

startbuffer
    Whatever
stopbuffer

and retreive them using:

getbuffer

You may also typeset the contents using

typebuffer

which is useful when you want to include verbatim material in tables and footnotes.

Buffers may be thought of as a clipboard for copy-pasting content; in fact, as named clipboard, which is useful when you want to repeat material in a document like a presentation or build metapost figures in steps. To get named buffers, simply store content using

startbuffer[anything]
    This is a named buffer
stopbuffer

and retrieve it using

getbuffer[anything]

or

typebuffer[anything]

Buffers are more robust than grabbing content using boxes because you do not need to care about catcodes while grabbing content. (Of course, you need to worry about them when retreiving content).

startbuffer
  A C file starts with type{#include<stdio.h>}.
stopbuffer

getbuffer

works fine even though the content has a #. For this reason, buffers are used when you want to process some XML inline in a regular TeX document.

Buffers can also be nested. For example:

startbuffer[one]
   Buffer one
   startbuffer[two]
      Buffer two
   stopbuffer
stopbuffer


getbuffer[one]
getbuffer[two]

(of course, buffer two is only available after buffer one has been retreived).

In MkIV, startbuffer and stopbuffer can be on the same line

startbuffer[line] #line stopbuffer
typebuffer[line]

And finally, the contents of a buffer are available at the Lua end (as the content is stored in memory). Use the Lua function buffers.getcontent('name') to access the contents of the buffer named name.

Of course, like any other ConTeXt macro, you may define your own version of buffers.

definebuffer
  [grabcontent]
  [
    before=...,
    after=...,
  ]

and then use them as regular buffers.

startgrabcontent
  A # B C
stopgrabcontent

typegrabcontent

The before and after keys are used with getgrabcontent.

Since buffers don't care about their content, they are an excellent comment environment. In fact, the hiding environment in ConTeXt is defined as a buffer.

setupbuffer
  [v!hiding]
  [c!before=,
   c!after=]

Answered by Aditya on September 19, 2020

The collect package; a little example (defining an environment to collect text and format it between rules and using section):

documentclass{article}
usepackage{collect}
usepackage{lipsum}

definecollection{test}
makeatletter
newenvironment{atest}[1]
  {@nameuse{collect}{test}{parnobreaknoindenthrulefill}
    {parnobreaknoindenthrulefillparbigskip}
    {section{#1}}
    {}%
  }
{@nameuse{endcollect}}
makeatother

begin{document}

begin{atest}{example one}
lipsum[2-3]
end{atest}

begin{atest}{example two}
lipsum[2]
end{atest}

lipsum[1-6]

includecollection{test}

end{document}

enter image description here

Answered by Gonzalo Medina on September 19, 2020

LaTeX

If you just want to store the text in form of tokens, like title does, then you can do it with environ:

usepackage{environ}
NewEnviron{sabstract}{globallet@sabstractBODY}

The environment's content is (locally) stored in the macro BODY, so globally letting @sabstract to it will do the same as title does with @title.

begin{sabstract}
This is it.

With two paragraphs.
end{sabstract}

Plain TeX

catcode`@=11
longdefsabstract#1endsabstract{def@sabstract{#1}}
catcode`@=12

sabstract
This is it.

With two paragraphs.
endsabstract

Answered by egreg on September 19, 2020

Wheee another one for the #-rule:

documentclass{article}
defdosomething{inside,}
defdosomethingelse{and outside the group}
deffoo#{bgroupdosomethingaftergroupdosomethingelseletnext= }

begin{document}
foo{
  verb|bar|

  verb|baz|
}
end{document}

Answered by morbusg on September 19, 2020

The scontents package tries to imitate the concept of ConText buffers from the LaTeX side.

documentclass{article}
usepackage{scontents}
begin{document}
% If you need a environment version (like a startbuffer ... stopbuffer)
begin{scontents}[store-env=main]
Something for main A.
end{scontents}

% If you need a macro version (no verbatim)
Scontents[store-cmd=main]{Something for main B.}

% or a macro with verbatim
Scontents*[store-cmd=main]{Something for verb|main C|.}

% Let's print them (like a getbuffer)
This is first stored in main: getstored[1]{main}par
This is third stored in main: getstored[3]{main}par

% Print all of stored in main
foreachsc[sep={[10pt]}]{main}

% Print source content (like a typebuffer)
typestored[3]{main}par
typestored[2]{main}par
typestored[1]{main}
end{document}

The environment and starred macro version support verbatim content, the environment can be nested but cannot start and end on the same line. With both versions (environment and starred) it is also possible to write content to an external file. The non starred macro version has no support for verbatim content.

(I leave this answer here only because this post served as general inspiration for scontents)

Answered by Pablo González L on September 19, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP