Ответ 1
Язык BibTeX немного сложный: для полной ссылки взгляните на Tame the BeaST. Ключевыми моментами, которые следует помнить, является то, что это язык стека и он использует постфиксный подход. Почти все встроенные функции также удаляют их вход из стека.
Взяв его по частям, первая строка начинается с FUNCTION
, что означает, что она определит новую функцию (format.eprint
), которая может использоваться в другом месте в файле .bst
. Важно отметить, что эту новую функцию можно использовать только ниже: порядок функций в файле .bst
важен. Скобки используются для отображения разных аргументов: FUNCTION
требуется два, имя функции и код, который ее реализует.
В самом коде eprint
будет полем. Использование имени поля добавляет значение поля в стек (для текущей записи). Затем мы имеем duplicate$
, который дублирует верхний элемент в стеке. Это инструкция по сборке BibTeX, показанная терминалом $
. Таким образом, стек теперь будет содержать две копии значения eprint
.
Следующая инструкция empty$
. Это проверит, если верхний элемент стека пуст и удаляет его, следовательно, требуется duplicate$
. Результатом теста является либо 1
, либо 0
, который остается в стеке. Таким образом, верхний элемент в стеке теперь равен 1 или 0, а следующий элемент - значение eprint
.
Далее у вас есть оператор if$
, который находится в postfix и поэтому имеет две ветки перед if$
. Поскольку язык постфиксен, происходит то, что if$
будет выбирать истинную ветвь, если верхний элемент в стеке 1
, а ложная ветвь - в противном случае. Это также удаляет верхний элемент из стека. (Если вам нужна реальная деталь, две ветки фактически помещаются в стек, а оператор if$
удаляет соответствующий элемент и оставляет остальную часть исполняемого материала.)
Первая (истинная) ветвь читает 'skip$
, которая является инструкцией "ничего не делать". Скобки вокруг одной инструкции могут быть пропущены, если вы включите ведущий '
. Альтернативой, которая (слегка) легче читать для новых пользователей, будет
FUNCTION {format.eprint}
{ eprint duplicate$ empty$
{ }
{ "\eprint"
archive empty$
{ }
{ "[" * archive * "]" * }
if$
"{" * swap$ * "}" *
}
if$
}
то есть. просто используя пустой набор фигурных скобок для ветки "do nothing" (true). Таким образом, цель здесь - ничего не делать, если поле eprint
пустое.
Ложная ветвь начинается "\eprint"
, которая помещает литеральный \eprint
в верхнюю часть стека. Следующая часть помещает поле archive
в стек и выполняет другой тест для пустого поля. Если поле archive
доступно, код
"[" * archive * "]" *
помещает [
в стек, а затем присоединяет его к верхнему элементу в стеке (который был \eprint
): эта операция соединения - это то, что делает *
. Затем значение поля archive
добавляется в стек и объединяется, а затем еще ]
. Таким образом, верхняя часть стека будет содержать
\eprint[<archive>]
(где <archive>
- значение поля архива), если для archive
есть что-то, и в остальном только \eprint
.
Наконец, есть еще несколько строковых построений. Мы имеем
"{" * swap$ * "}" *
который сначала помещает {
в стек. Он соединяется с верхним элементом (\eprint
или \eprint[<archive>]
), чтобы дать \eprint{
. Функция swap$
меняет местами верхние два элемента в стеке, поэтому верхний элемент - это имя <eprint>
(значение поля eprint
). Существует совместное создание
\eprint{<eprint>
а затем окончательное дополнение }
до конца.
В результате стек получит один элемент в верхней части. Если eprint
пуст, в верхней части стека будет пустой элемент, иначе он будет читать
\eprint{<eprint>}