Forma correcta de declarar campos que admiten cadenas de baberos en un estilo biblatex personalizado

Forma correcta de declarar campos que admiten cadenas de baberos en un estilo biblatex personalizado

Problema

Estoy creando un estilo biblatex personalizado y quería tener un soporte para bibstrings similar al que monthtiene el campo en las implementaciones comunes. Es decir, si pongo algo entre corchetes {something}, entonces el contenido, somethingse representa en el campo. Pero si tengo algo sin corchetes, se interpreta como una cadena y se convierte a su definición.

Puedo lograrlo parcialmente verificando si el contenido del campo es un bibstring, a través de \ifbibstring(y amigos). Sin embargo, eso sólo funciona si el contenido siempre está entre paréntesis. Si no es biber da error y no pasa el campo para su posterior procesamiento.

Por ejemplo, el siguiente código genera el mensaje de advertencia

ADVERTENCIA - Subsistema BibTeX: /tmp/M3YJZ8wGD7/mwe.bib_28410.utf8, línea 21, advertencia: macro no definida "mytitle"

y eso hace que Biber no cree ese campo en el .bblarchivo. Encontré un error similar enbiblatex/biber: uso de macros de cadenas de un archivo en múltiples secciones de referencia, pero eso no soluciona mi problema.

MWE

Esta es mi implementación mínima para demostrar mi 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}

Salida de corriente:

ingrese la descripción de la imagen aquí

Rendimiento esperado:

ingrese la descripción de la imagen aquí

Pregunta

Tenga en cuenta que espero el mismo comportamiento con baberos como month. Si tengo el campo sin corchetes, el caso de test4la entrada en .bib, debe convertirse usando la definición de bibstring. Pero si tengo la misma definición entre corchetes, como en test3, el contenido debería imprimirse.

¿Cómo puedo lograr eso con un estilo personalizado?

Respuesta1

Aquí hay al menos dos nociones de "cuerda". Tampoco lo hace por sí solo lo que quieres. Sólo una combinación de los dos puede lograr eso.

@strings

En primer lugar, hay @string. @stringes una forma de insertar el mismo texto en varias .bibentradas sin tener que volver a escribir el texto completo cada vez. Esta característica funciona completamente a .bibnivel de archivo.

Una @stringentrada tiene un ID (igual que la clave de entrada de una .bibentrada habitual) y se le puede llamar por ese nombre.

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

El contenido de a @stringse puede utilizar proporcionando el ID de cadena como valor de campo.sinlos brackets.

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

Biber (o BibTeX) resuelve estas cadenas inmediatamente al leer el .bibarchivo. Una advertencia es que @stringlos s deben definirse antes de poder usarse. En particular, no puedes usar texto arbitrario sin llaves, solo @stringtrabajos conocidos. Nos quedamos entonces con

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

Cuando la entrada se procesa más, no queda ninguna indicación de que el texto proviene de un archivo @string.

Esto le permitiría inyectar texto arbitrario en una entrada. El texto no se podrá cambiar con biblatex, pero se puede cambiar cargando diferentes .bibarchivos con diferentes definiciones para la misma cadena. Esto es lo que ieeetranhace con IEEEabrv.biby IEEEfull.bib. Puede cargar IEEEabbrv.bibpara obtener el nombre abreviado de la revista o IEEEfull.bibpara obtener los nombres completos de la revista.

Para todos los efectos, las cadenas de meses funcionan de manera similar. janes un @stringfor 1, febfor 2y así sucesivamente.

@stringLos s no usan llaves en el .bibarchivo cuando se usan como valores de campo.

cadenas de bibliografía

Luego hay un segundo concepto de "cuerdas", que no tiene ninguna relación, es decir, las cuerdas de babero. Esos son a los que te refieres con \ifbibstring, \bibstringy \NewBibliographyString. Bibstrings son parte de biblatexla función de localización de y le permiten traducir ciertos términos a otros idiomas. Normalmente se definen en los .lbxarchivos, pero sus valores también se pueden anular en el preámbulo.

