BibTeX

BibTeX의 버전 번호는 지금도 0.99d입니다. TeX Live 2024에 들어 있는 것도 이 번호이며, 공식 문서 btxdoc.tex는 여전히 1988년 2월 8일 날짜를 달고 “BibTeX 1.00이 나오면 이 문서를 확장하겠다”고 적어 두고 있습니다. 1.00은 아직 나오지 않았습니다. 그럼에도 BibTeX는 LaTeX에서 참고문헌을 다룰 때의 기준점으로 남아 있습니다. 이유는 간단합니다. 처음부터 문헌이 무엇인가(.bib 데이터베이스)와 그것을 어떻게 인쇄하는가(.bst 스타일)를 갈라놓았기 때문입니다. 이 페이지에서는 .bib 작성법, \cite\bibliographystyle\bibliography가 각각 하는 일, latex → bibtex → latex → latex라는 네 번의 빌드, 그리고 LaTeX Warning: Citation ... undefined가 사라지지 않을 때의 원인을 차례로 살펴봅니다.

BibTeX가 LaTeX와 별개의 프로그램인 이유

BibTeX는 LaTeX의 일부가 아니라 독립된 실행 파일입니다. 게다가 .tex 파일은 한 번도 읽지 않습니다. 읽는 것은 LaTeX가 내놓은 .aux뿐이며, 거기서 어떤 키가 인용되었는지, 어떤 스타일을 요구했는지, 어떤 .bib를 열어야 하는지 세 가지를 집어 낸 뒤 결과를 .bbl에 써 돌려줍니다. 이 철저한 분업이 뒤에 나올 네 번의 빌드가 필요한 이유 그 자체입니다. 표준 스타일 파일 머리에는 지금도 “Copyright (C) 1984, 1985, 1988 Howard Trickey and Oren Patashnik”라는 저작권 표시가 남아 있습니다. LaTeX 자체가 아직 모습을 갖추어 가던 시기입니다. BibTeX는 나중에 덧붙인 확장이 아니라 거의 동갑내기 짝으로 설계되었습니다.

구조는 세 부품으로 나뉩니다. 문헌의 원자료를 담은 .bib 파일, 본문에 두는 \cite와 두 명령(\bibliographystyle, \bibliography), 그리고 모양을 정하는 .bst 파일입니다. thebibliography 환경으로 문서 끝에 문헌을 손수 늘어놓는 방식도 작은 문서라면 충분합니다. 그러나 같은 문헌을 여러 논문에서 돌려 쓰기 시작하는 순간 어느 판이 옳은지 알 수 없게 됩니다. BibTeX가 푼 문제가 바로 이것입니다. 자료를 한곳에 모아 두면 투고처가 바뀌어도 오후 한나절이 아니라 스타일 이름 한 단어면 끝납니다. LaTeX 전체를 관통하는 “구조와 표현의 분리”라는 발상이 참고문헌에도 그대로 적용된 셈입니다.

.bib 항목 쓰는 법: 항목 유형・인용 키・필드

.bib 파일은 항목을 나열한 평범한 텍스트입니다. 각 항목은 @article처럼 항목 유형을 선언한 뒤, 중괄호 안 맨 앞에 인용 키를 적고 이어서 필드fieldname = {value} 형태로 쉼표로 구분해 씁니다. 인용 키는 본문의 \cite{...}와 한 글자도 어긋나면 안 되는 식별자이며, 이름 짓기는 자유입니다. 관례인 “성+연도”, 곧 knuth1984 같은 형태는 충돌이 드물고 공저 논문에서도 기억에 남습니다. 필드의 순서는 결과에 영향을 주지 않습니다. 정렬과 성형은 스타일의 몫이기 때문입니다.

references.bib
@string{bstj = "Bell System Technical Journal"}

@book{knuth1984,
  author    = {Donald E. Knuth},
  title     = {The {TeX}book},
  publisher = {Addison-Wesley},
  year      = {1984}
}

@article{shannon1948,
  author  = {Claude E. Shannon},
  title   = {A Mathematical Theory of Communication},
  journal = bstj,          % @string abbreviation, no braces
  volume  = {27},
  number  = {3},
  pages   = {379--423},
  year    = {1948}
}

@inproceedings{lamport1987,
  author    = {Leslie Lamport},
  title     = {Document Production: Visual or Logical?},
  booktitle = {Proceedings of TUG},
  year      = {1987},
  pages     = {19--24}
}

