Maneira correta de declarar campos que suportam bibstrings no estilo biblatex personalizado

Maneira correta de declarar campos que suportam bibstrings no estilo biblatex personalizado

Problema

Estou criando um estilo biblatex personalizado e queria ter um suporte para bibstrings semelhante ao que o monthcampo tem nas implementações comuns. Ou seja, se eu colocar algo entre colchetes, {something}então o conteúdo, something, é renderizado no campo. Mas se eu tiver algo sem colchetes, ele será interpretado como uma string e convertido em sua definição.

Posso conseguir isso parcialmente verificando se o conteúdo do campo é um bibstring, por meio de \ifbibstring(e amigos). No entanto, isso só funciona se o conteúdo estiver sempre entre colchetes. Se não for o biber dá erro e não passa o campo para posterior processamento.

Por exemplo, o código abaixo gera a mensagem de aviso

AVISO - subsistema BibTeX: /tmp/M3YJZ8wGD7/mwe.bib_28410.utf8, linha 21, aviso: macro indefinida "mytitle"

e isso faz com que o Biber não crie esse campo no .bblarquivo. Encontrei um erro semelhante embiblatex/biber: usando macros de strings de um arquivo em múltiplas refsections, mas isso não resolve o meu problema.

MWE

Esta é minha implementação mínima para demonstrar meu problema.

% !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}

Saída atual:

insira a descrição da imagem aqui

Resultado esperado:

insira a descrição da imagem aqui

Pergunta

Observe que estou esperando o mesmo comportamento com babadores como month. Se eu tiver o campo sem colchetes, caso de test4entrada em .bib, isso deverá ser convertido usando a definição do bibstring. Mas se eu tiver a mesma definição entre colchetes, como em test3, o conteúdo deverá ser impresso.

Como posso conseguir isso com um estilo personalizado?

Responder1

Existem pelo menos duas noções de 'string' aqui. Nenhum dos dois faz por si só o que você deseja. Somente uma combinação dos dois pode fazer isso.

@stringé

Em primeiro lugar, existe @string. @stringé uma maneira de inserir o mesmo texto em várias .bibentradas sem precisar redigitar o texto inteiro todas as vezes. Esse recurso funciona inteiramente no .bibnível do arquivo.

Uma @stringentrada possui um ID (assim como a chave de entrada de uma .bibentrada normal) e pode ser chamada por esse nome.

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

O conteúdo de a @stringpode ser usado fornecendo o ID da string como um valor de camposemos aparelhos.

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

Biber (ou BibTeX) resolve essas strings imediatamente ao ler o .bibarquivo. Uma ressalva é que @strings devem ser definidos antes de poderem ser usados. Em particular, você não pode usar texto arbitrário sem colchetes, apenas @stringtrabalhos conhecidos. Ficamos então com

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

Quando a entrada é processada posteriormente, não há indicação de que o texto provém de um arquivo @string.

Isso permitiria injetar texto arbitrário em uma entrada. O texto não poderia ser alterado por biblatex, mas você poderia alterá-lo carregando .bibarquivos diferentes com definições diferentes para a mesma string. Isto é o que ieeetranacontece com IEEEabrv.bibe IEEEfull.bib. Você carrega IEEEabbrv.bibpara obter o nome abreviado do diário ou IEEEfull.bibpara obter nomes completos do diário.

Para todos os efeitos, as sequências de meses funcionam de maneira semelhante. jané um @stringfor 1, febfor 2e assim por diante.

@strings não usam colchetes no .bibarquivo quando são usados ​​como valores de campo.

cadeias de bibliografia

Depois, há um segundo conceito de 'strings', completamente não relacionado, nomeadamente bibstrings. Esses são aqueles aos quais você se refere com \ifbibstring, \bibstringe \NewBibliographyString. Bibstrings fazem parte do biblatexrecurso de localização do e permitem traduzir certos termos para outros idiomas. Normalmente eles são definidos nos .lbxarquivos, mas seus valores também podem ser substituídos no preâmbulo.

Bibstrings podem ser usados ​​com \bibstring{<bibstringid>}onde <bibstringid>é o nome de um bibstring definido com \NewBibliographyString. O ideal <bibstringid>é que também tenha recebido um valor no .lbxarquivo, caso contrário <bibstringid>é impresso em negrito.

Todo o tratamento da data é muito mais complicado, mas para esta resposta podemos assumir que biblatextem uma função chamada \mkbibmonthque mapeia 1 para \bibstring{january}, 2 para \bibstring{february}etc. Então, quando \mkbibmonth{7}é chamado, isso resulta em \bibstring{july}e então 'Julho' é impresso em seu documento se for inglês é a língua ativa ou 'Juli' se o alemão for a língua ativa.

Um exemplo mais simples e típico de babadores é o pubstatecampo. O formato do campo para pubstateé

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

Existem algumas strings predefinidas que você pode usar para o pubstatecampo, por exemplo inpress, forthcoming, submitted. Se você usar um desses, ou seja, você tem

pubstate = {inpress},

em uma de suas .bibentradas, biblatexnão imprime "inpress" no documento; em vez disso, usa a tradução desse termo conforme fornecido na string. (É claro que biblatexficaria feliz em usar qualquer outra string que você fornecer, pubstate = {january}também funcionaria.) O campo é impresso como está se não houver nenhuma string com esse nome, então pubstate = {foonostring}simplesmente imprimiria 'foonostring'.

Com bibstringsa entrada no .bibarquivo sempre apresenta colchetes.

Comparação dos dois tipos de string

Pelo que eu sei, não existem outras combinações de @stringsbabadores que biblatexfuncionem exatamente da mesma maneira. Suspeito fortemente que os meses @stringforam implementados apenas por motivos de compatibilidade com versões anteriores.

Portanto, como vimos, em geral existem duas maneiras de criar resultados dependentes do contexto.

  1. @stringé resolvido pelo back-end
  2. ( .lbx) bibstrings resolvidos porbiblatex

Qual deles é mais apropriado depende do seu caso de uso. @strings parecem mais apropriados se você deseja apenas economizar na digitação ou se deseja alternar entre várias formas de entrada (nomes de diários longos versus nomes curtos). Em geral, @stringos s não estão vinculados a idiomas ou localidades. Os babadores são a escolha certa se você deseja uma localização verdadeira.

Não consigo dizer pelo exemplo da sua pergunta qual das duas abordagens seria mais útil no seu caso de uso.

Podemos conseguir o que você quer?

Se você insiste no esquema descrito na sua pergunta, isso é quase possível combinando as duas abordagens. Não acho que seja uma ideia particularmente boa, mas vamos lá.

Para cada valor possível sem colchetes, você precisa definir um @stringcom um texto de substituição. Se você deseja uma solução portátil, isso precisa ser feito em um .bibarquivo especial que você precisará carregar em todos os seus projetos.

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

Em seguida, faça os babadores bracelessa, bracelessbconhecidos porbiblatex

\NewBibliographyString{bracelessa}
\NewBibliographyString{bracelessb}

e defini-los

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

Em seguida, use o formato de campo

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

para o campo em questão.

Agora

title = bracelessa,

imprimirá 'Um título' em seu documento.

Por que isso não dá exatamente o que você descreve?

Em primeiro lugar, a entrada sem chave não é arbitrária. Você precisa definir a @stringe an apropriado bibstring. Em segundo lugar, title = {something}nem sempre será renderizado something. Se você escrever title = {bracelessa}'Um título' será exibido. As colisões podem ser dificultadas pela escolha de nomes mais ridículos para os bibstrings, mas sempre serão possíveis, pois não há como descobrir se um valor de campo foi fornecido diretamente ou por meio de um @string.

informação relacionada