Есть ли у LaTeX структура данных массива? - PullRequest
16 голосов
/ 15 апреля 2010

Есть ли в LaTeX массивы? Я не имею в виду способ набора массивов. Я имею в виду массивы как структуру данных в LaTeX / TeX как «язык программирования». Мне нужно хранить несколько vbox-ов или hbox-ов в массиве. Это может быть что-то вроде «массива макросов».

Подробнее: у меня есть среда, которая должна набирать песни. Мне нужно сохранить абзацы некоторых песен, приведенные в качестве аргументов для моего макроса \ songparagraph (поэтому я не буду набирать их, просто сохраню эти абзацы). Поскольку я не знаю, сколько абзацев может быть в одной конкретной песне, мне нужен массив для этого. Когда среда закрыта, все абзацы будут набраны, но сначала они будут измерены, и будет рассчитано наилучшее размещение для каждого абзаца (например, некоторые абзацы можно поместить один в другой в два столбца, чтобы песня выглядела более компактный и сэкономить место).

Любые идеи приветствуются. Пожалуйста, если вы знаете о массивах в LaTeX, опубликуйте ссылку на базовую документацию, учебное пособие или просто укажите основные команды.

Ответы [ 7 ]

10 голосов
/ 15 апреля 2010

Это массив, как его можно реализовать в 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}

Запустите это через LaTeX (latex mydoc.tex или pdflatex mydoc.tex), и вы увидите вывод.

Краткое объяснение: здесь создаются две команды (с новой командой): ary1 и ary2. \expandafter необходим, потому что newcommand должен определять не \csname, а команду, созданную \csname ... \endcsname. \expandafter перепрыгивает через следующий токен, в этом случае последовательность управления \newcommand и выполняет следующую команду, прежде чем TeX увидит \newcommand. Это означает, что первое, что видит в новых строках команд TeX - это конструкция \csname ... \endcsname, TeX выполняет ее, а затем выполняет \newcommand с результатом конструкции \csname ... \endcsname , \csname foo\endcsname совпадает с \foo, но вы можете использовать любой символ или даже пробел в команде, созданной \csname ... \endcsname.

Это не тривиально. Смотрите великую книгу "TeX by topic" от Виктора Эйххоута: http://eijkhout.net/texbytopic/texbytopic.html

5 голосов
/ 19 апреля 2010

У Луатекса есть таблицы Луа, которые обобщают массивы. Если для вас не важен стандартный латекс, рассмотрите возможность использования латекса с латексом. Затем вы можете делать такие вещи, как:

\def\lookup#1{\directlua {
    local array={1,2,4,8}; tex.print(array[#1])}}
\[ 2 \mapsto \lookup{2} \]

Luatex немного ненадежен с латексом из-за необходимости экранировать все виды символов Lua в коде латекса. В контексте есть макросы \startluacode ... \stopluacode для обработки определений кода Lua и \ctxlua для вызовов кода Lua, и я не вижу причин, почему что-то подобное не может быть определено для Latex.

4 голосов
/ 16 апреля 2010

pgfkeys и pgffor также могут работать для вас. Они являются частью пакета pgf (формат переносимой графики), но их можно использовать независимо от всех графических элементов.

3 голосов
/ 16 апреля 2010

Вы также можете посмотреть что-то вроде пакета datatool или системы программирования expl3 и типа данных «список свойств».

3 голосов
/ 16 апреля 2010

Чтобы расширить ответ Патрика, краткий ответ - «Нет». Однако, поскольку он имеет расширение макроса, его можно запрограммировать на наличие массивов.

Вот еще один пример, использующий push и pop для «массивов». Когда вызывается \type@pushcolour, текущий цвет сохраняется в стеке. \type@popcolour берет верхнее определение цвета и использует его:

\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}}

(я адаптировал этот код из исходного кода для пакета beamer)

2 голосов
/ 16 апреля 2010

Проверьте Arrayjob , который реализует массивы для LaTeX. По общему признанию, я только посмотрел на это, таким образом, я не знаю, насколько это будет эффективно. Но если тебе не нужно писать это самому ...

0 голосов
/ 26 июля 2018

Пакет readarray позволяет вводить отформатированные данные в элементы двухмерного или трехмерного массива (или одномерного массива файловых записей).

\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}
...