어떤 필드가 필수인지는 BibTeX 본체가 아니라 스타일이 정합니다. 표준 plain을 쓰면 빠진 필드가 Warning--empty journal in shannon1948처럼 하나하나 지목됩니다. 오류가 아니라 경고이므로 처리는 멈추지 않습니다. 다만 그 정보가 아무 말 없이 출력에서 사라질 뿐이므로, 경고는 반드시 읽어야 합니다. @string{bstj = "..."}로 학술지명 같은 약칭을 정의해 두면 중괄호 없는 맨 이름으로 값을 참조할 수 있습니다. 또 crossref 필드를 쓰면 논문집의 한 편이 상위 @proceedings 항목을 상속받아, 학회명과 출판사를 편마다 다시 쓰지 않아도 됩니다.

항목 유형대상plain의 필수 필드
@article학술지에 실린 논문author, title, journal, year
@book출판사에서 낸 단행본author 또는 editor, title, publisher, year
@inproceedings학회 논문집에 실린 발표author, title, booktitle, year
@incollection제목을 따로 가진 책의 한 장author, title, booktitle, publisher, year
@phdthesis박사 학위논문(석사는 @mastersthesis)author, title, school, year
@techreport연구 기관이 낸 보고서author, title, institution, year
@unpublished간행되지 않은 초고나 사신author, title, note
@misc어디에도 들어맞지 않는 것(웹 페이지 등)필수 없음. howpublishednote가 대신함

제목의 TeXtex가 되는 이유: 중괄호로 대문자 지키기

plainabbrv는 논문 제목을 첫 글자만 남기고 소문자로 바꿉니다. 그래서 title = {A Note on TeX and NASA Systems}라고 쓴 @article은 출력에서 “A note on tex and nasa systems”가 됩니다. 고유명사도 약어도 가차 없이 뭉개집니다. 막는 방법은 하나뿐입니다. 지키고 싶은 부분을 중괄호로 한 겹 더 감싸는 것입니다. {TeX}, {NASA}처럼 쓰면 그 범위는 변환 대상에서 빠집니다. 참고로 이 소문자 변환은 논문 제목(title)에 걸리며 책 제목이나 booktitle에는 걸리지 않습니다. 즉 @book{TeX}를 써도 해롭지는 않지만 효과도 없다는 점을 알아 두면 혼란이 줄어듭니다.

references.bib
% unprotected: plain.bst prints "A note on tex and nasa systems"
@article{bad,
  author  = {A. One},
  title   = {A Note on TeX and NASA Systems},
  journal = {J. Test},
  year    = {2000}
}

% protected: prints "A note on {TeX} and {NASA} systems"
@article{good,
  author  = {B. Two},
  title   = {A Note on {TeX} and {NASA} Systems},
  journal = {J. Test},
  year    = {2000}
}

% names: separate with "and"; brace a corporate author whole
@misc{org,
  author = {{World Health Organization}},
  title  = {Annual Report},
  year   = {2024}
}

저자명도 같은 발상으로 다뤄집니다. 여러 명은 and로 구분하고(author = {A. Smith and B. Jones}), 쉼표는 성과 이름을 가르는 용도로 예약되어 있어 author = {Smith, Alice}는 성 Smith, 이름 Alice를 뜻합니다. 목록 끝을 and others로 맺으면 스타일이 “et al.”로 바꿔 줍니다. 까다로운 것은 단체명입니다. {World Health Organization}처럼 전체를 중괄호로 한 겹 더 감싸지 않으면 BibTeX가 성과 머리글자로 해체해 버립니다. 이름을 구문으로 읽기 때문이며, 그 해석에서 빼고 싶은 부분은 중괄호로 입을 막습니다. 여기서도 도구는 하나뿐입니다.

\bibliographystyle\bibliography가 실제로 하는 일

두 명령은 “인쇄한다”기보다 .aux에 전언을 남기는 명령입니다. \bibliographystyle{plain}은 거기에 \bibstyle{plain}을, \bibliography{references}\bibdata{references}를 써 넣고, BibTeX는 그것을 읽어 움직입니다. 여기에 더해 \bibliography에는 또 하나의 역할이 있어, 놓인 자리에 참고문헌 목록을 출력합니다. 그래서 보통 본문 맨 끝, \end{document} 바로 앞에 둡니다. 인수에는 확장자를 붙이지 않아 파일이 references.bib여도 references라고 쓰며, .bib를 여럿 쓸 때는 \bibliography{books,papers}처럼 쉼표로 나열합니다.

document.tex
\documentclass{article}
\begin{document}

TeX was created by Knuth~\cite{knuth1984}, building on
Shannon's information theory~\cite{shannon1948,lamport1987}.

