[BiBTeX] bst ファイルのカスタマイズ

bstファイルをいじらない方法

文献の引用が確定し、BibTeXで処理することがなくなった場合、 bbl ファイルをUTF8対応のテキストエディタでいじります。 [huh]

本文中の et~al. をイタリックにしたい。

bbl ファイルの

\bibitem[Abascal et~al., 2005]

\bibitem[Abascal {\itshape et~al.}, 2005]

というように置換します。

たくさんある場合は、”et~al.” を”{\itshape et~al.} で一括置換します。

bstファイルをいじる方法

まず、所望の出力に近い bstファイルを探します。ここでは、plain.bstを例にとって説明します。(bstファイルの中には以下の作業ではうまく動作しない場合があります)。bstファイルの関数は次のような形式になっています。

FUNCTION{定義名}{定義の内容}

plain.bstをテキストエディタで開くと,次のような関数があります。

FUNCTION {article} { output.bibitem
 format.authors "author" output.check 
 new.block 
 format.title "title" output.check 
 new.block 
 crossref missing$ 
   { journal emphasize "journal" output.check 
     format.vol.num.pages output 
     format.date "year" output.check 
   } 
   { format.article.crossref output.nonnull 
     format.pages output 
   } 
 if$ 
 new.block 
 note output 
 fin.entry

}

これは、articleというエントリ型で、フィールドを次のような順番に出力せよいう命令です。

著者名.タイトル.雑誌名.(巻,号,引用ページ).年号.

フィールドの並べ替え

format.フィールド output.check

の順番を入れ替えることで,フィールドを並べ替えることができます.著者名の次に年号を表示したい場合は,次のように入れ替えます。

FUNCTION {article} { output.bibitem
format.authors "author" output.check

newblock   format.date “year” output.check

 new.block 
 format.title "title" output.check 
 new.block 
 crossref missing$ 
   { journal emphasize "journal" output.check 
     format.vol.num.pages output 
   } 
   { format.article.crossref output.nonnull 
     format.pages output 
   } 
 if$ 
 new.block 
 note output 
 fin.entry

}

フィールドで表示される文字の変更

incollectionなどのエントリ型ではフィールドの1つに「editor」が用いられます.editor は次のように表示されます.

David K. Levine and Steven A. Lippman editors

このeditorsやeditorsを(ed)や(eds)に変更します.このようにフィールドで表示される文字を変更するには各フィールドの関数を変更します.

#sh{{ FUNCTION { fomat.フィールド} }}

この例では次の関数が変更箇所となります.

FUNCTION {format.editors} { editor empty$
   { "" } 
   { editor format.names 
     editor num.names$ #1 > 
{ ", editors" * } 
{ ", editor" * } 
     if$ 
   } 
 if$

}

この中のeditor, editorsを(ed),(eds)に置き換えるだけです.

この関数の中には編集者が2人以上ならば (editors) そうでないならば (editor) というような条件分岐が存在します.一般に bst ファイルの条件分岐は次のような形になっています.

条件$

    {条件が真のとき}
    {条件が偽のとき}

if$ }

editorにおいて,2つの条件分岐が存在します.

条件:editor empty$.「編集者がいないとき(empty)」 条件:editor num.names$ #1 > .「編集者の人数(editor num.names)が1より大きいとき(#1 >」

著者名の出力の変更

author (editorを含む)の書式を指示する関数はnamesです.

FUNCTION {format.names} { ‘s :=
 #1 'nameptr := 
 s num.names$ 'numnames := 
 numnames 'namesleft := 
   { namesleft #0 > } 
   { s nameptr "{ff~}{vv~}{ll}{, jj}" format.name$ 't := 
     nameptr #1 > 
{ namesleft #1 > 
    { ", " * t * } 
    { numnames #2 > 
 { "," * } 
 'skip$ 
      if$ 
      t "others" = 
 { " et~al." * } 
 { " and " * t * } 
      if$ 
    } 
  if$ 
} 
't 
     if$ 
     nameptr #1 + 'nameptr := 
     namesleft #1 - 'namesleft := 
   } 
 while$

}

7行目の部分はFirst Name Last Name von Jrを表しています.記号の意味は次の表の通りです.

変更例

ll Last Nameをすべて表示
ff First Nameをすべて表示
vv vonをすべて表示
jj Jr.をすべて表示
l Last Name の頭文字のみ表示
f First Name の頭文字のみ表示
v von の頭文字のみ表示
j Jr. の頭文字のみ表示

変更例

赤字の部分 フィールド 出力
{f.~}{v.~}{ll}{, jj} John Maynard Keynes J. M. Keynes
{ll}{, vv~}{,ff} John Maynard Keynes Keynes,John Maynard
  • 「~」(ティルダ)は文字を切り離さないための命令です。日本語でも、姓と名が別の行にあれば縁起が悪いとされますが、そうならないための命令と解釈してください。
  • 「.」(ピリオド)は省略された名につける記号です。
  • 「,」(カンマ)はLast Nameが先に表示された場合につける記号です。

著者が複数人の場合

plainスタイルでは,著者名を「David Baron and David Besanko」と入力すると,「David Baron and David Besanko」と出力されます.これを「Baron, D. and D. Besanko」のように一人目だけ Lasr Name を最初に表示したい場合は次のように関数を変更します。

FUNCTION {format.names} { ‘s :=
 #1 'nameptr := 
 s num.names$ 'numnames := 
 numnames 'namesleft := 
   { namesleft #0 > } 
  { nameptr #1 >  
       { s nameptr "{f.~}{vv~}{ll}{, jj}" 
            format.name$ 't :=  } %2人目以降のときの出力
       { s nameptr "{vv~}{ll}{, jj}{, f.}" 
            format.name$ 't :=} %1人目の出力
     if$ 
     nameptr #1 > 
       { 
         namesleft #1 > 
           { ", " * t * } 
           { 
             ", " * 
      t "others" = 
 { " et~al." * } 
 { " and " * t * } 
      if$ 
    } 
  if$ 
} 
't 
     if$ 
     nameptr #1 + 'nameptr := 
     namesleft #1 - 'namesleft := 
   } 
 while$

} }}}}}

