Does LaTeX have an array data structure?
Are there arrays in LaTeX? I don't mean the way to typeset arrays. I mean arrays as the data structure in LaTeX/TeX as a "programming language". I need to store a number of vbox-es or hbox-es in an array. It may be something like "an array of macros".
More details: I have an environment that should typeset songs. I need to store some songs' paragraphs given as arguments to my macro \songparagraph (so I will not typeset them, just store those paragr开发者_运维知识库aphs). As I don't know how many paragraphs can be in one particular song I need an array for this. When the environment is closed, all the paragraphs will be typeset - but they will be first measured and the best placement for each paragraph will be computed (for example, some paragraphs can be put one aside the other in two columns to make the song look more compact and save some space).
Any ideas would be welcome. Please, if you know about arrays in LaTeX, post a link to some basic documentation, tutorial or just state basic commands.
This is an array how it could be implemented in LaTeX:
\documentclass{article}
\begin{document}
\newcounter{mycounter}
\setcounter{mycounter}{1}
% ary is any prefix you want, it should not exist as a command.
\expandafter\newcommand\csname ary\the\value{mycounter} \endcsname{myfirstelement}
\stepcounter{mycounter}
\expandafter\newcommand\csname ary\the\value{mycounter} \endcsname{mysecondelement}
\csname ary1 \endcsname
or
\newcounter{index}
\setcounter{index}{2}
\csname ary\the\value{index} \endcsname
\end{document}
Run this through LaTeX (latex mydoc.tex or pdflatex mydoc.tex) and you see the output.
A short explanation: this creates two commands (with newcommand): ary1 and ary2. The \expandafter
is needed because newcommand
should not define \csname
but the command created by \csname
... \endcsname
. \expandafter
jumps over the next token, in this case the control sequence \newcommand
and executes the next command before TeX sees the \newcommand
. That means, the first thing in the newcommand-lines TeX sees is the \csname
...\endcsname
construct, TeX executes it and then executes \newcommand
with the result of the \csname
...\endcsname
construct. \csname foo\endcsname
is the same as \foo
, but you can use any character or even spaces in the command created by \csname
...\endcsname
.
This is not trivial. See the great book "TeX by topic" from Victor Eijkhout: http://eijkhout.net/texbytopic/texbytopic.html
Luatex has Lua's tables, which generalise arrays. If having standard Latex is not important to you, consider using Luatex with Latex. You can then do such things as:
\def\lookup#1{\directlua {
local array={1,2,4,8}; tex.print(array[#1])}}
\[ 2 \mapsto \lookup{2} \]
Luatex is a bit flaky with Latex, because of the need to escape all kinds of Lua characters in the Latex code. Context has \startluacode ... \stopluacode
macros to handle Lua code definitions, and \ctxlua
for Lua code calls, and I can't see any reason why something like these couldn't be defined for Latex.
pgfkeys and pgffor might also work for you. They're part of the pgf (portable graphics format) package but they can be used independently of all the graphics stuff.
To expand on Patrick's answer, the short answer is "No". However, as it has macro expansion, it can be programmed to have arrays.
Here's another example, this one using push and pop for "arrays". When \type@pushcolour
is called, it saves the current colour on to the stack. \type@popcolour
takes the top colour definition, and uses it:
\newcount\type@count
\def\type@pushcolour{%
\xglobal\colorlet{foo\the\type@count}{.}%
\global\advance\type@count by1\relax}
\def\type@popcolour{%
\global\advance\type@count by-1\relax%
\color{foo\the\type@count}}
(I adapted this code from the source for the beamer package)
You could also look at something like the datatool package or the expl3 programming system, and the "property list" data type.
Check out Arrayjob which implements arrays for LaTeX. Admittedly, I've only peeked at it, so I don't know how effective it will be. But, if you don't have to write it yourself ...
The readarray package allows one to input formatted data into elements of a 2-D or 3-D array (or a 1-D file-record array).
\documentclass{standalone}
\usepackage{readarray}
\def\data{% the data
1 15 14 4
10 11 8 5
7 6 9 12
16 2 3 13
}
\readarray\data\dataA[4,4] %read the data to \dataA
\begin{document}
value at (2,1) = \dataA[2,1] %access a specific field
\end{document}
精彩评论