27

I would like to have my document compiled with two pages in one using LaTeX, like what you see when you choose to print two pages in one. As my pages are "portrait", I need the page to be shown in landscape when the two pages are compiled in one, and If I could also include margins around each page, that would be wonderful.

Does anyone know of any package(s) I can use to get the effect I am after?

9
  • 4
    I must echo Caramdir's question. It's usually the print driver which handles that, assuming that you are doing this for printing, and even if you don't want to print, you can always "print to file". Aug 2, 2010 at 1:38
  • 5
    @Jose, Caramdir: to save paper, I prefer to do the 'n-up'ing before sending it to the printer to be sure that I get what I want. Also, by being a bit clever with the scaling, I can print a normal journal article 2-up with only 90% reduction in size due to all the excessive white-space around the margins. Save trees without compromising on readability! Aug 2, 2010 at 8:10
  • 9
    @Caramdir, @Jose: Because it looks pretty on the computer? Because I want to learn what I can do with latex? Because this might be useful to someone?
    – Vivi
    Aug 2, 2010 at 11:20
  • 4
    Also, sending PDFs that are already 2 to a page forces other people to save paper when they print your stuff, which is nice.
    – Seamus
    Aug 2, 2010 at 11:24
  • 3
    I think it's fair to say that we are living in a transitional period where typography is still very much linked to paper and printing and, in my opinion, the end of the transition cannot arrive too quickly. This is why I make a clear distinction, as articulated by Caramdir, between the typsetting system (in this context, *TeX) and the different ways of rendering the output of that system. This does not contradict what anyone else is saying, but it helps perhaps explain my original commment. Aug 2, 2010 at 14:55

9 Answers 9

15

You could use pdfpages or pdfjam and its pdfnup tool.

4
  • 2
    "A potential drawback of pdfjam and other scripts based upon it is that any hyperlinks in the source PDF are lost.". Pdfpages, on the other hand, looks promising :)
    – Vivi
    Aug 1, 2010 at 21:02
  • 1
    @Vivi: I don't know about pdfjam, but I use pdfpages to put my beamer slides so that they are 4 to a page. You do have to be a little careful with internal links, though. Aug 1, 2010 at 21:06
  • 2
    @Vivi pdfjam is just a number of convenient scripts that make use of pdfpages--both destroy hyperlinks.
    – frabjous
    Oct 26, 2010 at 18:14
  • 1
    @frabjous, @Vivi: Till Tantau writes in the pgfpages documentation that all n-up pdf tools will break hyperlinks because of the PDF specification that hyperlinks are absolute not relative. Mar 9, 2011 at 17:38
16

It occurs to me that post-processing isn't necessary for getting two pages in one. What about just making a two column document?

\documentclass[twocolumn]{article}
\usepackage[landscape,margin=2cm]{geometry}
6

Andrew had the very sensible idea of not shrinking the file down to 71% since this makes the text rather small, and usually you don't want the excessive white margins. My approach to this: First magnify the file as needed, using the shell script I provide below (following Andrew's suggestion), and then use whatever tool you like to put 2 or 4 (or more) pages on one. I have to point out that I assume here that you work with postscript files. Yes, you do lose all the hyperlinks and stuff like that when you use pdftops, but I don't see any problem in this since I would only use this for printing.

My script is rather long since it tries to be clever. You don't really need instructions for using it; just type the name of the script (I call it gr since it makes things greater) without any parameters, and it'll print some usage information. I've put some comments in the file that explain a bit more. One thing I should explain: There's a nice feature that I often use, namely the so called "groptions". Suppose you have a TeX file "document.tex", and the output "document.ps". If in the first 10 lines of document.tex you have a line

%groptions: 15 thisfile -u4

then you can call the script by

gr document

and this will have the same effect as

gr 15 document -u4

namely: Magnify by 15%, and shift up by 4mm. So you don't always have to remember the parameters for that particular file.

# In the following comments I assume that this script is called "gr".
# You can also call it "mag" or whatever if you wish;
# the builtin command line help will understand this.

gv=false
[ "$1" = --gv ] && gv=true && shift
# This opens the output file with gv if the first parameter is --gv .
# I have aliased "gr" to "gr --gv", so that the --gv option
# is always selected if I type "gr" on a command line,
# and it is not selected if "gr" is called in a shell script.

