формат bib-стиля для bibtext bst файла - поясняется на примере - PullRequest
27 голосов
/ 23 августа 2010

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

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

1 Ответ

37 голосов
/ 24 августа 2010

Язык BibTeX немного сложен: для полной информации взгляните на Приручите BeaST .Необходимо помнить, что это язык стеков и что он использует постфиксный подход.Почти все встроенные функции также удаляют свои входные данные из стека.

По частям, первая строка начинается с FUNCTION, что означает, что она определит новую функцию (format.eprint)это можно использовать в другом месте файла .bst.Важно отметить, что эту новую функцию можно использовать только ниже: порядок функций в файле .bst важен .Скобки используются для отображения различных аргументов: FUNCTION необходимо два, имя функции и код, который ее реализует.

В самом коде eprint будет полем.Использование имени поля добавляет значение поля в стек (для текущей записи).Затем у нас есть duplicate$, который дублирует верхний элемент в стеке.Это встроенная инструкция BibTeX, отображаемая терминалом $.Таким образом, в стеке теперь будет две копии значения eprint.

Следующая инструкция - empty$.Это проверит, пуст ли верхний элемент стека и удалит его , отсюда и необходимость duplicate$.Результат теста - либо 1, либо 0, который остается в стеке.Таким образом, верхний элемент в стеке теперь равен 1 или 0, а следующий элемент имеет значение eprint.

Далее у вас есть оператор if$, который находится в postfix, и дваветви до до if$.Поскольку язык - постфикс, то получается, что if$ выберет истинную ветвь, если верхний элемент в стеке равен 1, а ложная ветвь - в противном случае.Это также удаляет верхний элемент из стека.(Если вам нужна реальная детализация, две ветви фактически помещаются в стек, а затем оператор if$ удаляет соответствующую и оставляет остальную часть материала для выполнения.)

Первая (true) ветка читает 'skip$, что является инструкцией «ничего не делать».Брекеты вокруг одной инструкции могут быть пропущены, если вы включите ведущий '.Альтернатива, которую (немного) легче читать для новых пользователей, будет

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

, т.е. , просто используя пустой набор фигурных скобок для ветви «ничего не делать» (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>}
...