Правильный способ объявления полей, поддерживающих bibstrings в пользовательском стиле biblatex

Правильный способ объявления полей, поддерживающих bibstrings в пользовательском стиле biblatex

Проблема

Я создаю собственный стиль biblatex и хочу иметь поддержку bibstrings, похожую на ту, что monthесть у поля в общих реализациях. То есть, если я помещаю что-то в скобки, {something}, то содержимое, something, отображается в поле. Но если у меня есть что-то без скобок, оно интерпретируется как bibstring и преобразуется в его определение.

Я могу частично добиться этого, проверив, является ли содержимое поля bibstring, через \ifbibstring(и друзей). Однако это работает только если содержимое всегда находится в скобках. Если это не так, biber выдает ошибку и не передает поле для дальнейшей обработки.

Например, приведенный ниже код генерирует предупреждающее сообщение

ПРЕДУПРЕЖДЕНИЕ - Подсистема BibTeX: /tmp/M3YJZ8wGD7/mwe.bib_28410.utf8, строка 21, предупреждение: неопределенный макрос "mytitle"

и это заставляет biber не создавать это поле в .bblфайле. Я нашел похожую ошибку наbiblatex/biber: использование строковых макросов из одного файла в нескольких секциях ссылок, но это не решает мою проблему.

МВЭ

Это моя минимальная реализация для демонстрации моей проблемы.

% !BIB program = biber
\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
  @test{test1,
    title = {A},
    year = {1995},
  }

  @test{test2,
    title = {B},
    year = {1994},
  }

  @test{test3,
    title = {mytitle},
    year = {1998},
  } 

  @test{test4,
    title = mytitle,
    year = {1998},

  }
\end{filecontents}

\begin{filecontents}{test.dbx}
  \DeclareDatamodelFields[type=field, datatype=literal]{title}

  \DeclareDatamodelFields[type=field, datatype=datepart]{year}

  \DeclareDatamodelEntryfields[test]{%
    year,%
    title%
  }
\end{filecontents}

\begin{filecontents}{english-test.lbx}
  \InheritBibliographyExtras{english}

  % Bibliography strings
  \NewBibliographyString{mytitle}

  \DeclareBibliographyStrings{%
    inherit = {american},
    mytitle = {{my title}{my title}},
  }
\end{filecontents}

