How to add page numbers to Postscript/PDF

前端 未结 14 1868
臣服心动
臣服心动 2020-12-07 12:06

If you\'ve got a large document (500 pages+) in Postscript and want to add page numbers, does anyone know how to do this?

相关标签:
14条回答
  • 2020-12-07 12:15

    I took captaincomic's solution and added support for filenames containing spaces, plus giving some more informations about the progress

    #!/bin/bash
    clear
    echo
    echo This skript adds pagenumbers to a given .pdf file.
    echo 
    echo This skript needs the packages pdftk and enscript
    echo if not installed the script will fail.
    echo use the command sudo apt-get install pdftk enscript
    echo to install.
    echo 
    input="$1"
    output="${1%.pdf}-header.pdf"
    echo input file is $input
    echo output file will be $output
    echo 
    pagenum=$(pdftk "$input" dump_data | grep "NumberOfPages" | cut -d":" -f2)
    enscript -L1 --header='||Page $% of $=' --output - < <(for i in $(seq "$pagenum"); do echo; done) | ps2pdf - | pdftk "$input" multistamp - output "$output"
    echo done.
    
    0 讨论(0)
  • 2020-12-07 12:15

    I wrote the following shell script to solve this for LaTeX beamer style slides produced with inkscape (I pdftk cat the slides together into the final presentation PDF & then add slide numbers using the script below):

    #!/bin/sh
    
    # create working directory
    tmpdir=$(mktemp --directory)
    
    # read un-numbered beamer slides PDF from STDIN & create temporary copy
    cat > $tmpdir/input.pdf
    
    # get total number of pages
    pagenum=$(pdftk $tmpdir/input.pdf dump_data | awk '/NumberOfPages/{print $NF}')
    
    # generate latex beamer document with the desired number of empty but numbered slides
    printf '%s' '
    \documentclass{beamer}
    \usenavigationsymbolstemplate{}
    \setbeamertemplate{footline}[frame number]
    \usepackage{forloop}
    \begin{document}
     \newcounter{thepage}
      \forloop{thepage}{0}{\value{thepage} < '$pagenum'}{
        \begin{frame}
        \end{frame}
      }
    \end{document}
    ' > $tmpdir/numbers.tex
    
    # compile latex file into PDF (2nd run needed for total number of pages) & redirect output to STDERR
    pdflatex -output-directory=$tmpdir numbers.tex >&2 && pdflatex -output-directory=$tmpdir numbers.tex >&2
    
    # add empty numbered PDF slides as background to (transparent background) input slides (page by
    # page) & write results to STDOUT
    pdftk $tmpdir/input.pdf multibackground $tmpdir/numbers.pdf output -
    
    # remove temporary working directory with all intermediate files
    rm -r $tmpdir >&2
    

    The script reads STDIN & writes STDOUT printing diagnostic pdflatex output to STDERR.

    So just copy-paste the above code in a text file, say enumerate_slides.sh, make it executable (chmod +x enumerate_slides.sh) & call it like this:

    ./enumerate_slides.sh < input.pdf > output.pdf [2>/dev/null]
    

    It should be easy to adjust this to any other kind of document by adjusting the LaTeX template to use the proper documentclass, paper size & style options.

    edit: I replaced echo by $(which echo) since in ubuntu symlinks /bin/sh to dash which overrides the echo command by a shell internal interpreting escape sequences by default & not providing the -E option to override this behaviour. Note that alternatively you could escape all \ in the LaTeX template as \\.

    edit: I replaced $(which echo) by printf '%s' since in zsh, which echo returns echo: shell built-in command instead of /bin/echo. See this question for details why I decided to use printf in the end.

    0 讨论(0)
  • 2020-12-07 12:16

    you can simply use

    pspdftool

    • http://sourceforge.net/projects/pspdftool

    in this way:

    pspdftool 'number(x=-1pt,y=-1pt,start=1,size=10)' input.pdf output.pdf
    

    see these two examples (unnumbered and numbered pdf with pspdftool)

    unnumbered pdf

    http://ge.tt/7ctUFfj2

    numbered pdf

    http://ge.tt/7ctUFfj2

    with this as the first command-line argument:

    number(start=1, size=40, x=297.5 pt, y=10 pt)
    
    0 讨论(0)
  • 2020-12-07 12:17

    Based on rcs's proposed solution, I did the following:

    Converted the document to example.pdf and ran pdflatex addpages, where addpages.tex reads:

    \documentclass[8pt]{article}
    \usepackage[final]{pdfpages}
    \usepackage{fancyhdr}
    
    \topmargin 70pt
    \oddsidemargin 70pt
    
    \pagestyle{fancy}
    \rfoot{\Large\thepage}
    \cfoot{}
    \renewcommand {\headrulewidth}{0pt}
    \renewcommand {\footrulewidth}{0pt}
    
    \begin{document}
    \includepdfset{pagecommand=\thispagestyle{fancy}}
    \includepdf[fitpaper=true,scale=0.98,pages=-]{example.pdf}
    % fitpaper & scale aren't always necessary - depends on the paper being submitted.
    \end{document}
    

    or alternatively, for two-sided pages (i.e. with the page number consistently on the outside):

    \documentclass[8pt]{book}
    \usepackage[final]{pdfpages}
    \usepackage{fancyhdr}
    
    \topmargin 70pt
    \oddsidemargin 150pt
    \evensidemargin -40pt
    
    \pagestyle{fancy}
    \fancyhead{} 
    \fancyfoot{} 
    \fancyfoot[LE,RO]{\Large\thepage}
    
    \renewcommand{\headrulewidth}{0pt}
    \renewcommand{\footrulewidth}{0pt}
    
    \begin{document}
    \includepdfset{pages=-,pagecommand=\thispagestyle{fancy}}
    \includepdf{target.pdf}
    \end{document}
    

    Easy way to change header margins:

    % set margins for headers, won't shrink included pdfs
    % you can remove the topmargin/oddsidemargin/evensidemargin lines
    \usepackage[margin=1in,includehead,includefoot]{geometry}
    
    0 讨论(0)
  • 2020-12-07 12:23

    I was looking for a postscript-only solution, using ghostscript. I needed this to merge multiple PDFs and put a counter on every page. Only solution I found was an old gs-devel posting, which I heavily simplified:

    %!PS
    % add page numbers document bottom right (20 units spacing , harcoded below)
    % Note: Page dimensions are expressed in units of the default user space (72nds of an inch).
    % inspired by https://www.ghostscript.com/pipermail/gs-devel/2005-May/006956.html
    
    globaldict /MyPageCount 1 put % initialize page counter
    
    % executed at the end of each page. Before calling the procedure, the interpreter
    % pushes two integers on the operand stack:
    % 1. a count of previous showpage executions for this device
    % 2. a reason code indicating the circumstances under which this call is being made:
    %    0: During showpage or (LanguageLevel 3) copypage
    %    1: During copypage (LanguageLevel 2 only)
    %    2: At device deactivation
    % The procedure must return a boolean value specifying whether to transmit the page image to the
    % physical output device.
    << /EndPage {
      exch pop % remove showpage counter (unused)
      0 eq dup { % only run and return true for showpage
        /Helvetica 12 selectfont % select font and size for following operations
        MyPageCount =string cvs % get page counter as string
        dup % need it twice (width determination and actual show)
        stringwidth pop % get width of page counter string ...
        currentpagedevice /PageSize get 0 get % get width from PageSize on stack
        exch sub 20 sub % pagewidth - stringwidth - some extra space
        20 moveto % move to calculated x and y=20 (0/0 is the bottom left corner)
        show % finally show the page counter
        globaldict /MyPageCount MyPageCount 1 add put % increment page counter
      } if
    } bind >> setpagedevice
    

    If you save this to a file called pagecount.ps you can use it on command line like this:

    gs \
      -dBATCH -dNOPAUSE \
      -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
      -sOutputFile=/path/to/merged.pdf \
      -f pagecount.ps -f input1.pdf -f input2.pdf
    

    Note that pagecount.ps must be given first (technically, right before the the input file which the page counting should start with).

    If you don't want to use an extra .ps file, you can also use a minimized form like this:

    gs \
      -dBATCH -dNOPAUSE \
      -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress \
      -sOutputFile=/path/to/merged.pdf \
      -c 'globaldict /MyPageCount 1 put << /EndPage {exch pop 0 eq dup {/Helvetica 12 selectfont MyPageCount =string cvs dup stringwidth pop currentpagedevice /PageSize get 0 get exch sub 20 sub 20 moveto show globaldict /MyPageCount MyPageCount 1 add put } if } bind >> setpagedevice'
      -f input1.pdf -f input2.pdf
    

    Depending on your input, you may have to use gsave/grestore at the beginning/end of the if block.

    0 讨论(0)
  • 2020-12-07 12:25

    I am assuming you are looking for a PS-based solution. There is no page-level operator in PS that will allow you to do this. You need to add a footer-sort of thingy in the PageSetup section for each page. Any scripting language should be able to help you along.

    0 讨论(0)
提交回复
热议问题