PDF 파일을 편집하거나 수정하는 것은 보통 AdobeAcrobat을 이용하는 것이 일반적이다. 그러나 이 프로그램은 저렴하지 않은 상업용 프로그램이다.
AdobeAcrobat을 이용하지 않고 PDF 파일을 편집하는 방법에 관한 팁을 모아본다.
1.1. n-up ¶
두 쪽을 마주보게 각 페이지를 축소해서 배열하는 경우, 즉 1x2 up의 경우를 예로 들어둔다.
원래의 PDF 파일이
testin.pdf
라고 할 때, 다음과 같은 testout.tex
을 작성한다.
\documentclass[a4paper]{article}
\usepackage{pdfpages}
\begin{document}
\includepdf[pages=-,nup=1x2,landscape,frame=false]{testin.pdf}
\end{document}
\usepackage{pdfpages}
\begin{document}
\includepdf[pages=-,nup=1x2,landscape,frame=false]{testin.pdf}
\end{document}
이 파일을 PDFLaTeX으로 실행한다.
#> pdflatex testout
이 방법은
pdfpages.sty
가 제공하는 \includepdf
명령을 이용하는데, 사용례를 몇 가지 보이면 다음과 같다.
\includepdf[nup=1x2,landscape,pages=4-7]{foo.pdf}
\includepdf[nup=1x2,landscape,pages=4-7,turn=false]{foo.pdf}
\includepdf[nup=2x2,pages=1-4,column]{foo.pdf}
\includepdf[nup=1x2,landscape,pages=4-7,turn=false]{foo.pdf}
\includepdf[nup=2x2,pages=1-4,column]{foo.pdf}
짝수쪽부터 시작하는 것을 방지하기 위하여 처음에 빈 쪽을 넣으려면
\includepdf[nup=2x2,pages={{},5-7}]{foo.pdf}
nup된 각 페이지에 프레임을 넣으려면
\includepdf[nup=2x2,pages=1-4,frame]{foo.pdf}
각 페이지의 일부를 trim함으로써 원래 페이지의 header나 footer를 제거하고 싶다면
\includepdf[nup=2x2,pages=1-4,
trim= 0 40mm 0 40mm,
clip]{foo.pdf}
trim= 0 40mm 0 40mm,
clip]{foo.pdf}
nup된 페이지에 페이지 번호를 붙이고 싶다면
\includepdf[nup=2x2,pages=1-4,pagecommand={\thispagestyle{plain}}]{foo.pdf}
1.3. PDF 파일 한쪽씩 합치기 ¶
이 방법은 두 문서의 페이지수가 같고 마지막 페이지를 알고 있다고 가정했을 때 입니다.
각각의 문서를 컴파일해서 a.pdf와 b.pdf를 얻었고, 이 두 PDF의 페이지가 예를 들어 10페이지씩이라고 가정하겠습니다.
다음과 같은 total.tex을 작성합니다.
\documentclass{article}
\usepackage{pdfpages}
\makeatletter
\def\for#1#2#3{\@ifnextchar[{\@for@{#1}{#2}{#3}}{\@for@{#1}{#2}{#3}[1]}}
\long\def\@for@#1#2#3[#4]#5{\setcounter{#1}{#3}\addtocounter{#1}{1}%
\edef\for@loopend{\arabic{#1}}%
\setcounter{#1}{#2}%
\loop
\ifnum \expandafter\the\csname c@#1\endcsname < \for@loopend\relax
#5\addtocounter{#1}{#4}\repeat}
\newcounter{repeatcnt}
\makeatother
\begin{document}
\for{repeatcnt}{1}{10}{%
\includepdfmerge{a.pdf,\therepeatcnt,b.pdf,\therepeatcnt}
}
\end{document}
\usepackage{pdfpages}
\makeatletter
\def\for#1#2#3{\@ifnextchar[{\@for@{#1}{#2}{#3}}{\@for@{#1}{#2}{#3}[1]}}
\long\def\@for@#1#2#3[#4]#5{\setcounter{#1}{#3}\addtocounter{#1}{1}%
\edef\for@loopend{\arabic{#1}}%
\setcounter{#1}{#2}%
\loop
\ifnum \expandafter\the\csname c@#1\endcsname < \for@loopend\relax
#5\addtocounter{#1}{#4}\repeat}
\newcounter{repeatcnt}
\makeatother
\begin{document}
\for{repeatcnt}{1}{10}{%
\includepdfmerge{a.pdf,\therepeatcnt,b.pdf,\therepeatcnt}
}
\end{document}
이제 pdflatex으로 total.tex을 컴파일하면 total.pdf를 얻을 수 있습니다.
페이지 수에 신경쓰시고,
\includepdfmerge
명령 안에 모든 인자가 콤마로 분리되어 있다는 점에 주의하시면 될 것입니다. 이 예제에서는 for Loop를 구현하는 예도 보였습니다.
오래 전의 위의 샘플을 Expl3로 다시 써보았습니다.
\documentclass[a4paper]{article}
\usepackage{expl3,xparse}
\usepackage{pdfpages}
\usepackage{ksforloop}
\ExplSyntaxOn
\int_new:N \lastlastpagenum
\NewDocumentCommand \numberofpdfpages { m }
{
\luatex_if_engine:TF
{
\pdftex_pdfximage:D { #1 }
\int_gset:Nn \g_tmpa_int { \pdftex_pdflastximagepages:D }
}
{
\pdftex_if_engine:TF
{
\pdftex_pdfximage:D { #1 }
\int_gset:Nn \g_tmpa_int { \pdftex_pdflastximagepages:D }
}
{
\xetex_if_engine:T
{
\int_gset:Nn \g_tmpa_int { \xetex_pdfpagecount:D "#1" }
}
}
}
}
\NewDocumentCommand \pdffilestoprepare { m m }
{
\numberofpdfpages { #1 } \int_set_eq:NN \l_tmpa_int \g_tmpa_int
\numberofpdfpages { #2 } \int_set_eq:NN \l_tmpb_int \g_tmpa_int
\int_compare:nTF { \l_tmpa_int > \l_tmpb_int }
{
\int_set_eq:NN \lastlastpagenum \l_tmpb_int
}
{
\int_set_eq:NN \lastlastpagenum \l_tmpa_int
}
\tl_set:Nn \leftpdffile { #1 }
\tl_set:Nn \rightpdffile { #2 }
}
\NewDocumentCommand \domerge { m m o }
{
\pdffilestoprepare { #1 } { #2 }
\IfValueT { #3 } { \int_set:Nn \lastlastpagenum { #3 } }
\ksforloop{}{\lastlastpagenum}
{
\includepdfmerge{\leftpdffile,\ksfori,\rightpdffile,\ksfori}
}
}
\ExplSyntaxOff
\begin{document}
\domerge{a.pdf}{b.pdf}
\domerge{a.pdf}{b.pdf}[10]
\end{document}
\usepackage{expl3,xparse}
\usepackage{pdfpages}
\usepackage{ksforloop}
\ExplSyntaxOn
\int_new:N \lastlastpagenum
\NewDocumentCommand \numberofpdfpages { m }
{
\luatex_if_engine:TF
{
\pdftex_pdfximage:D { #1 }
\int_gset:Nn \g_tmpa_int { \pdftex_pdflastximagepages:D }
}
{
\pdftex_if_engine:TF
{
\pdftex_pdfximage:D { #1 }
\int_gset:Nn \g_tmpa_int { \pdftex_pdflastximagepages:D }
}
{
\xetex_if_engine:T
{
\int_gset:Nn \g_tmpa_int { \xetex_pdfpagecount:D "#1" }
}
}
}
}
\NewDocumentCommand \pdffilestoprepare { m m }
{
\numberofpdfpages { #1 } \int_set_eq:NN \l_tmpa_int \g_tmpa_int
\numberofpdfpages { #2 } \int_set_eq:NN \l_tmpb_int \g_tmpa_int
\int_compare:nTF { \l_tmpa_int > \l_tmpb_int }
{
\int_set_eq:NN \lastlastpagenum \l_tmpb_int
}
{
\int_set_eq:NN \lastlastpagenum \l_tmpa_int
}
\tl_set:Nn \leftpdffile { #1 }
\tl_set:Nn \rightpdffile { #2 }
}
\NewDocumentCommand \domerge { m m o }
{
\pdffilestoprepare { #1 } { #2 }
\IfValueT { #3 } { \int_set:Nn \lastlastpagenum { #3 } }
\ksforloop{}{\lastlastpagenum}
{
\includepdfmerge{\leftpdffile,\ksfori,\rightpdffile,\ksfori}
}
}
\ExplSyntaxOff
\begin{document}
\domerge{a.pdf}{b.pdf}
\domerge{a.pdf}{b.pdf}[10]
\end{document}
이 예제에는 외부 pdf 파일의 마지막 페이지 번호를 얻어내는 방법이 들어 있습니다. (즉 각 pdf 파일의 최종 페이지 수를 미리 알고 있지 않아도 됩니다.)
두 파일의 최종 페이지를 비교하여 적은 쪽수를 가진 파일을 기준으로 합칩니다.
세 번째의 옵션 인자를 주면 1쪽부터 해당쪽까지 합칩니다.
2.1. pdfcrop.pl ¶
Heiko Oberdiek 씨가 작성한 Perl 스크립트입니다.
다음은
pdfcrop.pl --help
화면입니다.
PDFCROP 1.2, 2002/11/04 - Copyright (c) 2002 by Heiko Oberdiek. Syntax: pdfcrop [options] <input[.pdf]> [output file] Function: Margins are calculated and removed for each page in the file. Options: (defaults:) --help print usage --(no)verbose verbose printing (false) --(no)debug debug informations (false) --gscmd _name_ call of ghostscript (gswin32c) --pdftexcmd _name_ call of pdfTeX (pdftex) --margins "left top right bottom" (0 0 0 0) add extra margins, unit is bp. If only one number is given, then it is used for all margins, in the case of two numbers they are also used for right and bottom. --(no)clip clipping support, if margins are set (false) --(no)hires using '%%HiResBoundingBox' (false) instead of '%%BoundingBox' Examples: pdfcrop.pl --margins 10 input.pdf output.pdf pdfcrop.pl --margins '5 10 5 20' --clip input.pdf output.pdf
windows에서 TeX Live 2010을 사용할 경우 pdfcrop.pl 대신 pdfcrop 이라고 부르면 됩니다.
2.2. PDFTeX 파일을 작성하는 방법 ¶
from KTUGOperate:4284 (by 이공훈)
위의 유틸리티로 웬만한 PDF는 다 변환이 되지만, AdobeIllustrator에서 한글 Font를 포함하여 만들어진 PDF의 일부가 Ghostscript에서 읽어지지 않을 때가 있습니다. 이런 경우, 다음과 같은
이 파일을 예를 들면
.tex
파일을 작성하여 PDFTeX을 실행하면 PDF 파일을 원하는 크기만큼 잘라낼 수 있습니다.
원본 파일이 ainput.pdf
인 경우,
\def\pdffile{ainput.pdf} % <-- file 이름 수정
\def\page #1 [#2 #3 #4 #5]{%
\count0=#1\relax
\setbox0=\hbox{%
\pdfximage page #1{\pdffile}%
\pdfrefximage\pdflastximage
}%
\pdfhorigin=-#2bp\relax
\pdfvorigin=#3bp\relax
\pdfpagewidth=#4bp\relax
\advance\pdfpagewidth by -#2bp\relax
\pdfpageheight=#5bp\relax
\advance\pdfpageheight by -#3bp\relax
\ht0=\pdfpageheight
\shipout\box0\relax
}
\page 1 [40 290 552 552] % <-- 괄호 안의 BoundingBox 수정
\end
\def\page #1 [#2 #3 #4 #5]{%
\count0=#1\relax
\setbox0=\hbox{%
\pdfximage page #1{\pdffile}%
\pdfrefximage\pdflastximage
}%
\pdfhorigin=-#2bp\relax
\pdfvorigin=#3bp\relax
\pdfpagewidth=#4bp\relax
\advance\pdfpagewidth by -#2bp\relax
\pdfpageheight=#5bp\relax
\advance\pdfpageheight by -#3bp\relax
\ht0=\pdfpageheight
\shipout\box0\relax
}
\page 1 [40 290 552 552] % <-- 괄호 안의 BoundingBox 수정
\end
aoutput.tex
으로 저장하고 다음과 같이 실행합니다.
#> pdftex aoutput
3.1.1. 일부 페이지만 추출 ¶
한 페이지만 추출하려면
texexec --pdfselect
방법을 쓴다. orig.pdf
의 1페이지만을 test1.pdf
로 쓰려면 다음과 같이 한다.
#> texexec --pdfselect --selection=1 --batch --result=test1.pdf orig.pdf
따라서, 1페이지부터 10페이지까지 별도의 PDF 파일로 만들려면, Perl을 이용하여,
for(1..10) { system("texexec --pdfselect --selection=$_ --batch --result=test$_.pdf orig.pdf"); }
3.1.2. 한 페이지만 추출하는 Shell 스크립트 ¶
위의
texexec
로 한 페이지만 추출하는 것을 Shell Script로 만든 것.(Claus Gerhardt 씨)
#!/bin/sh ## # pdfsel.sh # pdfselect # # $1= selected pages either in form of a list x,y,z or in form of range x:y or as odd #resp. even #filenename without suffix pdf, the resulting file is named filename-ext.pdf # Claus Gerhardt ## # EXTENSIONS : "*" # OSTYPES : "****" for file; do location=$(dirname "$file") cd "${location}" && \ texexec --pdfselect --batch --silent --selection="$1" --result="${file}-ext.pdf" "${file}.pdf" \ && rm -f "${file}-ext.tui" && rm -f "${file}-ext.tmp" && rm -f "texexec.tex" \ && rm -f "texexec.tmp" && rm -f "texexec.tui" && rm -f "mprun.mp" rm -f "mpgraph.mp" \ && rm -f "${file}-ext.log" done
3.2.1. 일부 페이지 추출 ¶
KTUGOperate:7342 (by 이공훈)
1페이지부터 10페이지까지 추출하는 방법.
#!/usr/bin/perl for(1..10) { open(OUT,">test$_.tex") or die "Cannot write 'test$_.tex'"; print OUT << "EOF"; \\documentclass[a4paper]{article} \\usepackage{pdfpages} \\begin{document} \\includepdf[pages=$_]{orig.pdf} \\end{document} EOF close OUT; system("pdflatex --interaction batchmode test$_"); unlink "test$_.tex","test$_.log","test$_.aux"; }
3.2.2. 한 페이지만 추출하는 Shell Script ¶
pdfsel.sh
#!/bin/sh PAGENUM=$1 OUTFILE=$2-ext-$1.tex echo '\documentclass{article}' > $OUTFILE echo '\usepackage{pdfpages}' >> $OUTFILE echo '\begin{document}' >> $OUTFILE echo '\includepdf[pages='$PAGENUM']{'$2'.pdf}' >> $OUTFILE echo '\end{document}' >> $OUTFILE pdflatex --interaction=batchmode $OUTFILE
#> sh pdfsel.sh 13 test
(입력파일의 확장명
.pdf
를 쓰지 않음. 첫번째 인자는 추출하려는 페이지, 두번째 인자는 입력파일. 결과는 test-ext-13.pdf
와 같이 만들어진다.)
동일한 DOS Batchfile.
@echo off rem pdfsel.bat echo \documentclass{article} > %2-ext-%1.tex echo \usepackage[pdftex]{graphicx} >> %2-ext-%1.tex echo \usepackage{pdfpages} >> %2-ext-%1.tex echo \begin{document} >> %2-ext-%1.tex echo \includepdf[pages=%1]{%2.pdf} >> %2-ext-%1.tex echo \end{document} >> %2-ext-%1.tex pdflatex --interaction=batchmode %2-ext-%1 del %2-ext-%1.aux rem del %2-ext-%1.log del %2-ext-%1.tex
위의 pdfsel.bat를 이용하여 Windows 명령행에서, 1페이지부터 10페이지까지 한 페이지씩 각각 하나의 PDF로 원본
test.pdf
를 추출하는 방법.
#> for /L %i IN (1,1,10) DO call pdfsel.bat %i test
3.3. pdftk를 사용하는 방법 ¶
PDFtk는 https://www.pdflabs.com/ 에서 제공하며, 여기 설명하는 페이지 추출말고도
PDF Merge, 암호화 등의 다양한 기능들을 제공한다.
3.3.1. 일부 페이지만 추출 ¶
다음 예를 인풋 파일의 1쪽에서 12쪽까지 그리고 14쪽부터 끝까지를 추출하는 것이다.
pdftk A=in.pdf cat A1-12 A14-end output out.pdf다음과 같은 파일 추출/병합도 가능하다.
pdftk A=in1.pdf B=in2.pdf cat B1 A1-7even A1-7odd output out1.pdf
3.3.3. 여러장의 PDF를 하나로 묶으려면 ¶
다음과 같은 명령어를 사용하면 된다.
in1.pdf, in2.pdf 를 out1.pdf로 만들려면
pdftk in1.pdf in2.pdf cat output out1.pdf or pdftk A=in1.pdf B=in2.pdf cat A B output out1.pdf모든 *.pdf를 out1.pdf로 묶으려면
pdftk *.pdf cat output out1.pdf
- 출처 : pdftk --help message
4. Booklet 만들기 ¶
PDF Booklet이란 한 쪽에 두 페이지씩 들어가게 인쇄하여 양면인쇄한 후 가운데를 철하면 소책자가 되도록 하는 것이다. PDFPages 패키지,
\includepdf
명령의 signature
옵션을 이용한다. 주의할 점은, signature
값이 4의 배수가 되도록 하는 것이다.
11쪽 짜리 PDF가 하나 있고, 이것으로 소책자를 만들려는 경우를 생각해보자. 원 파일 이름이 doc.pdf
라 하고, 다음과 같은 aout.tex
을 작성한다.
%%-----------
\documentclass{article}
\usepackage[pdftex]{graphicx}
\usepackage{pdfpages}
\begin{document}
\pagestyle{empty}
\includepdf[pages=-,signature=12,landscape]{doc.pdf}
\end{document}
%%------------
\documentclass{article}
\usepackage[pdftex]{graphicx}
\usepackage{pdfpages}
\begin{document}
\pagestyle{empty}
\includepdf[pages=-,signature=12,landscape]{doc.pdf}
\end{document}
%%------------
이 원본 파일에 대하여 PDFLaTeX을 실행하면
aout.pdf
가 만들어진다. 이 PDF를 양면인쇄하여 가운데를 접어서 철해보자.