% \nocite{*}            % force every entry of the database into the list
\bibliographystyle{plain}
\bibliography{references}

\end{document}

본문의 \cite{knuth1984}.bib의 인용 키를 그대로 가리킵니다. 목록에 오르는 것은 인용된 문헌뿐이며, .bib에 들어 있어도 한 번도 \cite하지 않은 항목은 무시됩니다. 반대로 전부 내보내고 싶으면 \nocite{*}를 둡니다. \nocite는 본문에 아무 표시도 남기지 않고 “인용했다”고 등록만 하는 명령입니다. 키는 \cite{shannon1948,lamport1987}처럼 한 번에 묶을 수 있습니다. 대괄호로 쪽을 덧붙이는 \cite[p.~42]{knuth1984}나 저자-연도식인 natbib\citet\citep\cite 쪽의 쓰임새는 인용 페이지에서 다룹니다.

latex → bibtex → latex → latex: 왜 네 번 돌리는가

네 번이 필요한 이유는 정보가 한 번에 한 방향으로만 흐르기 때문입니다. .aux가 없으면 BibTeX는 무엇을 인용했는지 알 수 없고, .bbl이 없으면 LaTeX는 무엇을 인쇄해야 할지 알 수 없습니다. 게다가 “[1]”, “[2]” 같은 번호는 참고문헌 목록을 실제로 조판해 보아야 확정되므로, 그 번호를 본문의 \cite 표시에 되돌리려면 한 바퀴가 더 필요합니다. BibTeX 공식 문서 btxdoc.tex가 이 절차를 직접 밝혀 두었고, 아주 드물게는 BibTeX와 LaTeX를 한 번씩 더 돌려야 할 수도 있다고 덧붙이고 있습니다.

  • 1번째 latex — 본문을 처리해 인용된 키를 \citation{...}으로, 스타일과 데이터베이스 지정을 \bibstyle{...}\bibdata{...}.aux에 써 냅니다. 이 시점에 참고문헌 목록은 아직 존재하지 않습니다.
  • bibtex.aux만 읽어 어떤 키, 어떤 스타일, 어떤 .bib인지 파악합니다. 데이터베이스에서 해당 항목을 꺼내 .bst 규칙으로 성형하고, thebibliography 환경 전체를 .bbl 파일로 써 냅니다.
  • 2번째 latex.bbl을 읽어 참고문헌 목록을 조판합니다. 그러나 본문의 \cite는 아직 옛 .aux를 보고 있어 Citation ... undefined 경고가 이 회차에도 사라지지 않습니다.
  • 3번째 latex — 번호가 확정되어 본문 인용과 목록이 비로소 맞아떨어집니다. 경고는 이때야 멈춥니다.
terminal
$ pdflatex document.tex   # writes document.aux (\citation, \bibstyle, \bibdata)
$ bibtex   document       # note: job name, not document.tex -> writes .bbl and .blg
$ pdflatex document.tex   # pulls in .bbl; citations still undefined here
$ pdflatex document.tex   # numbers settle; warnings clear

명령 표기에서 유일한 함정은 bibtex에 넘기는 것이 .tex가 아니라 확장자 없는 작업 이름이라는 점입니다. bibtex document.tex라고 치면 document.tex.aux를 찾다가 실패합니다. BibTeX는 결과와 별도로 .blg라는 로그를 남기므로, 경고의 전문을 나중에 다시 읽고 싶을 때는 이 파일을 엽니다. 그리고 실무에서는 이 네 줄을 손으로 칠 일이 없습니다. latexmk.aux를 들여다보고 BibTeX 실행 여부와 반복 횟수를 판단해 주므로 latexmk -pdf document.tex 한 줄이면 됩니다.

Citation ... undefined와 참고문헌이 비어 나올 때

LaTeX Warning: Citation ... undefinedLaTeX Warning: There were undefined references.가 뜨고, 본문의 인용이 [?]로 나오며, 참고문헌이 제목째 사라져 있습니다. 열에 아홉은 원인이 단순히 돌린 횟수가 모자란 것입니다. .bbl이 아직 없으면 LaTeX는 목록을 한 줄도 찍지 않습니다. 제목마저 없는 까닭은 thebibliography 환경 자체가 .bbl 안에 들어 있기 때문입니다. 그러니 먼저 차분히 latex → bibtex → latex → latex를 끝까지 통과시키세요. 그래도 경고가 남는다면 BibTeX 쪽이 자기 나름의 다른 메시지를 남겼을 것입니다.

