Invocar funciones indirectamente (usando una cadena) en BibTeX

Invocar funciones indirectamente (usando una cadena) en BibTeX

¿Es posible realizar llamadas a funciones indirectas en estilos BibTeX, es decir, obtener el nombre de la función de un campo en .bib? EXECUTEPodría hacer eso, pero estas declaraciones no funcionan dentro de funciones (?).

Mi solución actual es buscar el nombre del campo, compararlo con una cadena literal y llamar a la función respectiva si coincide. Esto funciona pero es horrible (¿probablemente sea cierto ya que es un .bst? :)
Por ejemplo:

FUNCTION {format.thesis.type}
{ this.to.prev.status
  this.status.std
  type empty$
    {
      % Leave warnings to callers
      ""
    }
    {
      type "bthesis" =
      {
        bbl.bthesis
      }
      {
        type "mthesis" =
        {
          bbl.mthesis
        }
        {
          type "phdthesis" =
          {
            bbl.phdthesis
          }
          {
            type "Unknown thesis type " swap$ * ", printing it verbatim" * warning$
            type
          }
        if$
        }
      if$
      }
    if$
    }
  if$
  cap.status.std
}

Respuesta1

Como habrás adivinado, no puedes.

BibTeX, al igual que TeX, guarda funciones en una tabla hash. TeX tiene \csname<control-sequence>\endcsnameque buscar la entrada de la tabla hash que corresponde al literal de cadena <control-sequence>.
BibTeX no :-)

Para tener eso, necesitarías agregar esa funcionalidad al propio BibTeX (lo cual puede no ser la tarea más divertida).


Como premio de consolación, aquí tienes una strcasefunción que puede hacer que tu tarea sea menos aburrida.

La sintaxis es:

{ Other cases } "{OTHERWISE}"
{ Case n } <string n>
...
{ Case 2 } <string 2>
{ Case 1 } <string 1>
<string> strcase

La función strcasecomparará <string>cada uno <string n>(de 1a n: esta es una notación pulida inversa, por lo que leerá los elementos al revés) y, una vez que se encuentra una coincidencia, Case nse ejecuta el código y el resto se descarta (incluso si varias cadenas coinciden). ). Si no se encuentra ninguna coincidencia, Other casesse ejecuta el código. Puedes utilizar tantos { Case n } <string n>pares como desees, pero el final { Other cases } "{OTHERWISE}"es obligatorio, para que la función sepa dónde detenerse.

Su caso podría redactarse como (con una verificación previa de type missing$:

FUNCTION {format.thesis.type}
{ this.to.prev.status
  this.status.std
  type missing$
    {
      % Do something when type is not given
    }
    {
      { "Unknown thesis type "  type ", printing it verbatim" * * warning$ }
                        "{OTHERWISE}"
      { bbl.bthesis }   "bthesis"
      { bbl.mthesis }   "mthesis"
      { bbl.phdthesis } "phdthesis"
      type strcase
    }
  if$
  cap.status.std
}

Aquí hay un ejemplo compilable con el .bstcódigo:

\begin{filecontents*}{test.bst}
ENTRY { type name } { } { }
INTEGERS { strcase.next } % the code requires an integer
STRINGS { s t } % and two strings
FUNCTION { not }
  {   { #0 }
      { #1 }
    if$
  }
FUNCTION { pop.next } { swap$ pop$ }
FUNCTION { strcase.end }
  { #0 'strcase.next :=
    #1
      swap$
      'skip$
    if$
  }
FUNCTION { strcase }
  { #1 'strcase.next :=
      { strcase.next }
      { 's :=
        't :=
        s t =
          {   { swap$ "{OTHERWISE}" = not }
              { pop.next }
            while$
            pop.next
            strcase.end
          }
          { "{OTHERWISE}" t =
              { strcase.end }
              { pop$ s }
            if$
          }
        if$
      }
    while$
  }
FUNCTION { thesis }
  {
    type missing$
      { "Type missing for entry " cite$ * warning$ }
      {
        { "Unknown thesis type "  type ", printing it verbatim" * * warning$ }
          "{OTHERWISE}"
        { "This is a bachelor thesis" warning$ } "bthesis"
        { "This is a master thesis" warning$ }   "mthesis"
        { "This is a doctor thesis" warning$ } "phdthesis"
        type strcase
      }
    if$
  }
READ
ITERATE {call.type$}
\end{filecontents*}
\begin{filecontents*}{test.bib}
@thesis{bach, type = {bthesis}}
@thesis{mast, type = {mthesis}}
@thesis{doct, type = {phdthesis}}
@thesis{unkn, type = {unknown}}
@thesis{void, name = {me}}
\end{filecontents*}
\documentclass{article}
\begin{document}
\nocite*
\bibliography{test}
\bibliographystyle{test}
\end{document}

información relacionada