\begin{filecontents}{test.bbx}
  \RequireBibliographyStyle{standard}

  % map language
  \DeclareLanguageMapping{english}{english-test}

  % Dummy driver for testing
  \DeclareBibliographyDriver{test}{%
    \usebibmacro{begentry}%
    \printfield{title}%
    \newunit%
    \printfield{year}%
    \newunit%
    \usebibmacro{finentry}%
  }

  \DeclareFieldFormat[test]{title}{%
    \ifbibstring{#1}{\bibstring{#1}}{#1}%
  }
\end{filecontents}

\usepackage[backend=biber, bibstyle=test]{biblatex}
\addbibresource{\jobname.bib}


\begin{document}

  \nocite{*}
  \printbibliography

\end{document}

Выходной ток:

введите описание изображения здесь

Ожидаемый результат:

введите описание изображения здесь

Вопрос

Обратите внимание, что я ожидаю того же поведения с bibstrings, например month. Если у меня есть поле без скобок, случай записи test4в .bib, который должен быть преобразован с использованием определения bibstring. Но если у меня есть то же определение со скобками, например в test3, вместо этого должно быть выведено содержимое.

Как этого добиться с помощью индивидуального стиля?

решение1

Здесь есть как минимум два понятия «строка». Ни одно из них само по себе не делает то, что вам нужно. Только их комбинация может это сделать.

@stringс

Во-первых, есть @string. @stringесть способ вставить один и тот же текст в несколько .bibзаписей без необходимости каждый раз перепечатывать весь текст. Эта функция работает исключительно на .bibуровне файла.

Запись @stringимеет идентификатор (точно так же, как ключ входа обычной .bibзаписи) и может быть вызвана по этому имени.

@string{brontostring = {On the Theory of Brontosauruses}}

Содержимое a @stringможно использовать, указав идентификатор строки в качестве значения поля.безбрекеты.

@book{foo,
  author = {Anne Elk},
  title  = brontostring,
  date   = {1970},
}

Biber (или BibTeX) разрешает эти строки немедленно при чтении файла .bib. Одно предостережение заключается в том, что @strings должны быть определены до того, как их можно будет использовать. В частности, вы не можете использовать произвольный текст без фигурных скобок, @stringработают только известные s. Затем мы остаемся с

@book{foo,
  author = {Anne Elk},
  title  = {On the Theory of Brontosauruses},
  date   = {1970},
}

При дальнейшей обработке записи не остается никаких указаний на то, что текст происходит из @string.

Это позволит вам вводить произвольный текст в запись. Текст не будет изменяться с помощью biblatex, но вы можете изменить его, загрузив разные .bibфайлы с разными определениями для одной и той же строки. Это то, что ieeetranпроисходит с IEEEabrv.bibи IEEEfull.bib. Вы загружаете либо IEEEabbrv.bibдля получения сокращенного названия журнала, либо IEEEfull.bibдля получения полных названий журналов.

По сути, строки месяцев работают аналогичным образом. janЭто @stringfor 1, febfor 2и так далее.

@stringне используйте фигурные скобки в .bibфайле, если они используются в качестве значений полей.

библиографические строки

Затем есть вторая, совершенно не связанная концепция «строк», а именно bibstrings. Это те, на которые вы ссылаетесь с помощью \ifbibstring, \bibstringи \NewBibliographyString. Bibstrings являются частью biblatexфункции локализации и позволяют вам переводить определенные термины на другие языки. Обычно они определяются в .lbxфайлах, но их значения также могут быть переопределены в преамбуле.

Bibstrings можно использовать с , \bibstring{<bibstringid>}где <bibstringid>— имя bibstring, определенное с \NewBibliographyString. В идеале <bibstringid>также будет иметь значение в .lbxфайле, в противном случае <bibstringid>будет напечатано жирным шрифтом.

Вся обработка дат намного сложнее, но для этого ответа мы можем предположить, что biblatexесть функция, \mkbibmonthкоторая сопоставляет 1 с \bibstring{january}, 2 с \bibstring{february}и т. д. Поэтому при \mkbibmonth{7}вызове это приводит к \bibstring{july}тому, что в вашем документе печатается «Июль», если активным языком является английский, или «Юли», если активным языком является немецкий.

Более простой и типичный пример для bibstrings — это pubstateполе. Формат поля pubstateдля

\DeclareFieldFormat{pubstate}{\ifbibstring{#1}{\bibstring{#1}}{#1}}

Есть несколько предопределенных строк, которые вы можете использовать для pubstateполя, например inpress, forthcoming, , submitted. Если вы используете одну из них, то есть у вас есть

pubstate = {inpress},

в одной из ваших .bibзаписей, то biblatexне печатает "inpress" в документе, вместо этого он использует перевод этого термина, как указано в bibstring. (Конечно, biblatexс радостью использовал бы и любую другую bibstring, которую вы ему укажете, pubstate = {january}это тоже сработает.) Поле печатается как есть, если bibstring с таким именем отсутствует, поэтому pubstate = {foonostring}просто печатает 'foonostring'.

При bibstringsвводе в .bibфайле всегда присутствуют фигурные скобки.

Сравнение двух типов струн

Насколько мне известно, других комбинаций @stringsи bibstrings, biblatexкоторые работают точно так же, нет. Я сильно подозреваю, что месяцы @stringбыли реализованы только из соображений обратной совместимости.

Итак, как мы увидели, в целом существует два способа создания контекстно-зависимого вывода.

  1. @strings решено бэкэндом
  2. ( .lbx) bibstrings разрешеныbiblatex

Какой из них более подходит, зависит от вашего варианта использования. @strings кажутся более подходящими, если вы просто хотите сэкономить на наборе текста или если вы хотите иметь возможность переключаться между несколькими формами ввода (длинные и короткие названия журналов). В целом @strings не привязаны к языкам или локалям. Bibstrings — это то, что вам нужно, если вам нужна настоящая локализация.

На примере вашего вопроса я не могу точно сказать, какой из двух подходов будет более полезным в вашем случае.

Можем ли мы получить то, что вы хотите?

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

Для каждого возможного значения без скобок вам нужно определить a @stringс текстом замены. Если вам нужно портативное решение, это нужно сделать в специальном .bibфайле, который вам нужно будет загрузить во все ваши проекты.

@string{bracelessa = {bracelessa}}
@string{bracelessb = {bracelessb}}

Затем сделайте нагрудные струны bracelessa, bracelessbизвестныеbiblatex

\NewBibliographyString{bracelessa}
\NewBibliographyString{bracelessb}

и определить их

\DeclareBibliographyStrings{%
  inherit = {american},
  bracelessa = {{A title}{A t\addddot}},
  bracelessb = {{B title}{B t\addddot}},
}

Затем используйте формат поля

\DeclareFieldFormat[test]{title}{\ifbibstring{#1}{\bibstring{#1}}{#1}}

для рассматриваемой области.

Сейчас

title = bracelessa,

напечатает «Заголовок» в вашем документе.

Почему это не дает вам именно то, что вы описываете?

Во-первых, ввод без скобок не является произвольным. Вам нужно определить как a, так @stringи соответствующий bibstring. Во-вторых, title = {something}не всегда будет отображать something. Если вы напишете title = {bracelessa}'A title', то вместо этого выйдет . Коллизии можно усложнить, выбрав более нелепые имена для bibstrings, но они всегда будут возможны, поскольку нет способа узнать, было ли задано значение поля напрямую или через @string.

Связанный контент