메시지나오는 곳원인과 대처
Citation ... undefinedLaTeX.bbl이 아직 없거나 오래됨. latex → bibtex → latex → latex를 끝까지 실행
There were undefined references.LaTeX해결되지 않은 \cite\ref가 남아 있음. latex를 한 번 더 실행
I found no \citation commandsBibTeX\cite\nocite도 없음. 인용을 넣거나 \nocite{*}를 추가
I found no \bibstyle commandBibTeX문서에 \bibliographystyle{...}을 쓰지 않음
I found no database filesBibTeX\bibliography{...}가 없거나 지정한 .bib를 찾을 수 없음
I found no style fileBibTeX그 이름의 .bst가 없음. 철자를 확인하거나 투고처의 .bst를 배치
Warning--I didn't find a database entryBibTeX인용한 키가 .bib에 없음. 철자가 다르거나 항목을 넣지 않았음

그래도 낫지 않는다면 의심할 것은 오래된 보조 파일입니다. 키 이름을 바꾸었거나, .bib를 다른 디렉터리로 옮겼거나, 스타일을 갈아 끼운 뒤에는 .aux.bbl.blg에 지난번 정보가 그대로 남아 있을 수 있습니다. latexmk -C를 실행하면 생성물을 한꺼번에 지워 주므로, 그다음 처음부터 다시 빌드하는 편이 가장 빠릅니다. 또한 인용 키는 대소문자를 구별하므로 Knuth1984knuth1984는 BibTeX에게 서로 다른 문헌입니다.

plainunsrtalphaabbrv의 차이

네 표준 스타일이 정하는 것은 정렬 순서, 레이블의 형태, 이름과 학술지명을 어디까지 줄이는가 세 가지뿐이고, 담는 필드는 모두 같습니다. 그럴 만도 한 것이, plain.bstunsrt.bstalpha.bstabbrv.bst하나의 파일에서 만들어집니다. btxbst.doc라는 템플릿을 C 전처리기에 -DPLAIN, -DUNSRT, -DALPHA, -DABBRV로 나누어 넘겨 생성한다고 그 파일 첫머리에 적혀 있습니다. 넷이 미묘하게 달라 보이는 것은 같은 본문을 조건부로 컴파일한 결과인 셈입니다.

스타일정렬 순서레이블과 특징
plain저자 알파벳순[1] 형태의 일련번호. 가장 무난한 기본값
unsrt본문에서 처음 인용한 순서[1] 일련번호. 서식은 plain과 동일
alpha레이블순(사실상 저자와 연도)[Knu84] 같은 영숫자 레이블. 수식이 많은 분야에서 읽기 좋음
abbrv저자 알파벳순번호는 plain과 같지만 이름・월・학술지명을 축약해 분량을 줄임

BibTeX 배포물에는 이와 별도로 자체 README가 “준표준”이라 부르는 네 가지 스타일도 들어 있습니다. acm(ACM Transactions식), apalike(APA식 저자-연도, apalike.sty와 함께 사용), ieeetr(IEEE Transactions식, 인용 순서 번호), siam(SIAM식)입니다. 공학이라면 ieeetr, 컴퓨터 과학이라면 acm, 심리학이나 사회과학에서 저자-연도가 필요하다면 apalike에서 출발하는 것이 무난합니다. 그 밖에 학회와 출판사가 투고 규정에 맞춘 .bst를 배포하므로, 투고처가 정해져 있다면 그것부터 찾아보세요. 어느 스타일로 옮기든 .bib와 본문의 \cite는 한 줄도 고칠 필요가 없습니다.

.bst를 손으로 쓰지 않는 이유: makebstcustom-bib

.bst가 기피되는 까닭은 그것이 후위 표기 스택 언어로 쓰여 있기 때문입니다. 스타일 설계자를 위한 공식 문서 btxhak.tex(Oren Patashnik, 1988년 2월 8일)는 첫머리에서 이렇게 못 박습니다. 문헌 스타일은 후위 스택 언어로 쓰며, 스타일 파일은 “이름 없는 언어로 쓰인 프로그램”이라고. 언어에 이름조차 없습니다. 명령은 열 개뿐이지만 모든 값을 스택에 쌓고 꺼내는 방식이라, author 하나를 성형하는 데도 역폴란드 표기의 조각이 길게 이어집니다. 기존 .bst를 읽고 흉내 내는 것은 가능하지만, 맨바닥에서 설계하는 일은 수지가 맞지 않습니다.

terminal
$ latex makebst      # answer the questions; choose "merlin" as the master file
                     # -> writes a .dbj batch job
