numbering pages

Help
2011-03-10
2013-03-05
  • Jean-Luc T.
    Jean-Luc T.
    2011-03-10

    Hi Denis et al.,

    I use xournal to give math lectures and post them on the web for students.  If is very useful to then have page numbers and a running header/footer.  I don't think xournal can do this (correct me if I'm wrong), and searching the web only turned up a kludgy solution: use pdftk to stamp each PDF page with its own PDF overlay.

    Kludgy or not, it seems the only way, so I wrote a script to do this automatically: I'd like to know if the Xournal community can think of a better way, or if it would be worth developing further (right now it's missing many features, such as specifying margins).

    (The script requires pdftk, pdflatex, and a few standard latex packages such as geometry, ifthen, and fancyhdr.)

    Best,

    Jean-Luc

    ---------------- numberpdf bash script ---------------------------------------

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    #!/bin/sh
    CMDNAME=`basename $0`
    AUTHOR="Jean-Luc Thiffeault (www.math.wisc.edu/~jeanluc)"
    MAXPAGES=9999
    usage()
    {
    cat << EOF
    Usage: $CMDNAME [-hv] [-o outfile] filename[.pdf] [outfile]
    This script adds page numbers to a PDF document.
    OPTIONS:
       -h, --help         show this message
       -v, --version      version number
       -o, --outfile      specify an output filename
       --{l,c,r}head      left, center, right header (default empty).
       --{l,c,r}foot      left, center, right footer (default cfoot="\thepage").
    Append even/odd to head or foot to specify different format for even/odd pages.
    Example: for alternate left/right numbering in the footer:
    $CMDNAME in.pdf -o out.pdf --lfootodd "\thepage" --rfooteven "\thepage"
    Author: $AUTHOR
    EOF
    }
    HEADOPTS="lhead:,chead:,rhead:,lheadeven:,cheadeven:,rheadeven:,lheadodd:,cheadodd:,rheadodd:"
    FOOTOPTS="lfoot:,cfoot:,rfoot:,lfooteven:,cfooteven:,rfooteven:,lfootodd:,cfootodd:,rfootodd:"
    # TODO: Add margin options.
    # Use getopt instead of built-in getopts because it can do long
    # options and doesn't care if the extra arguments come first.
    CMDLINEOPTS=`getopt -o hvo: \
        --long help,version,output:,${HEADOPTS},${FOOTOPTS} \
        -n $CMDNAME -- "$@"`
    if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
    # Note the quotes around `$CMDLINEOPTS': they are essential!
    eval set -- "$CMDLINEOPTS"
    while true ; do
        case "$1" in
        -h|--help)
                usage
                exit 0
                ;;
        -v|--version)
                rev=`echo '$Revision: 1.3 $' | cut -d '$' -f 2 | cut -c 10-`
            echo $CMDNAME version $rev by $AUTHOR
                exit 0
                ;;
        -o|--output)
                outfile=$2
            shift 2 ;;
        --lhead)
                lhead=$2
            shift 2 ;;
        --chead)
                chead=$2
            shift 2 ;;
        --rhead)
                rhead=$2
            shift 2 ;;
        --lheadeven)
                lheadeven=$2
            shift 2 ;;
        --cheadeven)
                cheadeven=$2
            shift 2 ;;
        --rheadeven)
                rheadeven=$2
            shift 2 ;;
        --lheadodd)
                lheadodd=$2
            shift 2 ;;
        --cheadodd)
                cheadodd=$2
            shift 2 ;;
        --rheadodd)
                rheadodd=$2
            shift 2 ;;
        --lfoot)
                lfoot=$2
            shift 2 ;;
        --cfoot)
                cfoot=$2
            shift 2 ;;
        --rfoot)
                rfoot=$2
            shift 2 ;;
        --lfooteven)
                lfooteven=$2
            shift 2 ;;
        --cfooteven)
                cfooteven=$2
            shift 2 ;;
        --rfooteven)
                rfooteven=$2
            shift 2 ;;
        --lfootodd)
                lfootodd=$2
            shift 2 ;;
        --cfootodd)
                cfootodd=$2
            shift 2 ;;
        --rfootodd)
                rfootodd=$2
            shift 2 ;;
        --) shift ; break ;;
        *) echo "Internal error!" ; exit 1 ;;
        esac
    done
    # We want at least one and at most two non-option argument.
    if [ $# -eq 0 ] || [ $# -gt 2 ]; then
        usage
        exit 1
    fi
    filename=$(basename $1 .pdf)     # base filename
    infile=$(dirname $1)/$filename   # base filename with path
    pagenumfile=pagenumbers
    if [ ! -n "$outfile" ]; then
        if [ $# -eq 2 ]; then
            # If there are two non-option arguments, and outfile wasn't
            # specified as an option, set outfile to the second argument.
        outfile=$2
        else
        outfile=${infile}num.pdf
        fi
    else
        if [ $# -eq 2 ]; then
        echo "Specify either -o or two non-option arguments, but not both."
        exit 1
        fi
    fi
    # With --{l,c,r}head option, use the same header for even/odd pages.
    if [ -n "$lhead" ] || [ -n "$chead" ] || [ -n "$rhead" ]; then
        if \
        [ -n "$lheadeven" ] || [ -n "$cheadeven" ] || [ -n "$rheadeven" ] || \
        [ -n "$lheadeven" ] || [ -n "$cheadeven" ] || [ -n "$rheadeven" ]
        then
        echo "Don't specify even/odd headers if you use --{l,c,r}head option."
        exit 1
        fi
        lheadeven="$lhead"
        cheadeven="$chead"
        rheadeven="$rhead"
        lheadodd="$lhead"
        cheadodd="$chead"
        rheadodd="$rhead"
    fi
    # With --{l,c,r}foot option, use the same footer for even/odd pages.
    if [ -n "$lfoot" ] || [ -n "$cfoot" ] || [ -n "$rfoot" ]; then
        if \
        [ -n "$lfooteven" ] || [ -n "$cfooteven" ] || [ -n "$rfooteven" ] || \
        [ -n "$lfooteven" ] || [ -n "$cfooteven" ] || [ -n "$rfooteven" ]
        then
        echo "Don't specify even/odd footers if you use --{l,c,r}foot option."
        exit 1
        fi
        lfooteven="$lfoot"
        cfooteven="$cfoot"
        rfooteven="$rfoot"
        lfootodd="$lfoot"
        cfootodd="$cfoot"
        rfootodd="$rfoot"
    fi
    # Default is to label the pages at the bottom-center, if no other
    # footer is specified.  Default header is empty.
    if \
       [ ! -n "$lfooteven" ] && [ ! -n "$cfooteven" ] && [ ! -n "$rfooteven" ] && \
       [ ! -n "$lfooteven" ] && [ ! -n "$cfooteven" ] && [ ! -n "$rfooteven" ]
    then
        cfooteven="\thepage"
        cfootodd="\thepage"
    fi
    # Split file into individual pages.  Also makes the doc_data.txt file.
    pdftk $infile.pdf burst output ${filename}_page%04d.pdf &> /dev/null
    # Extract the number of pages from doc_data.txt.
    numpages=`grep NumberOfPages doc_data.txt | cut -c 16-`
    if [ $numpages -lt 1 ]; then
        echo "No pages?"
        exit 1
    fi
    # Limited to a maximum of 9999 pages because of the %04d in filenames.
    # Also need to change the ???? in cleanup part if this is changed.
    if [ $numpages -gt $MAXPAGES ]; then
        echo "Oops... script limited to $MAXPAGES pages."
        exit 1
    fi
    # Make the page numbers latex file.
    echo "\documentclass[12pt]{book}
    \usepackage[top=.75in, bottom=.7in, left=1.2in, right=1.2in]{geometry}
    \usepackage{fancyhdr,ifthen,times}
    \lhead[$lheadeven]{$lheadodd}
    \chead[$cheadeven]{$cheadodd}
    \rhead[$rheadeven]{$rheadodd}
    \lfoot[$lfooteven]{$lfootodd}
    \cfoot[$cfooteven]{$cfootodd}
    \rfoot[$rfooteven]{$rfootodd}
    \pagestyle{fancy}
    \renewcommand{\headrulewidth}{0pt}
    \begin{document}
    \setcounter{page}{1}
    \newcounter{lastpage}
    \setcounter{lastpage}{$numpages} % The number of pages to print.
    \addtocounter{lastpage}{1}
    \whiledo{\value{page} < \value{lastpage}}{
    \hbox{}\newpage
    }
    \end{document}" > $pagenumfile.tex
    # Split page numbers file into individual pages.
    pdflatex $pagenumfile.tex &> /dev/null
    pdftk $pagenumfile.pdf burst output ${pagenumfile}_page%04d.pdf
    for (( i=1; i<=$numpages; i++))
    do
      printf -v p '%04d' $i
      pdftk ${filename}_page$p.pdf stamp ${pagenumfile}_page$p.pdf \
          output ${filename}num_page$p.pdf
    done
    # Catenate all the pages back together.
    pdftk ${filename}num_page????.pdf cat output ${filename}num.pdf
    # Convert to PS and back (reduces size -- removes redundant fonts?)
    pdf2ps ${filename}num.pdf &> /dev/null
    ps2pdf ${filename}num.ps &> /dev/null
    rm -f ${filename}num.ps
    # Rename according to command-line.
    # Note that they can have the same name.
    mv -f ${filename}num.pdf $outfile &> /dev/null
    # Clean up
    rm -f ${filename}_page????.pdf ${infile}num_page????.pdf \
        ${pagenumfile}_page????.pdf
    rm -f doc_data.txt
    rm -f $pagenumfile.pdf $pagenumfile.aux $pagenumfile.log $pagenumfile.tex
    
     
  • Jean-Luc T.
    Jean-Luc T.
    2011-03-11

    For some reason your search turned up more options than my original one… maybe because I was specifically looking for Linux solutions.  As far as I can tell, none of these are command-line based?   Since I have to do the renumbering often (every time I add a lecture, using a Makefile) that's a problem.

    Thanks anyways!

    Jean-Luc

     
  • doe544
    doe544
    2011-03-11

    http://jpdftweak.sourceforge.net/ is not command-line based but I found it easy to add pagenumbers.
    It worked on Ubuntu10.04 for me. (just tested it on a pdf consisting of two pages)

    btw. do you use matlab on linux or are you also using scilab (just curious :) )?

     
  • Jean-Luc T.
    Jean-Luc T.
    2011-03-13

    > btw. do you use matlab on linux or are you also using scilab (just curious :) )?

    Matlab for the most part (and some Mathematica).

    Jean-Luc

     
  • WCA_Rick
    WCA_Rick
    2011-03-31

    I took a different approach.  i wrote a simple set of python scripts to add or remove page numbers from the xoj file itself.

    Xournal page numbering scripts

    One script numbers the file, the other script removes the number.  Crude, but my students like having the page numbers since I typically give students the pages after using them in class.

     
  • Jean-Luc T.
    Jean-Luc T.
    2011-03-31

    That's great!  Much simpler than what I did.  In fact I suppose it would be relatively easy to add this feature directly to xournal, then.

    Many thanks,

    Jean-Luc