タイトルの出力の変更

plain.bstでは,タイトルを「Implementaion and Information in Teams」と入力すると,次のように最初の文字を残してすべて小文字で出力します.

Implementaion and information in teams これは関数title 関数によって出力が制御されます.

FUNCTION {format.title} { title empty$ %もしtitleフィールドが空白ならば
   { "" }         %何も記述しない 
   { title "t" change.case$ } %さもなければ,
   titleの表記を先頭をのぞいて小文字(t)に変換して記述せよ. 
 if$               %条件終わり

} }

タイトルの大文字小文字の判断はchange.case$によって赤字の部分で指定されています.

t 先頭の頭文字を除いて,残りの頭文字を小文字に変換
l すべて頭文字を小文字に変換
u すべての文字を大文字に変換

引数の[t]は,例えば,「Subgame Perfect Implementation: A Necessary and Almost Sufficient Condition」と入力すると次のような出力になります.

Subgame perfect implementation: A necessary and almost sufficient condition

タイトルを入力通りに出力したい場合は,change.case$を書きません.

FUNCTION {format.title} { title empty$ %もしtitleフィールドが空欄ならば

   { "" }        %何も記述しない 
   { title }     %さもなければ,title を記述せよ. 
 if$             %条件終わり

}

さらに,タイトルの両側を(“),(”)で囲みたい場合は次のように書き直す.

FUNCTION {format.title} { title empty$

   { "" } % 
    {title  % 
    "``" swap$ * "''" * 
   } 
 if$

}

年号の出力の変更

年号や月の書式を整える関数はFUNCTION {format.date}であります.年号を「(1999)」のよう「( )」をつけるためには次のように書き換えます.

FUNCTION {format.date} { year empty$ %もしyearが空欄ならば
       { month empty$ %もしmonthが空欄ならば 
{ "" }                %なにも記述されない 
{ "there's a month but no year in " cite$ * warning$ 
  month               %さもなければ警告文を出力する 
} 
     if$ 
   } 
   { month empty$     %もし,yearが空欄でなくかつmonthが空欄ならば 
    {year "(" swap$ * ")" * }  %yearを記述せよ 
    { month * " " * year "(" swap$ * ")" * } %さもなければ,monthも記述せよ. 
     if$ 
   } 
 if$

}

フィールドの強調

plainスタイルのarticleのjournalは強調(\em)表示されます.強調表示は次の関数で制御されています.

FUNCTION {emphasize} { duplicate$ empty$

   { pop$ "" } 
   { "{\em " swap$ * "}" * } 
 if$

}

\emを\bfseriesに変更すると強調されているすべてのフィールドがボールド体になります.これを理解するために,journal の関数を見てみましょう.

journal emphasize “journal”  output.check

このようにフィールド名がemphasizeによってjournalが強調されていることがわかります.

応用:関数の定義

これを応用してvolumeをボールド体で出力してみよう.ボールド体で表記するために新しく関数boldを作る.関数boldは上の関数emphasizeの\emを\bfseries に変更しただけであります.

FUNCTION {bold} { duplicate$ empty$

   { pop$ "" } 
   { "{\bfseries " swap$ * "}" * } 
 if$

}

次に,volume,number,pagesをつかさどる関数を書き直します.

FUNCTION {format.vol.num.pages} { volume bold field.or.null %volumeをボールド体で記述せよ.

 number empty$ 
   'skip$ 
   { "(" number * ")" * * 
     volume empty$ 
{ "there's a number but no volume in " cite$ * warning$ } 
'skip$ 
     if$ 
   } 
 if$ 
 pages empty$ 
   ';skip$ 
   { duplicate$ empty$ 
{ pop$ format.pages } 
{ ":" * pages n.dashify * } 
     if$ 
   } 
 if$

}

pbibtexでの条件文

pBibTeXでは,bibTeXで用意されている関数の他に次の関数が追加されています.

#sh{{ is.kanji.str$ }}

jplain.bstをテキストエディッタで開き,関数editorを見てみましょう.

FUNCTION {format.editors} { editor empty$

   { "" } 
   { editor format.names 
     editor num.names$ #1 >%もし編者が二人以上ならば 
     { editor is.kanji.str$        %かつ,editorが日本語ならば 
          {"(編)" * }    %$editorに(編)を表記せよ 
          {", editors" * } %さもなければ(英語ならば)
          editorsを表記せよ. 
           if$ 
         } 
         { editor is.kanji.str$ %編者が一人でeditorが日本語ならば 
         {"(編)" *} 
       {", editor" * } 
       if$ 
     } 
   if$ 
   } 
 if$

}

このようにis.kanji.str$はフィールドが日本語であるかどうかを判断します。

ここで示したカスタマイズを下記に残しておきましょう。