$ latex mystyle.dbj  # runs docstrip -> mystyle.bst

그래서 실제로 쓰이는 것이 custom-bib 패키지이고, 그 입구가 makebst입니다. latex makebst라고 치면 대화식 질문이 시작됩니다. 성을 앞에 둘지, 연도를 괄호에 넣을지, 제목을 이탤릭으로 할지—답해 나가기만 하면 반대편에서 .bst가 나옵니다. 만든 이는 Patrick W. Daly로, 저자-연도 인용을 LaTeX 쪽으로 들여온 natbib의 저자와 같은 인물이며, makebst가 내놓는 스타일은 natbib와 함께 쓰도록 설계되어 있습니다. 투고 규정이 기존 스타일과 아슬아슬하게 어긋날 때 가장 현실적인 탈출구입니다.

일본어 문헌 다루기: pbibtexupbibtex

기본 bibtex는 서양어를 전제로 하므로, 일본어 저자명이나 제목이 들어간 .bib에서는 정렬도 문자열 처리도 무너집니다. 그래서 TeX Live에는 pbibtex(pLaTeX용, EUC-JP 코드 포인트순 정렬)와 upbibtex(upLaTeX용, Unicode 코드 포인트순)가 들어 있습니다. 중요한 것은 단순한 인코딩 교체가 아니라 스타일 언어 자체가 확장되었다는 점입니다. 문자열에 비 ASCII 문자가 있는지 판정하는 내장 함수 is.kanji.str$가 추가되었고, substring$은 멀티바이트 문자를 중간에서 자르지 않도록, add.period$는 「。」나 「?」 뒤에 마침표를 덧붙이지 않도록 손질되었습니다. 계보는 마쓰이 쇼이치의 JBibTeX로 거슬러 올라가며, 배포물은 그 역사를 문서째 함께 담고 있습니다.

terminal
$ uplatex   document.tex   # 1st pass: writes .aux
$ upbibtex  document       # Japanese-aware: writes .bbl
$ uplatex   document.tex   # pulls in .bbl
$ uplatex   document.tex   # resolves references
$ dvipdfmx  document.dvi   # DVI -> PDF

스타일도 일본어판이 함께 들어 있습니다. plain에 대응하는 jplain, unsrtjunsrt, alphajalpha, abbrvjabbrv, 그리고 성을 앞세우는 jname입니다. 학회용으로는 jipsj(정보처리학회), tipsj, tieice(전자정보통신학회), jorsj가 준비되어 있습니다. 그리고 이들 역시 jbtxbst.doc라는 하나의 템플릿에서 C 전처리기로 잘라 낸 것으로, 서양어 쪽과 만드는 방식이 똑같습니다. 빌드는 이름만 바뀝니다. latexplatexuplatex로, bibtexpbibtexupbibtex로 바꿉니다. DVI를 거치므로 마지막에 dvipdfmx로 변환합니다. latexmk는 설정 파일에서 이들을 호출하도록 지정할 수 있어 일본어 작업도 똑같이 자동화됩니다.

BibTeX를 계속 쓸 것인가, biblatex/biber로 옮길 것인가

판단의 경계는 분명합니다. 투고처가 .bst를 지정한다면 BibTeX, 체재를 스스로 정할 수 있다면 biblatex/biber입니다. BibTeX의 설계는 8비트 문자 인코딩을 전제로 하므로 여러 언어가 섞인 저자명과 악센트 문자에 손이 더 가고, 정렬 규칙에는 손이 닿지 않습니다. 체재를 세밀하게 바꾸려면 결국 .bst를 건드려야 하는데, 그것이 앞 절에서 본 이름 없는 스택 언어입니다. 요컨대 BibTeX의 약점은 모두 “1988년에 얼어붙은 설계”라는 한 가지에서 비롯합니다.

그 너머에 있는 것이 biblatex(LaTeX 패키지)와 그 기본 백엔드 biber입니다. Unicode를 있는 그대로 다루고, 정렬과 체재를 LaTeX 쪽 옵션으로 드러내며, .bst를 한 줄도 쓰지 않게 해 줍니다. 명령도 바뀌어 \cite 대신 \autocite\printbibliography를 쓰고, 빌드에서는 bibtex 대신 biber를 부릅니다. 다만 .bib 파일 자체는 양쪽이 공통이라 갈아타는 비용은 생각보다 작습니다. 40년 전에 “문헌이 무엇인가”와 “어떻게 인쇄하는가”를 갈라 둔 설계가 가장 크게 보답하는 지점이 바로 여기입니다.