bstファイル:文献リストにおける著者名の表示

bstファイル:文献リストにおける著者名の表示

- hhh kkk の投稿
返信数: 2

文献リストにおける著者名の表示を以下のようになるbstファイルを作成する必要がありまして、このフォーラムに質問させていただきました。

--------------------------------

著者が
1名の場合  : Sato, T.
2名の場合  : Sato, T. and Kato, M.
3名の場合  : Sato, T., Kato, M., and Yamada, D.
4名以上の場合: Sato, T., Kato, M., Yamada, D. et al.
と参考文献リストに表示するbstファイルを作成する必要があり、
色々試しているのですが、うまくいきません。
以下、改良前後のbstの関連する部分を示します。

なお、改良前のbstは、IEEEのとある雑誌のbstファイルをダウンロードして、
ほんの少しだけ変更したものとなっており、以下のように著者名が文献リストに表示されます
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 改良前のbst:
%% 
%% 1名の場合  : Sato, T.
%% 2名の場合  : Sato, T. and Kato, M.
%% 3名以上の場合: Sato, T., Kato, M., and Yamada, D. % 最後の著者名の前だけandをつける
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
FUNCTION {format.names}
{ 's :=
  #1 'nameptr :=
  s num.names$ 'numnames :=
  numnames 'namesleft :=
    { namesleft #0 > }
    { s nameptr
      "{vv~}{ll}{, jj}{, f.}" format.name$ 't :=
      nameptr #1 >
        {
          namesleft #1 >
            { ", " * t * }
            {
              numnames #2 >
                { ", " * }
                'skip$
              if$
              t "others" =
                { " et~al." * }
                { bbl.and space.word * t * }
              if$
            }
          if$
        }
        't
      if$
      nameptr #1 + 'nameptr :=
      namesleft #1 - 'namesleft :=
    }
  while$
}

FUNCTION {format.authors}
{ author empty$
    { "author missing" }
    { author format.names }
  if$
}


----------------------------------
以下は、
ChatGPTにプロンプト入力して、仕様の動作を行うbstの作成を試みた結果です。
期待どおりには動作せず、どのように変更すればいいかよく分かりません。

---------------------
FUNCTION {format.names}
{ 's :=                        % 著者名リストを s に保存
  #1 'nameptr :=                % 現在の著者インデックス
  s num.names$ 'numnames :=     % 著者数
  numnames 'namesleft :=

  { nameptr numnames > not }    % ループ条件
  { 
    % ---- 区切り文字の処理 ----
    nameptr #1 >                % 2人目以降なら
      {
        numnames #4 >= nameptr #3 = and
          { ", " * }            % 4人以上で3人目 → カンマ
          {
            nameptr = numnames  % 最後の著者?
              {
                numnames #2 =   % 2人なら
                  { " and " * }
                  { ", and " * }% 3人なら
                if$
              }
              { ", " * }        % 中間の著者
            if$
          }
        if$
      }
      'skip$
    if$

    % ---- 著者名の出力(姓, 名イニシャル)----
    s nameptr "{vv~}{ll}{, jj}{, f.}" format.name$ 't :=

    % ---- 4人以上の場合の処理 ----
    numnames #4 >= nameptr #3 = and
      { " et~al." * #99 'nameptr := } % et al. を付けてループ終了
      { nameptr #1 + 'nameptr := }    % 次の著者へ
    if$
  }
  while$
}


FUNCTION {format.authors}
{ author empty$
    { "author missing" }
    { author format.names }
  if$
}
------------------------------------

hhh kkk への返信

Re: bstファイル:文献リストにおける著者名の表示

- Z. R. の投稿

# ChatGPTの吐いたコードは見てませんが……

「手っ取り早く修正すること」を考えます。

改修要件で変化する部分を考えると以下の処理を割り込ませればよいはずです。

  • 4件目の処理の場合に(nameptr = 4
    • 名前を"others"だと見なす(t := "others"
      and othersを“et al.”にする処理は実装済です。
    • 残り件数を1にする(namesleft := 1

なので以下のコードをtへの代入の直後に入れます。

      nameptr #4 =
        { "others" 't :=
          #1 'namesleft :=
        }
        'skip$
      if$

これで改修要件とほぼ同じになるますが、“et al.”の前のコンマが余計です。従って、コンマを出力するコードを「"others"でない場合」の分岐の中に入れます。これで要件通りになります。

format.names関数の改修後のコードを添付しました。

Z. R. への返信

Re: bstファイル:文献リストにおける著者名の表示

- hhh kkk の投稿
ご提示のコードで確かに要求仕様どおりの動作・表示になりました。ありがとうございました。