Solución:
Muy bien, aquí tienes una oportunidad para numerar líneas en un PDF (o cualquier otro formato de imagen) sin acceso a la fuente.
Escribí un pequeño script de shell que, usando ImageMagick (al menos la versión 6.6.9-4), convierte un PDF dado en imágenes rasterizadas separadas para cada página, las divide en medias páginas, las encoge a un ancho de un píxel (por lo que toma el promedio horizontal, básicamente), convierte esto en una imagen monocromática con un umbral dado (negro = texto, blanco = sin texto), reduce cada secuencia negra a un píxel (= medio de una línea), genera esto como un texto, lo canaliza a sed
para limpiarlo y eliminar todas las líneas que no son de texto y finalmente escribe un txt
archivo con la posición de cada línea como 1/1000 de la altura del texto.
findlines.sh
:
convert $1.pdf -crop 50x100% png:$1
for f in $1-*; do
convert $f -flatten -resize 1X1000! -black-threshold 99% -white-threshold 10% -negate -morphology Erode Diamond -morphology Thinning:-1 Skeleton -black-threshold 50% txt:-| sed -e '1d' -e '/#000000/d' -e 's/^[^,]*,//' -e 's/[(]//g' -e 's/:.*//' -e 's/,/ /g' > $f.txt;
done
La ejecución del script tarda aproximadamente 1 segundo en una página, lo que genera varios archivos: basename-<number>.txt
, donde extraño <numbers>
contienen las posiciones de los números de la línea izquierda, e incluso <numbers>
los de los números de página correctos. Estos archivos pueden ser leídos por pgfplotstable
(al menos v 1.4) y se utilizará para componer los números de línea en la parte superior del importado pdf
expediente. Definí un comando que toma el número de página y cuatro números de línea como argumentos, donde los cuatro números de línea se usan para decirle a la macro en qué números de línea “sin procesar” comienzan y terminan las líneas de texto “reales” en la columna izquierda y derecha. Configurando pgfkeys{print raw line numbers=true}
, los números de línea sin procesar encontrados por el algoritmo se muestran en rojo.
documentclass{article}
usepackage{tikz}
usepackage{pgfplotstable}
newififprintrawlinenumbers
pgfkeys{print raw line numbers/.is if=printrawlinenumbers,
print raw line numbers=true}
newcommand{addlinenumbers}[5]{
pgfmathtruncatemacro{leftnumber}{(#1-1)*2}
pgfmathtruncatemacro{rightnumber}{(#1-1)*2+1}
pgfplotstableread{pdfname-leftnumber.txt}leftlines
pgfplotstableread{pdfname-rightnumber.txt}rightlines
begin{tikzpicture}[font=tiny,anchor=east]
node[anchor=south west,inner sep=0] (image) at (0,0) {includegraphics[width=14cm,page=#1]{pdfname.pdf}};
begin{scope}[x={(image.south east)},y={(image.north west)}]
pgfplotstableforeachcolumnelement{[index] 0}ofleftlinesasposition{
ifprintrawlinenumbers
node [font=tiny,red] at (0.04,1-position/1000) {pgfplotstablerow};
fi
pgfmathtruncatemacro{checkexcluded}{
(pgfplotstablerow>=#2 && pgfplotstablerow<=#3) ? 1 : 0)
}
ifnumcheckexcluded=1
pgfmathtruncatemacrolinenumber{pgfplotstablerow-#2+1}
node [font=tiny,align=right,anchor=east] at (0.08,1-position/1000) {linenumber};
fi
}
pgfplotstablegetrowsof{leftlines}
pgfmathtruncatemacrorightstart{min((pgfplotsretval-#2),(#3-#2+1))}
pgfplotstableforeachcolumnelement{[index] 0}ofrightlinesasposition{
ifprintrawlinenumbers
node [font=tiny,red,anchor=east] at (1.0,1-position/1000) {pgfplotstablerow};
fi
pgfmathtruncatemacro{checkexcluded}{
(pgfplotstablerow>=#4 && pgfplotstablerow<=#5) ? 1 : 0)
}
ifnumcheckexcluded=1
pgfmathtruncatemacrolinenumber{pgfplotstablerow-#4+rightstart+1}
node [font=tiny] at (0.96,1-position/1000) {linenumber};
fi
}
end{scope}
end{tikzpicture}
}
begin{document}
defpdfname{article}
addlinenumbers{1}{20}{50}{2}{65}
pgfkeys{print raw line numbers=false}
addlinenumbers{2}{0}{69}{0}{64}
addlinenumbers{3}{19}{47}{21}{48}
end{document}
Como prueba de concepto, aquí está el resultado de las dos primeras páginas de un artículo del Environmental Science & Technology Journal. Creo que funciona muy bien. No he podido llamar findlines.sh
desde dentro de LaTeX, sin embargo, este paso debe realizarse manualmente antes de compilar el .tex
expediente.
Puede hacer (1) fácilmente con el pdfpages
paquete.
documentclass{article}
usepackage{pdfpages}
begin{document}
includepdf[pages=1-,pagecommand={thispagestyle{plain}}]{<pdffile>}
end{document}
En el documento de ejemplo, simplemente pasé el estilo de página plain
al pagecommand
, pero usando el fancyhdr
paquete puede hacer cualquier tipo de encabezado / pie de página adicional que desee. Para colocar el número de página de forma adecuada, es posible que también deba ajustar los márgenes con el geometry
paquete. Por ejemplo:
documentclass{article}
usepackage[margin=.5in]{geometry}
usepackage{pdfpages}
usepackage{fancyhdr}
fancyhf{}
renewcommand{headrulewidth}{0pt}
lfoot{textit{My pdf document}}
rfoot{thepage}
begin{document}
includepdf[pages=1-,pagecommand={thispagestyle{fancy}}]{<pdffile>}
end{document}
Esto coloca un pie de página que contiene “Mi documento pdf“a la izquierda y el número de página a la derecha. El margen es muy pequeño para que el número de página no interfiera con el documento incluido.
Para asegurarse de que el tamaño de papel del PDF de salida sea el mismo que el PDF incluido, agregue el fitpaper
opción a includepdf
. Desde el pdfpages
manual:
fitpaper Ajusta el tamaño del papel al del documento insertado.
Vea la respuesta de Jake para un método muy ingenioso de agregar números de línea a un pdf existente.
Si entiendo su necesidad de agregar números de línea al PDF, puede usar el lineno
paquete. Sin embargo, solo agrega números de línea de acuerdo con cómo LaTeX configura el texto, que puede ser bastante diferente de la fuente.
documentclass[11pt,a4paper]{article}
usepackage{lineno}
usepackage{lipsum}
begin{document}
linenumbers
lipsum
end{document}