Подтвердить что ты не робот

Bib-style формат для bibtext bst файла - поясняется на примере

мой вопрос касается способа определения поля bibtex-стиля в bst файле. Я хотел бы, чтобы следующий пример ниже объяснялся по частям, чтобы понять, что делает каждая часть. Я хотел бы иметь возможность самостоятельно внести изменения в этот пример.

FUNCTION {format.eprint}
{ eprint duplicate$ empty$
    'skip$
    { "\eprint"
      archive empty$
        'skip$
        { "[" * archive * "]" * }
      if$
      "{" * swap$ * "}" *
    }
  if$
}
4b9b3361

Ответ 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>}