Indirektes Aufrufen von Funktionen (mithilfe einer Zeichenfolge) in BibTeX

Indirektes Aufrufen von Funktionen (mithilfe einer Zeichenfolge) in BibTeX

Ist es möglich, indirekte Funktionsaufrufe in BibTeX-Stilen durchzuführen, d. h. den Funktionsnamen aus einem Feld im .bib? zu erhalten EXECUTE? Das wäre möglich, aber diese Anweisungen funktionieren nicht innerhalb von Funktionen(?).

Mein aktueller Workaround besteht darin, den Feldnamen abzurufen, ihn mit einem Stringliteral zu vergleichen und bei Übereinstimmung die entsprechende Funktion aufzurufen. Das funktioniert, ist aber schrecklich (also wahrscheinlich richtig, da es ein .bst? ist :)
Beispiel:

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
}

Antwort1

Wie Sie vermutet haben, ist das nicht möglich.

BibTeX speichert, genau wie TeX, Funktionen in einer Hash-Tabelle. TeX muss \csname<control-sequence>\endcsnameden Hash-Tabelleneintrag abrufen, der dem Stringliteral entspricht <control-sequence>.
BibTeX muss das nicht :-)

Dazu müssten Sie diese Funktionalität zu BibTeX selbst hinzufügen (was möglicherweise nicht die angenehmste Aufgabe ist).


Als Trostpreis gibt es hier eine strcaseFunktion, die Ihre Aufgabe vielleicht weniger langweilig macht.

Die Syntax lautet:

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

Die Funktion strcasevergleicht die <string>miteinander <string n>(von 1bis n: dies ist die umgekehrte polnische Notation, die Elemente werden also rückwärts gelesen) und sobald eine Übereinstimmung gefunden wird, Case nwird der Code für ausgeführt und der Rest verworfen (auch wenn mehrere Zeichenfolgen übereinstimmen). Wenn keine Übereinstimmung gefunden wurde, Other caseswird der Code ausgeführt. Sie können so viele { Case n } <string n>Paare verwenden, wie Sie möchten, aber das letzte { Other cases } "{OTHERWISE}"ist obligatorisch, damit die Funktion weiß, wo sie aufhören soll.

Ihr Fall könnte wie folgt lauten (mit vorheriger Prüfung auf 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
}

Hier ist ein kompilierbares Beispiel mit dem .bstCode:

\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}

verwandte Informationen