# Add page and line numbers to a pdf

Is there any quick script to add page and line numbers to each page of a pdf document?

1) I often enough get articles in pdf to review, with no page number. I end up writing them by hand to refer to each page when pointing errors.

2) When referring an error, I end up counting by hand the lines from the beginning or from the end, or copying the context, to precise the location of the error. It would be much more practical to have a standard way to add line numbers to an existing document.

I could manage editing the LaTeX source to obtain this, but not when I receive a pdf. PDF format does not contain lines per say, so identifying them would require to cluster the y coordinates of the letters, and adding those numbers in the margin would require to take the min of the x coordinates and remove a fixed amount from it. Anybody did this script already, or seen another way?

-

Alright, here's a go at numbering lines in a PDF (or any other image format) without access to the source.

I wrote a little shell script that, using ImageMagick (at least version 6.6.9-4), converts a given PDF into separate raster images for each page, splits these into half pages, shrinks them to a width of one pixel (so takes the horizontal average, basically), turns this into a monochrome image with a given threshold (black=text, white=no text), shrinks every black sequence down to one pixel (=middle of a line), outputs this as a text, pipes it to sed to clean it up and remove all the non-text lines and finally writes a txt file with the position of each line as 1/1000 of the text height.

findlines.sh:

convert $1.pdf -crop 50x100% png:$1

Notice that there is another variable $threshold: this is the minimal distance between two lines. Indeed, when you typeset, for example, a superscript, then there is small jump in the PDF file which my script considers as a separate line. But by asking for line skips of at least the threshold, these small jumps are not taken into account. Here is the script: use CAM::PDF; use PDF::API2;$file=$ARGV[0];$newfile=$ARGV[1];$leftmargin=70;
$threshold=8; if (-e$file) {

$pdf = CAM::PDF->new($file);

$nbpages=$pdf->numPages();

foreach $i (1 ..$nbpages) {
$page1 =$pdf->getPageContent($i); @BTS=(); while ($page1 =~ m/^BT\n((.|\n|\r)+?)\nET/gm) {
push @BTS, $1; } foreach$BT (@BTS) {
$x=0;$y=0;
while ($BT =~ m/([0-9.-]+) ([0-9.-]+) Td/g) {$x=$x + ($1);
$y=$y + ($2); if ($2 > $threshold or$2 < -$threshold) { push @{"PAGES".$i}, $y; } } } @{"PAGES".$i} = sort { $b <=>$a; } @{"PAGES".$i};$prey=10000000; @X=();
foreach $y (@{"PAGES".$i}) {
if ($prey -$y < $threshold) {} else { push @X,$y; }
$prey=$y;
}
@{"PAGES".$i}=@X; }$pdf = PDF::API2->open($file); # Add a built-in font to the PDF$font = $pdf->corefont('Times-Roman'); # Add an external TTF font to the PDF #$font = $pdf->ttfont('/path/to/font.ttf'); # Add some text to the page foreach$i (1 .. $nbpages) {$page = $pdf->openpage($i);
$j=0; foreach$y (@{"PAGES".$i}) {$text = $page->text();$text->font($font, 10);$text->fillcolor('blue');
$text->translate($leftmargin, $y);$text->text($j);$j++;
}
}

# Save the PDF
$pdf->saveas($newfile);

}

-
That's a very elegant approach! It's a bit unfortunate that it requires the document to be compiled with pdflatex and a special option, though. The chance that a document has been created that way are pretty slim, and if you had access to the source to recompile the document correctly, you might as well just use the lineno package as benregn suggests. –  Jake Sep 17 '12 at 14:25
You can always use ps2pdf14 to change the PDF level of your file. –  yannis Sep 17 '12 at 17:15
Ah, that's a useful hint! Do I understand correctly, though, that the files have to be produced by pdflatex? I haven't been able to get the script to work with PDFs of journal articles (for example the one linked to in my answer). –  Jake Sep 17 '12 at 18:21
The limitation is on the level of PDF code parsing. I'm only considering the Td operator (as pdflatex always uses solely that one), but there are others. You should uncompress your file and look at what operators are used for moving to the next line, in the ET/BT areas. –  yannis Sep 21 '12 at 13:34

I've encountered the same problems as the OP jeremy, and my version of convert doesn't have morphology as an option. So, I've had to find another solution.

If one does not care whether the line numbers correspond to actual lines in the text (for example numbering a scanned document in pdf format) but only that there are line numbers going down the side of the page, one can combine pdfpages with "Knuth's loop" described here to put a column of numbers down the left side of every page, which is often sufficient for the purpose at hand.

For example, the LaTeX code

\documentclass{article}
\usepackage{pdfpages}
\usepackage[top=0in, bottom=0in, left=0in, right=0in]{geometry}
\usepackage[usenames,dvipsnames]{color}

