How can I include the (approximate) file size of the generated pdf within a pdflatex
document? I envision having to compile it three times: once to create the pdf, a second time to write the size to an .aux
file and the third pass will include it in the document. A minimal working example would be pedagogic and useful!
3 Answers
\documentclass{article}
\IfFileExists{\jobname.pdf}
{\edef\Size{\pdffilesize{\jobname.pdf}}}
{\def\Size{0}}
\begin{document}
\Size
xyz
\end{document}
You test the existence of the PDF file produced in the previous run before pdftex
starts to write on a new one. The primitive \pdffilesize
outputs the file size and with \edef
you freeze this at the moment of executing \pdffilesize
.
It won't be accurate to the byte, because of compression. I get
10401
9427
10258
10599
10466
in successive runs over the document. Dividing by 1024 and rounding could be better:
\IfFileExists{\jobname.pdf}
{\edef\Size{\number\numexpr\pdffilesize{\jobname.pdf}/1024\relax\,KiB}}
{\def\Size{0\,KiB}}
Here is an implementation in ConTeXt MkIV. I use io.fileseize(...)
(part of ConTeXt's l-io.lua
library) to find the size of the pdf file and add it to a two pass data list. By default, ConTeXt automatically recompiles the file if the two pass data list has changed, until a maximum of 8 runs after which it stops even if the two pass data is changing.
The filesize never stabilizes! Here is the implementation.
\def\OutputSize{0}
\def\PrevOutputSize{0}
\definetwopasslist{OutputSize}
% Read size from aux file
\gettwopassdata{OutputSize}
\iftwopassdatafound
\xdef\PrevOutputSize{\twopassdata}
\fi
% Find the new size
\doiffile{\jobname.pdf}
{\ctxlua{context.setvalue("OutputSize", io.size("\jobname.pdf"))}}
\savetwopassdata {OutputSize} {\PrevOutputSize} {\OutputSize}
% Useful for grepping the result
\writestatus{CHECK}{Outsize: \PrevOutputSize, Newsize: \OutputSize}
% Show figure size on footer
\setupfootertexts[\jobname: \OutputSize]
\starttext
\input knuth
\stoptext
Starting in a scratch directory, compiling the file and grepping for CHECK
in the output gives:
$ context test.tex | grep CHECK
CHECK > Outsize: 0, Newsize: 0
CHECK > Outsize: 0, Newsize: 9380
CHECK > Outsize: 9380, Newsize: 10033
CHECK > Outsize: 10033, Newsize: 9751
CHECK > Outsize: 9751, Newsize: 9858
CHECK > Outsize: 9858, Newsize: 9921
CHECK > Outsize: 9921, Newsize: 9706
CHECK > Outsize: 9706, Newsize: 9952
As can be seen, even after 8 runs, the file size has not stabilized. I ran it again (without deleting any temporary file) and get
$ context test.tex | grep CHECK
CHECK > Outsize: 9952, Newsize: 9892
CHECK > Outsize: 9892, Newsize: 9856
CHECK > Outsize: 9856, Newsize: 10083
CHECK > Outsize: 10083, Newsize: 9899
CHECK > Outsize: 9899, Newsize: 9732
CHECK > Outsize: 9732, Newsize: 9965
CHECK > Outsize: 9965, Newsize: 9927
CHECK > Outsize: 9927, Newsize: 9793
So, even after 16 runs, the file size has not stabilized. I thought that the oscillation in file size is because the pdf output is compressed.
I added
\pdfcompresslevel=0
on top of the file, and started from scratch again. This time I get
$ context test.tex | grep CHECK
CHECK > Outsize: 0, Newsize: 0
CHECK > Outsize: 0, Newsize: 15044
CHECK > Outsize: 15044, Newsize: 15638
CHECK > Outsize: 15638, Newsize: 15920
CHECK > Outsize: 15920, Newsize: 15827
CHECK > Outsize: 15827, Newsize: 15798
CHECK > Outsize: 15798, Newsize: 15810
CHECK > Outsize: 15810, Newsize: 15692
$ context test.tex | grep CHECK
CHECK > Outsize: 15692, Newsize: 15865
CHECK > Outsize: 15865, Newsize: 15730
CHECK > Outsize: 15730, Newsize: 15827
CHECK > Outsize: 15827, Newsize: 15798
CHECK > Outsize: 15798, Newsize: 15810
CHECK > Outsize: 15810, Newsize: 15692
CHECK > Outsize: 15692, Newsize: 15865
CHECK > Outsize: 15865, Newsize: 15730
Again, an oscillating file size and I don't know why that is happening.
So, in the end I decided to round the file size in kilo bytes, by diving the file size by 1024
.
% Find the new size
\doiffile{\jobname.pdf}
{\ctxlua{context.setvalue("OutputSize", string.format("\%d", io.size("\jobname.pdf")/1024))}}
This time, as expected, the compilation stops after three runs.
$ context test.tex | grep CHECK
CHECK > Outsize: 0, Newsize: 0
CHECK > Outsize: 0, Newsize: 9
CHECK > Outsize: 9, Newsize: 9
The file size does not stabilise because of how pdf compresses (the digits). As soon as you enter a new file size (with different digits), it compresses differently when converted to pdf.
For example, this code:
\documentclass{article}
\begin{document}
1234
\end{document}
and this code:
\documentclass{article}
\begin{document}
4321
\end{document}
will produce files of equal size but this code:
\documentclass{article}
\begin{document}
1235
\end{document}
will produce a pdf file of a different size. So when you insert this new size into the document, just because the digits are different from the last time, it will produce a pdf file of a different size. However, you might find that after a number of iterations, the pdf file size appears to cycle through the same numbers.