PDF 배치(pdfpages)

\includepdf{paper.pdf} 라고 썼는데 한 페이지만 들어옵니다. LaTeX의 pdfpages를 처음 쓰는 사람이 가장 먼저 걸려 넘어지는 턱이고, 이유는 이 옵션의 기본값이 pages=1, 곧 “첫 페이지만”이기 때문입니다. 실측에서도 5페이지짜리 PDF를 옵션 없이 읽어 들이니 출력은 정확히 한 페이지였습니다. 전부 넣으려면 pages=- 라고 씁니다(같은 PDF가 5페이지가 되었습니다). 이 한 글자를 익히면 pdfpages의 나머지가 열립니다. 패키지 저자는 Andreas Matthias이고 TeX Live 2024 동봉판은 v0.5y, 2024/01/21입니다. 표지를 앞에 붙이고, 장별 PDF를 이어 학위 논문을 만들고, 슬라이드를 2×2로 배치해 배포 자료를 만들고, 모든 페이지에 DRAFT를 찍고, 책갈피와 목차에 항목을 더하는 일 — 이 페이지에서는 그 하나하나를 실제로 컴파일해 확인하며 살펴봅니다.

includepdf 사용법 — includegraphics와 무엇이 다른가

프리앰블에서 \usepackage{pdfpages}를 읽어 들이고 본문에서 \includepdf[…]{파일}을 부릅니다. 차이는 한 장 단위로 종이에 올린다 는 점입니다. \includegraphics는 PDF를 “그림”으로 본문 흐름에 두므로 판면보다 크면 넘치고 문서의 여백도 그대로 적용됩니다. \includepdf는 새 종이를 일으켜 원본 PDF의 페이지를 자동으로 확대·축소해 담습니다. 실측하면, A5(419.5 x 595.3pt)로 만든 PDF를 레터 크기 문서에 읽어 들인 결과는 출력 페이지가 612 x 792pt 레터 였습니다. 종이가 아니라 원본 페이지가 축척된 것입니다. 파일 이름에는 공백이 들어가면 안 됩니다.

내부에서 \includepdfgraphicx\includegraphics를 부릅니다. 그래서 pdfpages가 스스로 해석하지 않는 옵션 — trim, clip, scale, angle 등 — 은 그대로 그쪽으로 넘어갑니다. 가져오는 PDF의 머리글과 바닥글을 잘라 내고 싶다면 \includepdf[pages=-, trim=0 2cm 0 2cm, clip]{paper.pdf}처럼 씁니다. 자동 확대·축소를 멈추려면 noautoscale, 위치를 옮기려면 치수 둘을 받는 offset을 사용합니다.

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

% body text ...
\includepdf[pages=-]{cover.pdf}
% ... body text continues

\end{document}

pages 쓰는 법 — 전체 페이지, 역순, 백지 끼워 넣기

pages는 삽입할 페이지와 그 순서 를 쉼표로 나열합니다. 범위는 m-n으로 쓰고, m을 빼면 첫 페이지, n을 빼면 마지막 페이지를 뜻합니다. 그래서 pages=- 는 “처음부터 끝까지”입니다. 마지막 페이지는 범위 안에서만 쓸 수 있는 키워드 last로도 가리킬 수 있습니다. 재미있어지는 것은 순서입니다. pages=last-1이라고 쓰면 역순 으로 들어가고, 실측에서도 8페이지짜리 PDF가 PAGE 8부터 PAGE 1까지 순서로 출력되었습니다.

또 하나 알아 둘 값어치가 있는 것이 {} 입니다. 목록 안에 {}를 쓰면 그 자리에 백지 한 장 이 들어갑니다. pages={1,{},2-21}이라고 쓰면 “표지, 백지, 본문 1–20페이지” 순이 됩니다. 실측에서도 pages={1,{},2}는 3페이지를 출력했고 추출한 텍스트는 PAGE 1PAGE 2 둘뿐이었습니다. 가운데가 정말로 백지였던 것입니다. 양면 인쇄 학위 논문에서 각 장을 반드시 오른쪽 페이지에서 시작하게 할 때 씁니다.

latex
% cover, then one blank leaf, then body pages 1-20
\includepdf[pages={1,{},2-21}]{thesis-cover.pdf}

% every page, in reverse order
\includepdf[pages=last-1]{scan.pdf}

% a hand-picked selection, in this order
\includepdf[pages={3,1,4,1,5}]{notes.pdf}
쓰는 법들어가는 페이지
(omitted)첫 페이지만. 기본값은 pages=1 입니다
pages=-처음부터 끝까지 모든 페이지
pages={2-8}2페이지부터 8페이지까지
pages={1,3,5}1, 3, 5페이지만 이 순서로
pages={3,{},15}3페이지, 백지 한 장, 15페이지
pages=last-1모든 페이지를 역순으로. last는 범위 안에서만 유효합니다
pages={1-3,5,{},7}범위, 단일 페이지, 백지를 자유롭게 섞을 수 있습니다