\makeatletter
\newsavebox{\@linebox}
\savebox{\@linebox}[3em][t]{\parbox[t]{3em}{%
\@tempcnta\@ne\relax
\loop{\color{Red} \small\the\@tempcnta}\\
\makeatother

\begin{document}
\makeatletter

%% IF PAGE NUMBERS ALSO ARE NEEDED, USE \thispagestyle{plain} INSTEAD
\includepdf[pages=1-,pagecommand={\thispagestyle{empty} \hspace{0.5in} \usebox{\@linebox}},fitpaper]{loremipsum.pdf}

%% FOR LINE NUMBERS > 66 INCLUE OPTION openright AND DISCARD FIRST TWO PAGES OF OUTPUT
% \setcounter{page}{-1}  %% FOR LINE NUMBERS > 66 AND PAGESTYLE plain
% \includepdf[pages=1-,pagecommand={\thispagestyle{empty} \hspace{0.5in} \usebox{\@linebox}},fitpaper,openright]{loremipsum.pdf}

\makeatother
\end{document}

%% TO MAKE LOREMIPSUM.PDF
% \documentclass[10pt]{article}
% \usepackage{lipsum}
% \begin{document}
% \section*{Lorem Ipsum}
% \lipsum
% \end{document}


produces the output

To get numbers going all the way down the page, I had to find a workaround described in the LaTeX code. For numbering greater than 65, the first page's numbers get shifted to a second page (for some unknown reason), so my trick is to insert a blank page with the openright option (resetting the page count as needed) and then remove the first two pages of output later. Someone better versed in LaTeX might find a more elegant solution, but this seems to work for me. You can bet that the authors of unnumbered papers are going to get a short lecture on how important it is to provide the reviewer with line (and equation) numbers throughout.

-
This might solve the problem for some, but in my case the coordinates (page,line) used in an anonymous review should be understandable by the authors: it won't be the case if the numbers do not correspond to the lines of the document. –  Jeremy Jun 19 '11 at 4:26
Springer journals seems to do something like this. –  Joe Corneli Nov 3 '14 at 4:37

If you really want to add them to a PDF file, such as for legal documents, these tricks might work for you.

# Add page numbers to a doc

1. fix xref table if necessary with pdftk test-foo.pdf output test-bar.pdf
2. pspdftool 'number(start=1, size=20, x=550 pt, y=10 pt)' test-bar.pdf test-baz.pdf

These numbers are a little big, but this works great for scanned evidence sections. I prepare the evidence section as a separate doc and then number it with the correct "start" number to start after the last page of the brief.

pspdftool takes font options, but you have to figure out the font name from the name of the font file, not how it appears in a word processor.

# Add evenly-spaced line numbers to a doc

I do this because in a trial court filing, the lines should be numbered with even spaces, even if I use blockquotes with thin spacing.

LibreOffice links the line numbers to specific paragraphs on the page.

I got tired of using awkward text area blocks for blockquotes and linking them across pages.

I just want to write whatever I want in the page with different styles and stamp on the numbers later.

Solution:

1. Format one page with line numbers turned on in your word processor, and nothing else.
2. Export the line numbers page to nums.text.pdf.
3. Vectorize it so the numbers don't show up in text search. This worked:
gs -o temp.ps -dNOCACHE -sDEVICE=pswrite nums.text.pdf;
gs -o nums-outlines.pdf -sDEVICE=pdfwrite temp.ps
4. Stamp the numbers:
pdftk unnumbered-fulldoc.pdf multibackground nums-outlines.pdf output combinedfile.pdf

Hope this helps. -Mark

-

If I understand your need to add line numbers to the PDF, you can by using the lineno package. It does, however, only add line numbers according to how LaTeX sets up the text, which can be quite different from the source.

\documentclass[11pt,a4paper]{article}
\usepackage{lineno}
\usepackage{lipsum}
\begin{document}
\linenumbers
\lipsum
\end{document}


-
This adds the line numbers in the source LaTeX document. @Jeremy need to add line numbers to an existing pdf documemt. –  Alan Munn May 21 '11 at 18:03
No, I think the OP wants to add line numbers to an existing PDF. –  Martin Scharrer May 21 '11 at 18:03
@Alan Munn & @Martin Scharrer: Ahh, of course. I am the king of misunderstanding people! –  benregn May 21 '11 at 18:15
Agreed with Alan and Martin (althouh I think the feature would be useful for many other people too!) –  Jeremy May 23 '11 at 14:12

Here, we give a simple answer to this question by using a few latex packages. For example, the LaTeX code:

%% To make "loremipsum.pdf"
% \documentclass[10pt]{article}
% \usepackage{lipsum}
%\usepackage[top=2.5cm, bottom=2.5cm, left=2.5cm, right=2.5cm]{geometry}
%  \renewcommand{\baselinestretch}{1.33}
% \begin{document}
% \section*{Lorem Ipsum}
% \lipsum
% \end{document}

\documentclass[12pt]{article}
\usepackage[top=2.5cm, bottom=2.5cm, left=0.5cm, right=0.5cm]{geometry}
\usepackage{ifthen}
\usepackage{pdfpages}
\usepackage[left]{lineno}
\renewcommand\thelinenumber{\bf\scriptsize\color{red}\arabic{linenumber}}
\renewcommand{\baselinestretch}{1.0} % interline spacing

\begin{document}
\newcounter{ctr}
\newcounter{ct}
\setcounter{ct}{1}
\whiledo {\value{ct} < 3} % 2 is the number of the Pdf pages
{
\enlargethispage{3cm}
\begin{minipage}[t]{0.1\textwidth}
\internallinenumbers
\begin{runninglinenumbers*}
\setcounter{ctr}{1}
\whiledo {\value{ctr} < 48} % each page contain 32 line
{
$\longleftrightarrow$\
\stepcounter {ctr}%
}
\end{runninglinenumbers*}
\end{minipage}
\begin{minipage}[t]{0.8\textwidth}
\includepdf[pages=\thect,pagecommand={\thispagestyle{empty}}]{loremipsum.pdf}
\end{minipage}
\clearpage
\stepcounter {ct}%
}
\end{document}

enter code here


produces the output

-
The line numbers and the lines are not aligned, the shift becomes more and more dominant at the end of the page. –  SoundsOfSilence Aug 4 '14 at 12:10
As for Johnson's solution above: This might solve the problem for some, but in my case the coordinates (page,line) used in an anonymous review should be understandable by the authors: it won't be the case if the numbers do not correspond to the lines of the document. –  Jeremy Aug 5 '14 at 13:31