# If you have a file <file>.ps, you can use
#      gr 20 <file>
# or   gr 20 <file>.
# or   gr 20 <file>.ps
# to magnify it by 20%.  The default output file is "gr.ps".
# The rationale behind this:
# If you have <file>.tex and <file>.ps in your directory,
# and you use the tab key for expanding the file name,
# then you'll only get "<file>.", and you don't have to type "ps".
#
# If the input file comes from standard input, use "gr 20 -".
if [ $# -eq 1 ]
then infile="${1%ps}"
     infile="${infile%.}"
     [ -f "$infile.tex" ] &&
     grop=`head "$infile.tex" | grep groptions | dos2unix` &&
     set -- `echo -n "$grop" | sed "s|.*groptions: ||;s|thisfile|$infile|"`
fi

compute () {
arg=`echo "$@" | sed 's|--|+|g'`
echo | awk "{print $arg}" | tr , .
}

eval "set -- `getopt -sbash r:l:u:d:o:i:x:y:2 "$@"`"
right=0
up=0
outward=0
xmin=0
xmax=595
ymin=0
ymax=842
fromsecond=false
while [ $# -gt 0 ]
do case "$1" in
    -r) right=`compute $right+$2`; shift;;
    -l) right=`compute $right-$2`; shift;;
    -u) up=`compute $up+$2`; shift;;
    -d) up=`compute $up-$2`; shift;;
    -o) outward=`compute $outward+$2`; shift;;
    -i) outward=`compute $outward-$2`; shift;;
    -x) xmin=${2%-*}; xmax=${2#*-}; shift;;
    -y) ymin=${2%-*}; ymax=${2#*-}; shift;;
    -2) fromsecond=true;;
    --) shift; break;;
   esac
   shift
done

[ -z "`echo "$1" | sed 's|[0-9.]||g'`" ] && proz=$1 && shift || proz=0 

[ $# -eq 0 ] && echo "    ${0##*/} -- magnifies the pages of postscript files
Usage: ${0##*/} <how many %> <which file>
       3rd parameter (optional): output file (without suffix .ps)
       options: -2 -- magnify only from second page on
                -l<number> -- shift left by <number>mm
                -r<number> -- shift right by <number>mm
                -u<number> -- shift up by <number>mm
                -d<number> -- shift down by <number>mm
                -o<number> -- shift outward by <number>mm
                -i<number> -- shift inward by <number>mm
                -x<min>-<max> -- cropping the x-scope <min>-<max>pt (default 0-595)
                -y<min>-<max> -- cropping the y-scope <min>-<max>pt (default 0-842)" && exit 0

outfile="${2:-gr}.ps"
if [ "$1" = - ]
then infile=/tmp/tmp$$infile.ps
     cat > $infile
     what='"$infile"'
# you can also use this script on .ps.gz files.
else infile="${1%.gz}"
     infile="${infile%ps}"
     infile="${infile%.}"
     # This is a good place where one could add conditional compilation
     # of the input file. For me this is:
     # condlatex "$infile" || exit 1
     # conddvips "$infile"
     infile="$infile.ps"
     [ -f "$infile" ] && what='"$infile"' ||
       if [ -f "$infile.gz" ]
         then unzip="gunzip -c '$infile.gz' |" && what=
         else echo "»$infile« not found" && exit 0
       fi
fi
right=`compute $right-$proz*1.05`
up=`compute $up-$proz*1.48`
proz=`compute 1+$proz/100`

pages () {
page=$(eval "$unzip head -n15 $what" | grep '%%Pages:* ' | cut -d' ' -f2 | dos2unix)
[ "$page" = "(atend)" ] && 
eval "$unzip tail $what" | grep '%%Pages:* ' | cut -d' ' -f2 | dos2unix ||
echo $page
}

if [ "$outward" = 0 ] && [ "$fromsecond" = false ]
then str="1:0@$proz(${right}mm,${up}mm)"
else pages=`pages`
     rpo=`compute $right+$outward`
     rmo=`compute $right-$outward`
     [ "$fromsecond" = true ] && str="$pages:0@1" ||
                           str="$pages:0@$proz(${rpo}mm,${up}mm)"
     p=1
     while [ $p -lt $pages ]
     do str="$str,$((p++))@$proz(${rmo}mm,${up}mm)"
    [ $p -lt $pages ] &&
    str="$str,$((p++))@$proz(${rpo}mm,${up}mm)"
     done
fi
eval "$unzip pstops -pa4 '$str' $what" | sed '
/^%%Page:* /N
/^userdict\/PStoPSsaved save put$/N
/^%%Page:* .*\nuserdict\/PStoPSsaved save put/,/^ closepath}put initclip$/{
/^userdict\/PStoPSclip{0 0 moveto$/,/^ closepath}put initclip$/d
/^PStoPSmatrix setmatrix$/a    userdict/PStoPSclip{'"$xmin $ymin"' moveto    '"$xmax $ymin lineto $xmax $ymax lineto $xmin $ymax"' lineto    closepath}put initclip
}
' > "/tmp/tmp$$$outfile"
mv "/tmp/tmp$$$outfile" "$outfile"
if $gv; then
  ps w | grep "[^]] gv $outfile" >/dev/null || gv "$outfile" &
fi
[ "$outfile" = gr.ps ] && echo "output in gr.ps"
[ $proz = 1 ] && echo '         No magnification !!!'
[ "$infile" = /tmp/tmp$$infile.ps ] && rm $infile
0
5

The booklet package might be able to help, but Beamer compatibility could be a problem.

4
  • Unfortunately amsbook compatibility also seems to be problematic (by which I mean, I can’t get it to work). Also, as far as I can find, it can’t be used to just n-up your pages without also rearranging them for booklet printing? Dec 6, 2010 at 4:15
  • @Peter Right, I think you should use an external tool for n-up printing. Dec 6, 2010 at 8:41
  • Yes… I’m happy with that in principle, but I’ve not yet found an external tool that lets me do it with the precision, exact control, and quality that *TeX solutions typically have, not to mention keeping hyperlinks etc. intact (like Andrew Stacey and Vivi, I often like to work from 2-up pdf‘s before the dead tree stage, for various reasons). pdfpages and pdfjam as mentioned above seem to come the closest, though. Dec 6, 2010 at 20:13
  • Actually, thinking again, I’m not entirely happy with that solution in principle :-) I don’t totally follow the arguments that n-up is beyond TeX’s sphere of responsibility. In some uses, n-up is just part of how I want to print the document. But in others, I conceive of the n-upping as part of the “idealised document” that I’m imagining — just like the page breaks, margins, numbering, layout, and so on — so it would be lovely to control it with *TeX, just like those other attributes. It’s definitely form not content, but it can be part of the “ideal form”, not just the “physical form”. Dec 6, 2010 at 20:21