nup으로 2x2 배포 자료 만들기 — landscape는 /Rotate를 써 넣는다

nup=가로x세로 라고 쓰면 여러 논리 페이지를 한 장의 종이에 늘어놓습니다. 실측에서 8페이지짜리 슬라이드 PDF를 nup=2x2로 읽어 들이니 출력은 2장, nup=2x1, landscape이면 4장 이었습니다. 기본 채움 순서는 행 방향(왼쪽에서 오른쪽, 다음 행으로)이고, 열 방향으로 하려면 column, 마지막 장에서도 열 순서를 흐트러뜨리고 싶지 않으면 columnstrict를 더합니다. 페이지 사이에 틈을 두는 것은 delta(delta=5mm 5mm처럼 치수 둘), 각 페이지를 테두리로 두르는 것은 frame입니다.

landscape가 돌리는 것은 종이 쪽 이고, 그 위에 놓인 페이지 자체는 서 있는 채로 있습니다. 페이지 자체를 돌리려면 angle=90을 씁니다. 흥미로운 것은 이 landscapePDF에 /Rotate 90을 써 넣는다 는 점입니다. nup=2x1, landscape으로 만든 PDF를 pdfinfo -f 1 -l 1로 조사하면 Page 1 rot: 90이 나오고 용지 크기는 612 x 792 그대로입니다. 뷰어가 알아서 돌려서 보여 줍니다. 이 동작을 막으려면 turn=false를 지정합니다(기본은 turn=true). 같은 장치를 pdflscape 패키지도 쓰며, 지면보다 넓은 표를 다루는 페이지에서 자세히 비교합니다.

latex
% four slides per sheet, boxed, with a gap between them
\includepdf[pages=-, nup=2x2, frame, delta=5mm 5mm]{slides.pdf}

% two pages side by side on a landscape sheet
\includepdf[pages=-, nup=2x1, landscape]{report.pdf}

fitpaper — 종이 쪽을 원본 PDF에 맞추기

기본값에서는 원본 PDF가 종이에 맞춰 축척되지만, fitpaper=true 를 주면 반대가 되어 종이 크기가 원본 PDF에 맞춰 바뀝니다. 실측에서는 A5로 만든 8페이지 PDF를 레터 크기 문서에 fitpaper=true로 읽어 들이니 출력 페이지 크기가 419.527 x 595.275pt, 곧 원래 A5 그대로였습니다. 축척으로 화질이 떨어지면 곤란한 스캔 원고나, 이미 판면이 정해진 제출용 서류를 끼워 넣을 때 씁니다.

가져오는 PDF의 페이지 크기가 고르지 않을 때를 위한 도구도 있습니다. 기본적으로 처음 삽입한 페이지가 본 이 되고, 이후 페이지는 그 윤곽에 들어가도록 축척됩니다. 다른 페이지를 본으로 삼으려면 pagetemplate=⟨페이지 번호⟩, 치수를 직접 주려면 templatesize={⟨폭⟩}{⟨높이⟩} 를 씁니다. 반올림 오차를 피하려면 원하는 값보다 조금 크게 잡습니다. 세로 본에 가로 페이지가 오면 기본값에서는 축소되지만, rotateoversize=true를 주면 돌려서 담습니다. 같은 내용을 두 벌 찍고 나중에 잘라 두 부로 만들고 싶다면 doublepages가 각 페이지를 두 번 삽입합니다.

옵션무엇을 하는가(기본값)
nup한 장에 여러 페이지를 늘어놓음. nup=2x2는 가로 2 × 세로 2. 기본 1x1
frame각 논리 페이지를 \fboxrule 두께의 테두리로 두름. 기본 false
delta배치된 페이지 사이의 틈. 공백으로 구분한 치수 둘. 기본 0 0
landscape종이를 가로로 하고 PDF에 /Rotate 90을 써 넣음. 기본 false
turn가로 페이지를 뷰어가 돌려서 보여 줄지 여부. 기본 true
scale\includegraphics로 넘겨지는 배율. noautoscale과 조합해 수동으로 제어
fitpaper종이 크기를 삽입한 문서에 맞춤. 기본 false
offset삽입한 페이지의 원점을 옮김. 치수 둘. 기본 0 0
pagecommand삽입되는 각 페이지에서 실행할 LaTeX 코드. 기본 \thispagestyle{empty}
picturecommand페이지 왼쪽 아래를 원점으로 하는 picture에서 실행할 명령. 기본은 비어 있음
link삽입 페이지를 ⟨파일명⟩.⟨페이지 번호⟩ 라는 링크 대상으로 만듦. 기본 false. linkname으로 개명

쪽번호 되살리기와 DRAFT 찍기 — pagecommand와 picturecommand

가져온 페이지에 자기 문서의 쪽번호를 인쇄하고 싶을 때pagecommand를 씁니다. 이 옵션은 삽입되는 각 페이지에서 실행될 LaTeX 코드를 받습니다. pdfpages.sty는 그 기본값을 \thispagestyle{empty}로 정의해 두었고, 그래서 가져온 페이지에는 쪽번호도 머리글도 나오지 않습니다. pagecommand={\thispagestyle{plain}}으로 바꾸면 여러분 문서의 쪽번호가 그 위에 찍힙니다.

여기에 함정이 있습니다. pagecommand를 자기 용도로 덮어쓰면 기본값이던 \thispagestyle{empty}도 함께 사라집니다. 실측에서, 워터마크를 그리는 코드만 pagecommand에 넘긴 문서는 가져온 페이지에 1, 2, 3… 이라는 쪽번호를 의도 없이 인쇄했습니다. 번호를 내고 싶지 않다면 자기 코드 앞에 \thispagestyle{empty}를 붙여 두어야 합니다.

워터마크나 도장 자체를 위해서는 전용 훅이 마련되어 있습니다. picturecommand각 페이지의 왼쪽 아래를 원점으로 하는 picture 환경 안에서 실행될 명령을 받습니다(landscape 등으로 페이지가 돌아가도 원점은 움직이지 않습니다). 실측에서 picturecommand={\put(30,30){\Large CONFIDENTIAL}} 을 준 8페이지 삽입은 pdftotext 출력이 PAGE 1 CONFIDENTIAL PAGE 2 CONFIDENTIAL … 로, 모든 페이지에 찍혔습니다. 첫 페이지에만 찍고 싶다면 picturecommand* 를 씁니다.

latex
% your own page numbers on the imported pages
\includepdf[pages=-, pagecommand={\thispagestyle{plain}}]{paper.pdf}

% stamp every imported page; the picture origin is its lower-left corner
\includepdf[pages=-,
            picturecommand={\put(30,30){\Large CONFIDENTIAL}}]{paper.pdf}

% ...and picturecommand* would stamp only the first inserted page

장별 PDF로 학위 논문 조립하기 — includepdfmerge와 addtotoc

따로 조판한 PDF들을 잇는 명령이 \includepdfmerge 입니다. 인수는 “파일명, 페이지 지정, 파일명, 페이지 지정, …”의 나열이고, 페이지 지정은 pages와 같은 문법입니다. 생략하면 그 파일의 첫 페이지만 들어갑니다. 실측에서 \includepdfmerge{a.pdf,1-2,b.pdf,3} 은 3페이지를 출력했고 내용은 PAGE 1, PAGE 2, SOURCE PAGE 3 순이었습니다. 같은 옵션을 매번 쓰고 싶지 않다면 \includepdfset{…} 으로 기본값을 한꺼번에 설정할 수 있고, 개별 \includepdf에 쓴 옵션이 그것을 덮어씁니다.

끼워 넣은 PDF는 그대로는 목차에도 책갈피에도 나오지 않습니다. 그것을 해결하는 것이 addtotoc 이며, 쉼표로 구분된 다섯 인수를 받습니다. addtotoc={⟨페이지 번호⟩,⟨절 종류⟩,⟨레벨⟩,⟨제목⟩,⟨레이블⟩} 입니다. 페이지 번호는 삽입한 페이지 중 몇 번째인지, 절 종류는 section 같은 이름, 레벨은 깊이를 나타내는 수, 제목은 목차에 낼 문자열, 레이블은 \ref\pageref로 가리킬 이름입니다. 순서를 바꾸면 안 됩니다.

hyperref와 함께 쓰면 이 한 옵션이 세 가지 일을 한 번에 해치웁니다. 실측해 봅시다. hyperref를 읽어 들인 문서에서 addtotoc={1,section,1,Imported paper,sec:paper} 를 지정하니 .toc\contentsline {section}{\numberline {2}\ignorespaces Imported paper}{2} 가 쓰였고, .out에는 \BOOKMARK [1][-]{section.2}{Imported paper}{} 가 나타났으며, 본문에서의 \ref{sec:paper}\pageref{sec:paper} 가 올바르게 해결되었습니다. 목차 항목, PDF 책갈피, 상호 참조 셋이 이 한 줄에서 나옵니다. 그림·표 목록에 더하고 싶으면 addtolist를 씁니다.

document.tex
\documentclass{article}
\usepackage{hyperref}
\usepackage{pdfpages}   % load pdfpages after hyperref
\begin{document}
\tableofcontents
\section{Front matter}

% one contents entry, one PDF bookmark, one \ref target
\includepdf[pages=-,
            pagecommand={\thispagestyle{plain}},
            addtotoc={1,section,1,Imported paper,sec:paper}]{paper.pdf}

\section{After}
See \ref{sec:paper} on page \pageref{sec:paper}.

% assemble a thesis from separately typeset parts
\includepdfmerge{frontmatter.pdf, -, chap1.pdf, -, chap2.pdf, -}
\end{document}

signature=8이 만들어 내는 순서 — 8, 1, 2, 7, 6, 3, 4, 5

중철 소책자를 만들려면 페이지를 접었을 때 제대로 늘어서는 순서 로 재배열해야 합니다. pdfpagessignature 옵션에 4의 배수를 주면 그 장수로 접장을 구성하고 방향에 따라 자동으로 nup=1x2 또는 nup=2x1로 면 배치합니다. 실측해 봅시다. 8페이지 PDF에 signature=8, landscape를 지정하니 출력은 4면이 되었고, 추출한 페이지 순서는 PAGE 8, PAGE 1, PAGE 2, PAGE 7, PAGE 6, PAGE 3, PAGE 4, PAGE 5 였습니다. 이것을 양면으로 두 장에 찍어 겹쳐서 반으로 접으면 펼치는 순서대로 1부터 8이 나타납니다.

주의할 점은 pages=-, nup=1x2, landscape 로는 재배열이 전혀 일어나지 않는다 는 것입니다. 두 페이지를 나란히 놓을 뿐이어서 접어도 순서가 맞지 않습니다. 접장을 만들려면 반드시 signature를 써야 합니다. 더 복잡한 면 배치(여러 접장, 밀림 보정, 재단 표시 등)가 필요하다면 전용 booklet 패키지도 TeX Live에 들어 있습니다.

latex
% a saddle-stitched booklet in signatures of eight pages
\includepdf[pages=-, signature=8, landscape]{booklet-doc.pdf}

\includepdf가 옮겨 오는 것은 각 페이지의 겉모습뿐 입니다. 원본 PDF 안의 링크는 작동하지 않게 됩니다. pdfpages 설명서도 잃는 것이 링크만이 아니라 모든 종류의 PDF 주석(annotation) 이라고 명시하고 있습니다. 원래 링크를 남기고 싶다면 주석을 뽑아내 다시 붙이는 pax(Heiko Oberdiek)를 함께 씁니다.

반대 방향으로, pdfpages스스로 링크의 도착점을 만들 수도 있습니다. link=true를 주면 삽입된 각 페이지가 ⟨파일명⟩.⟨페이지 번호⟩ 라는 이름의 링크 대상이 되어, 본문에서 \hyperlink{paper.pdf.3}{…} 처럼 건너뛸 수 있습니다. 이름을 바꾸려면 linkname=mylink, 외부 파일을 가리키려면 linkfilename, linktodoc, linkfit, newwindow가 있습니다. 스레드를 만드는 thread, threadname도 같은 계열입니다.

엔진과 드라이버 — pLaTeX과 dvipdfmx에서 백지가 될 때

pdfpages 설명서가 드는 엔진은 pdfTeX, VTeX, XeTeX, LuaTeX, pTeX 이므로 pdfLaTeX에서도 LuaLaTeX에서도 XeLaTeX에서도, 그리고 (up)pLaTeX에서도 동작합니다. 다만 PDF를 직접 써 내는 엔진을 전제로 하기 때문에 DVI를 거치는 경로에서는 PDF를 가져올 수 없고 대신 백지가 들어갑니다. 일본어권에서 흔한 pLaTeX + dvipdfmx 구성에서는 PDF 가져오기가 dvipdfmx의 일 이 되므로 그래픽 드라이버를 올바로 지정해야 합니다. 설명서가 권하는 방식은 클래스 옵션에 dvipdfmx를 넘기는 것입니다.

document.tex
% the driver the pdfpages manual recommends for the platex route
\documentclass[dvipdfmx]{article}
\usepackage{pdfpages}

% ...or state it explicitly on graphicx
% \usepackage[dvipdfmx]{graphicx}

이 경로에는 알아 둘 만한 버릇이 하나 더 있습니다. pdfpages는 가져오는 PDF의 총 페이지 수를 알아내기 위해 외부 프로그램 extractbb를 부릅니다 만, 대응하는 .xbb 파일이 이미 있으면 extractbb를 부르지 않고 그 내용을 씁니다. 원본 PDF를 갈아 끼웠는데 낡은 .xbb가 남아 있으면 페이지 수가 맞지 않아 삽입이 어긋나므로, PDF를 갱신하면 .xbb도 다시 만드십시오. 마지막으로 배경색을 쓰는 문서의 함정 하나 — \pagecolor\usepackage{pdfpages} 보다 앞에 두어야 합니다.