Las cadenas de baberos se pueden usar con \bibstring{<bibstringid>}dónde <bibstringid>está el nombre de una cadena de baberos definida con \NewBibliographyString. Lo ideal <bibstringid>es que también haya recibido un valor en el .lbxarchivo, de lo contrario <bibstringid>se imprime en negrita.

El manejo completo de la fecha es mucho más complicado, pero para esta respuesta podemos asumir que biblatextiene una función llamada \mkbibmonthque asigna 1 a \bibstring{january}, 2 a \bibstring{february}, etc. Entonces, cuando \mkbibmonth{7}se llama, esto da como resultado que \bibstring{july}se imprima 'julio' en su documento si está en inglés. es el idioma activo o 'Juli' si el alemán es el idioma activo.

Un ejemplo más simple y típico de tirantes es el pubstatecampo. El formato de campo para pubstatees

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

Hay algunas cadenas predefinidas que puede utilizar para el pubstatecampo, por ejemplo inpress, forthcoming, submitted. Si usas uno de esos, es decir, tienes

pubstate = {inpress},

en una de sus .bibentradas, entonces biblatexno imprime "inpress" en el documento, sino que utiliza la traducción de ese término tal como figura en el bibstring. (Por supuesto, biblatextambién usaría cualquier otro bibstring que le dé, pubstate = {january}también funcionaría). El campo se imprime tal como está si no hay un bibstring con ese nombre, por lo que pubstate = {foonostring}simplemente imprimiría 'foonostring'.

Con bibstringsla entrada en el .bibarchivo siempre aparecen llaves.

Comparación de los dos tipos de cadenas.

Hasta donde yo sé, no hay otras combinaciones de @stringsy baberos biblatexque funcionen exactamente de la misma manera. Sospecho firmemente que los meses @stringsolo se implementaron por razones de compatibilidad con versiones anteriores.

Como hemos visto, en general hay dos formas de crear resultados dependientes del contexto.

  1. @strings resuelto por el backend
  2. ( .lbx) tirantes resueltos porbiblatex

Cuál es más apropiado depende de su caso de uso. @stringEsto parece más apropiado si solo desea ahorrar al escribir, o si desea tener una forma de cambiar entre varias formas de entrada (nombres de revistas largos o cortos). En general, @stringlos s no están vinculados a idiomas o configuraciones regionales. Los baberos son el camino a seguir si desea una verdadera localización.

No puedo decir con el ejemplo de su pregunta cuál de los dos enfoques sería más útil en su caso de uso.

¿Podemos conseguir lo que quieres?

Si insiste en el esquema que describió en su pregunta, entonces eso es casi posible combinando los dos enfoques. No creo que sea una buena idea, pero vámonos.

Para cada valor posible sin llaves, debe definir a @stringcon un texto de reemplazo. Si desea una solución portátil, debe hacerlo en un .bibarchivo especial que deberá cargar en todos sus proyectos.

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

Luego haz que los baberos bracelessa, bracelessbconocidos porbiblatex

\NewBibliographyString{bracelessa}
\NewBibliographyString{bracelessb}

y definirlos

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

Luego use el formato de campo.

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

para el campo en cuestión.

Ahora

title = bracelessa,

imprimirá 'Un título' en su documento.

¿Por qué eso no te da exactamente lo que describe?

En primer lugar, la entrada sin llaves no es arbitraria. Es necesario definir tanto a @stringcomo apropiado bibstring. En segundo lugar, title = {something}no siempre se renderizará something. Si escribes title = {bracelessa}'Un título' aparecerá en su lugar. Las colisiones se pueden hacer más difíciles eligiendo nombres más ridículos para las cadenas de baberos, pero siempre serán posibles ya que no hay manera de saber si un valor de campo se proporcionó directamente o mediante un archivo @string.

información relacionada