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).
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}
Answered by Gonzalo Medina on September 19, 2020
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}
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP