
Problema
Estou criando um estilo biblatex personalizado e queria ter um suporte para bibstrings semelhante ao que o month
campo 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 .bbl
arquivo. 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:
Resultado esperado:
Pergunta
Observe que estou esperando o mesmo comportamento com babadores como month
. Se eu tiver o campo sem colchetes, caso de test4
entrada 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 .bib
entradas sem precisar redigitar o texto inteiro todas as vezes. Esse recurso funciona inteiramente no .bib
nível do arquivo.
Uma @string
entrada possui um ID (assim como a chave de entrada de uma .bib
entrada normal) e pode ser chamada por esse nome.
@string{brontostring = {On the Theory of Brontosauruses}}
O conteúdo de a @string
pode 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 .bib
arquivo. Uma ressalva é que @string
s devem ser definidos antes de poderem ser usados. Em particular, você não pode usar texto arbitrário sem colchetes, apenas @string
trabalhos 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 .bib
arquivos diferentes com definições diferentes para a mesma string. Isto é o que ieeetran
acontece com IEEEabrv.bib
e IEEEfull.bib
. Você carrega IEEEabbrv.bib
para obter o nome abreviado do diário ou IEEEfull.bib
para obter nomes completos do diário.
Para todos os efeitos, as sequências de meses funcionam de maneira semelhante.
jan
é um @string
for 1
, feb
for 2
e assim por diante.
@string
s não usam colchetes no .bib
arquivo 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
, \bibstring
e \NewBibliographyString
. Bibstrings fazem parte do biblatex
recurso de localização do e permitem traduzir certos termos para outros idiomas. Normalmente eles são definidos nos .lbx
arquivos, 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 .lbx
arquivo, caso contrário <bibstringid>
é impresso em negrito.
Todo o tratamento da data é muito mais complicado, mas para esta resposta podemos assumir que biblatex
tem uma função chamada \mkbibmonth
que 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 pubstate
campo. O formato do campo para pubstate
é
\DeclareFieldFormat{pubstate}{\ifbibstring{#1}{\bibstring{#1}}{#1}}
Existem algumas strings predefinidas que você pode usar para o pubstate
campo, por exemplo
inpress
, forthcoming
, submitted
. Se você usar um desses, ou seja, você tem
pubstate = {inpress},
em uma de suas .bib
entradas, biblatex
não imprime "inpress" no documento; em vez disso, usa a tradução desse termo conforme fornecido na string. (É claro que biblatex
ficaria 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 bibstrings
a entrada no .bib
arquivo sempre apresenta colchetes.
Comparação dos dois tipos de string
Pelo que eu sei, não existem outras combinações de @strings
babadores que biblatex
funcionem exatamente da mesma maneira. Suspeito fortemente que os meses @string
foram implementados apenas por motivos de compatibilidade com versões anteriores.
Portanto, como vimos, em geral existem duas maneiras de criar resultados dependentes do contexto.
@string
é resolvido pelo back-end- (
.lbx
) bibstrings resolvidos porbiblatex
Qual deles é mais apropriado depende do seu caso de uso.
@string
s 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, @string
os 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 @string
com um texto de substituição. Se você deseja uma solução portátil, isso precisa ser feito em um .bib
arquivo especial que você precisará carregar em todos os seus projetos.
@string{bracelessa = {bracelessa}}
@string{bracelessb = {bracelessb}}
Em seguida, faça os babadores bracelessa
, bracelessb
conhecidos 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 @string
e 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
.