5

This is an expansion of Stefan's answer which suggests using pgfpages. I just tried it using the 2 on 1 layout. I used a negative length to the border shrink argument to make the pages bigger to fit better on the page, but found that the pages weren't centred properly (at the best size, the page numbers were being lost off the bottom of the page). So I extended the 2 on 1 layout to take a horizontal and/or vertical shift argument to shift the centres of the pages. I'm posting it here in case it is of any use to anyone else. Due to one command, it needs to be either in a separate .sty file or sandwiched in \makeatletter ... \makeatother.

\define@key{pgfpagesuselayoutoption}{horizontal shift}%
{\def\pgfpageoptionhshift{#1}}
\define@key{pgfpagesuselayoutoption}{vertical shift}%
{\def\pgfpageoptionvshift{#1}}

\pgfpagesdeclarelayout{2 on 1 shifted}
{
  \edef\pgfpageoptionheight{\the\paperwidth} % landscaped by default
  \edef\pgfpageoptionwidth{\the\paperheight}
  \def\pgfpageoptionborder{0pt}
  \def\pgfpageoptionfirstshipout{1}
  \def\pgfpageoptionhshift{0pt}
  \def\pgfpageoptionvshift{0pt}
}
{
  \pgfpagesphysicalpageoptions
  {%
    logical pages=2,%
    physical height=\pgfpageoptionheight,%
    physical width=\pgfpageoptionwidth,%
    current logical shipout=\pgfpageoptionfirstshipout%
  }
  \ifdim\paperheight>\paperwidth\relax
    % put side-by-side
    \pgfpageslogicalpageoptions{1}
    {%
      border shrink=\pgfpageoptionborder,%
      resized width=.5\pgfphysicalwidth,%
      resized height=\pgfphysicalheight,%
      center=\pgfpoint{.25\pgfphysicalwidth+\pgfpageoptionhshift}{.5\pgfphysicalheight+\pgfpageoptionvshift}%
    }%
    \pgfpageslogicalpageoptions{2}
    {%
      border shrink=\pgfpageoptionborder,%
      resized width=.5\pgfphysicalwidth,%
      resized height=\pgfphysicalheight,%
      center=\pgfpoint{.75\pgfphysicalwidth+\pgfpageoptionhshift}{.5\pgfphysicalheight+\pgfpageoptionvshift}%
    }%
  \else
    % stack on top of one another
    \pgfpageslogicalpageoptions{1}
    {%
      border shrink=\pgfpageoptionborder,%
      resized width=\pgfphysicalwidth,%
      resized height=.5\pgfphysicalheight,%
      center=\pgfpoint{.5\pgfphysicalwidth+\pgfpageoptionhshift}{.75\pgfphysicalheight+\pgfpageoptionvshift}%
    }%
    \pgfpageslogicalpageoptions{2}
    {%
      border shrink=\pgfpageoptionborder,%
      resized width=\pgfphysicalwidth,%
      resized height=.5\pgfphysicalheight,%
      center=\pgfpoint{.5\pgfphysicalwidth+\pgfpageoptionhshift}{.25\pgfphysicalheight+\pgfpageoptionvshift}%
    }%
  \fi    
}

To use it:

\usepackage{pgfpages}

... now put or load the above code ...

\pgfpagesuselayout{2 on 1 shifted}[border shrink=-3cm,vertical shift=.5cm, horizontal shift=2cm]
\nofiles

At the moment, both pages are shifted by the same amount and in the same direction. It would be easy to extend it to shift these independently.

5

As the question doesn't specifically say that the solution should be for PDFs, I'd like a useful external tool that works on postscript documents called pstops. According to dpkg-query -S pstops, this comes from the psutils package on Debian/Ubuntu. The syntax takes a little getting used to, but as it can do some really clever tricks with postscript files, it's worth learning the basics. As with (La)TeX, the best way to learn is by example so here's the most frequent situation for me: I want to print an article, to save trees I decide to print it 2-up (and double sided). But standard articles come with a lot of white-space when they are created as a4paper/letter, so in doing the 2-up, I don't shrink by the standard 71% - 90% tends to be okay. The command to do this is:

pstops -pa4 "2:[email protected](24cm,-2cm)[email protected](24cm,12.85cm)" original.ps new.ps

Reading from left to right, this says: physical (output) page size is a4, work with the pages modulo 2, the even pages should be scaled .9, rotated to the left, and placed at '(24cm,-2cm)' on the page; the odd pages should be scaled .9, rotated to the left, and placed at '(24cm, 12.85cm)'; the original file is 'original.ps' and put the output in 'new.ps'.

Of course, I'll tweak the positioning and scaling for each document (I try not to print many) to optimise the spacing and size.

Once caveat: I note from my notes on this that the files produced by pstops didn't print duplex on my department printer so I needed to add a little extra hack to the file to ensure that they did. I recommend testing with a simple file to see if this is necessary. If so, follow the link at the start of this paragraph.

7
  • It is not what I am looking for (I use pdflatex and a mac, and I am yet to learn how to use shell commands...), but +1 for the detailed answer, which I am sure will be useful for someone!
    – Vivi
    Aug 2, 2010 at 11:22
  • 1
    @Vivi: full confession: I suspected as much! I also have a suspicion, though, that this question will be quite a popular one so rather than having lots of questions with slightly different conditions, I'd rather have one question with lots of slightly different answers. (Just spotted a typo in the first sentence: "I'd like to mention a useful ..."). Also, my plan is to get you using shell commands whether you want to or not! Aug 2, 2010 at 12:17
  • Someone should get the GTK/Gnome (an other DEs) people to implement that in the print dialog so that it automatically does that with the right parameters.
    – Caramdir
    Aug 2, 2010 at 14:12
  • @Andrew: I used your method for some time and then got annoyed by having to tweak the positioning and scaling all the time. My solution: I first use a shell script called "gr" (like "greater") to enlarge the text and remove the excessive margins. This also opens a previewer, so that I can check if it looks alright. Then I use a command like yours, but with standard parameters that never change. Oct 25, 2010 at 10:31
  • @Hendrik: I'm guessing that 'gr' is a script that you wrote yourself. Rather than reinventing the wheel, could you post it? If you think it best, I could CW this answer and you could add it here; or you could add it as a new answer and we can link the two. Oct 25, 2010 at 10:45
4

Try the 2up package.

3
  • 3
    fwiw, booklet is a LaTeX translation of the 2up package; booklet might be a little more compatible with arbitrary LaTeX packages, but I'm not very familiar with either of them. Aug 2, 2010 at 2:38
  • Thanks Will. I hadn't realised there was a connection between booklet and 2up. (I see now that you've documented it all in the booklet manual.) Aug 2, 2010 at 5:16
  • I'm only the (very recent) maintainer: all code and documentation is Peter Wilson's. Oct 26, 2010 at 14:53
4

Expanding on Will Robertson's suggestion, here's some code that uses the typearea package to calculate margins and text height / width for A5 pages, and then using twocolumn mode to simulate two A5 pages on one A4 page.

\documentclass{article}

\usepackage[twoside,a5paper,DIV=calc]{typearea}

\makeatletter
\@twocolumntrue
\@twosidefalse
\makeatother

\setlength{\oddsidemargin}{\evensidemargin}
\setlength{\columnsep}{\evensidemargin}
\addtolength{\columnsep}{1in}
\setlength{\textwidth}{2\textwidth}
\addtolength{\textwidth}{\columnsep}
\setlength{\pdfpagewidth}{297mm}
\setlength{\pdfpageheight}{210mm}

\usepackage{lipsum}

\begin{document}

\lipsum

\end{document}

2
  • As soon as I load hyperref, your nice layout breaks :/ Sep 24, 2014 at 23:59
  • 1
    Try \usepackage[setpagesize=false]{hyperref} Sep 29, 2014 at 12:00
1

2up sounds like exactly what you want. But here's another answer: pgfpages is part of the PGF package and has a pretty nice interface to doing things like this. It's used in beamer to produce handouts of slides.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .