프로그램 소스 코드를 행 번호와 구문 강조(예약어, 주석, 문자열 색 구분)와 함께 보기 좋게 싣고 싶을 때의 표준 선택지는 listings와 minted입니다. 전자는 외부 도구가 필요 없어 어디서나 동작하고, 후자는 외부 Pygments 엔진을 호출해 훨씬 정확한 하이라이트를 제공합니다. 입력한 그대로만 출력하면 충분하다면 더 단순한 verbatim 계열로 충분합니다.
두 가지 접근
소스 코드를 조판하는 길은 생각이 다른 두 가지입니다. listings는 순수 LaTeX 매크로만으로 구현되어 추가 소프트웨어가 전혀 필요 없습니다. Overleaf에서도, 설정을 바꿀 수 없는 실습실 환경에서도 \usepackage{listings}만 쓰면 그대로 동작합니다. 반면 minted는 Python으로 만든 본격적인 렉서 Pygments에 처리를 맡기고 그 결과를 LaTeX로 가져옵니다. Pygments는 수백 가지 언어를 실제로 해석하므로, 하이라이트 정확도는 listings보다 훨씬 높습니다.
이 차이가 곧 선택 기준입니다. 간편함과 이식성이 중요하면 listings, 하이라이트 품질이 중요하면 minted를 고릅니다. minted는 외부 프로그램을 실행하므로 아래에서 다루는 shell escape라는 특별한 허가가 필요하고, 제한된 환경에서는 동작하지 않을 수 있습니다. 코드만 그대로 출력하면 되고 색이나 행 번호가 필요 없다면 verbatim이나 fancyvrb가 더 가볍습니다. 해당 내용은 “Verbatim”을 보세요.
| listings | minted | |
|---|---|---|
ハイライト方式 / Highlighting | 키워드 목록 기반(간단) | Pygments 렉서(고정밀) |
外部依存 / Dependencies | 없음(순수 LaTeX) | Python + Pygments 필요 |
シェルエスケープ / Shell escape | 불필요 | 원칙적으로 필요(새 TeX Live에서는 예외 있음) |
対応言語 / Languages | 주요 언어 내장 | Pygments가 500개 이상 지원 |
listings 기본
먼저 \usepackage{listings}를 읽습니다. 코드 블록은 lstlisting 환경으로 감싸고, 외부 파일 전체를 가져오려면 \lstinputlisting, 본문 중 짧은 조각을 넣으려면 \lstinline을 사용합니다. 언어와 모양은 매번 옵션으로 반복하기보다 프리앰블에서 \lstset{...}에 한 번 모아 두는 것이 정석입니다.
\usepackage{listings}
\usepackage{xcolor}
\lstset{
language=Python, % 言語 / language
basicstyle=\ttfamily\small, % 本文の書体 / base font
keywordstyle=\color{blue}\bfseries,
commentstyle=\color{teal}\itshape,
stringstyle=\color{red!60!black},
numbers=left, % 行番号を左に / line numbers on the left
numberstyle=\tiny\color{gray},
frame=single, % 枠線 / a single-line frame
breaklines=true, % 長い行を折り返す / wrap long lines
showstringspaces=false, % 文字列中の空白を記号化しない
tabsize=2,
}
\begin{lstlisting}[caption={階乗を計算する}, label=lst:fact]
def factorial(n):
# 再帰で階乗を求める
if n <= 1:
return 1
return n * factorial(n - 1)
\end{lstlisting}\lstset의 주요 키는 다음과 같습니다. basicstyle은 전체 글꼴을 정하고(\ttfamily\small이 흔한 선택), keywordstyle, commentstyle, stringstyle은 예약어, 주석, 문자열의 모양을 정합니다. numbers=left는 왼쪽에 행 번호를 붙이고, numberstyle은 그 서식을 정합니다. frame=single은 테두리, breaklines=true는 긴 줄 자동 줄바꿈이며, caption=과 label=을 주면 그림이나 표처럼 번호가 붙은 “listing”이 되어 \ref로 참조할 수 있습니다.
개별 블록에서는 \begin{lstlisting}[language=C, numbers=none]처럼 [ ] 안에서 옵션을 덮어쓸 수 있습니다. 외부 파일은 \lstinputlisting[language=Python, firstline=37, lastline=45]{sample.py}처럼 행 범위도 잘라낼 수 있습니다. 본문에 코드를 넣을 때는 \verb와 같은 방식으로 구분 기호를 골라 \lstinline|while (i < n)|처럼 씁니다.
listings의 한계(UTF-8과 일본어)
listings의 하이라이트는 언어별 키워드 목록과 단순한 규칙에 의존한 근사이며, 진짜 렉서만큼 영리하지 않습니다. 같은 단어가 문맥에 따라 타입 이름이 되기도 하고 변수 이름이 되기도 하는 식의 문맥 의존 색칠은 어렵고, 복잡한 언어일수록 어색함이 드러납니다. 이는 방식 자체의 한계입니다.
또 하나의 실무적 함정은 멀티바이트 문자입니다. listings는 기본적으로 UTF-8을 전제로 하지 않기 때문에 코드 안의 일본어 주석 등이 깨지거나 열 정렬이 어긋날 수 있습니다. 대응은 두 가지입니다. 코드 조각을 본문에 직접 쓰는 경우에는 \lstset{... literate={あ}{{あ}}1 ...}처럼 literate=로 문자를 하나씩 알려 주지만, 문자가 많아지면 현실적이지 않습니다. 외부 파일을 가져오는 경우에 한해 listings 대신 listingsutf8 패키지를 읽는 것이 쉽습니다(\lstinputlisting에서만 유효).
minted 기본(Pygments)
\usepackage{minted}를 읽으면 코드 블록을 minted 환경에 쓸 수 있습니다. listings와 크게 다른 점은 \begin{minted}{python}처럼 첫 번째 인수로 언어 이름을 준다는 것입니다. 한 줄짜리 단축 명령 \mint, 본문 삽입용 \mintinline, 외부 파일 입력용 \inputminted도 제공됩니다.
\usepackage{minted}
% ドキュメント全体の配色テーマ / a color theme for the whole document
\usemintedstyle{monokai}
\begin{minted}[linenos, bgcolor=black!90, fontsize=\small]{python}
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
\end{minted}
% 単一行 / a single line
\mint{python}|print("Hello!")|
% 本文中に埋め込む / inline in running text
\mintinline{python}{print("Hello!")}
% 外部ファイルを取り込む / include an external file
\inputminted[linenos]{python}{sample.py}옵션은 환경 이름 바로 뒤의 [ ]에 key=value 형식으로 줍니다. 자주 쓰는 것은 행 번호를 붙이는 linenos, Pygments 색 테마를 고르는 style=(monokai 등, 목록은 pygments.org/styles), 배경색 bgcolor=, 글자 크기 fontsize= 등입니다. 문서 전체에 같은 테마를 적용하려면 \usemintedstyle{monokai}, 더 넓게 기본값을 모으려면 \setminted{style=monokai, linenos}를 사용합니다. Pygments가 지원하지 않는 언어이거나 일부러 하이라이트를 끄고 싶다면 언어 이름을 text로 지정합니다.
\mint와 \mintinline의 코드는 \verb와 마찬가지로 짝이 맞는 구분 기호(예: |...| 같은 임의의 기호)나 중괄호 {...}로 둘러쌉니다. 단, \mint는 인라인용이 아니며, 코드가 한 줄뿐일 때 환경을 쓰는 수고를 줄이는 명령입니다. 본문에 자연스럽게 넣으려면 반드시 \mintinline을 사용하세요.
Shell escape(minted의 전제)
minted는 외부 Python 프로그램을 실행하므로, LaTeX가 외부 명령을 실행하도록 허용하는 shell escape를 켜고 컴파일해야 합니다. pdfLaTeX에서는 -shell-escape 옵션을 붙입니다.
pdflatex -shell-escape document.tex기본적으로 Python 3.8 이상과 Pygments도 필요합니다. 다만 minted 버전 3(2025년 이후의 완전한 재작성판)부터 상황이 좋아졌습니다. TeX 패키지 관리자(tlmgr install minted 등)로 설치하면 Pygments를 포함한 Python 쪽 전체가 TeX 트리 안의 전용 실행 파일 latexminted로 함께 제공되어, Pygments를 따로 설치할 필요가 없습니다. 또한 latexminted는 제한된 shell escape를 염두에 두고 설계되었습니다. TeX Live 2024 이후에는 신뢰된 실행 파일로 등록되어 있으므로 -shell-escape 없이도 그대로 컴파일할 수 있습니다.
그럼에도 TeX Live 2024 이전 버전이나 MiKTeX에서는 여전히 기존처럼 -shell-escape가 필요합니다(MiKTeX에서는 -enable-write18). shell escape는 임의의 외부 명령을 실행할 수 있으므로 신뢰할 수 없는 출처의 문서에는 사용하지 마세요. 반대로 Overleaf처럼 준비된 환경이나 로컬에서 자신의 코드를 다룰 때는 괜찮습니다(Overleaf는 minted를 기본 지원합니다). 이 “외부 의존성과 shell escape”가 더 이식성 좋은 listings와의 가장 큰 트레이드오프입니다.
어느 쪽을 고를까
- 설정 없이 어디서나 동작하는 안정감이 필요 → listings. Overleaf나 제한된 환경에서도
\usepackage만으로 충분합니다. - 하이라이트 정확도와 언어 지원 범위가 최우선 → minted. Pygments 기반 색칠은 차원이 다릅니다.
- 외부 도구를 설치할 수 없거나 shell escape를 쓸 수 없음 → listings가 확실합니다.
- 코드를 색 없이 그대로 출력하기만 하면 됨 →
verbatim이나fancyvrb로 충분합니다(“Verbatim” 참조). - 알고리즘을 의사코드로 쓰고 싶음 → 전용
algorithm2e/algpseudocode(“Algorithms” 참조).