Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

This is an example of what I want to do:

  1. After a run of pdflatex, calculate and store (into an auxiliary file?) the size of the resulting PDF file, as obtained from the Terminal command "du -h file.pdf", e.g. "50K". (This is just an example. It could be any other Terminal command not relating to the filesize.)

  2. On the next run, typeset the stored text at a specific place on every page of the document, at a given inches to the top and right of the bottom-left point of the page.

How can this be done?

share|improve this question
    
Duplicate of this question –  Juri Robl Aug 28 '12 at 8:50
    
@JuriRobl No, it isn't, because I'm not specifically asking for a size of a file (that was just an example that I, for better or worse, ended up choosing). It might as well be any other Terminal command, such as hash calculation, or a date, or whatever. –  MayGodBlessKnuth Aug 28 '12 at 8:51
    
Sorry then. Can't you just store it as a gdef in the aux file? Or do you want a complete LaTeX solution? –  Juri Robl Aug 28 '12 at 9:04
    
@MayGodBlessKnuth Perhaps consider editing the title and lead-in hereto make it clear that this is not a duplicate of the linked question. –  Joseph Wright Aug 29 '12 at 7:42

2 Answers 2

up vote 10 down vote accepted

Since pdfTeX 1.30.0 the expandable command \pdffilesize is available. Because the output file of the previous run will gets overwritten, the size should be asked as early as possible:

\edef\jobsize{\pdffilesize{\jobname.pdf}}
\documentclass{article}
\begin{document}
  The file size is \jobsize~(\the\numexpr(\jobsize+512)/1024\relax~KB).
\end{document}

Example output

However the printed file size will be part of the page. Thus the new output file will probably have a different file size. The file size depends on the included digits that are used in \jobname. If all digits are included anyway, then this does not matter. However the page stream changes that is usually compressed. Therefore it is quite possible that the file size will never match the actual file size regardless the number of reruns. Therefore rounding is a good idea.

Further remarks:

  • LuaTeX can also be supported:

    \RequirePackage{pdftexcmds}
    \makeatletter
    \edef\jobsize{\pdf@filesize{\jobname.pdf}}
    \makeatother
    
  • If the file does not exist yet, then \pdffilesize or \pdf@filesize expands to the empty string, example:

    \ifx\jobsize\empty
      \textbf{??}%
    \else
      \jobsize
    \fi
    
  • The size can also put in a reference to get warned by LaTeX because of changed references. But this might not be the best idea, because the size might never stabilize, see above.

Update

Some tricks allow the stabilizing of the file size:

  • Include all digits (\pdfincludechars), even if some are not used. Then the font size remains the same.

  • Use of a "form xobject" (a PDF terminus for reused material, similar to save boxes in (La)TeX. Then the page streams remain constant. Only the stream of the xobject varies. The randomized effect of compression can be eliminated by turning the compression off for this object.

It remains the xobject stream that varies with the file size. But the file size is stabilized so far that adding the file size in a reference in the .aux file can be tried to get rerun warnings.

The following example also uses siunitx for formatting the file size and puts the file size at a fixed location in the page as requested in the question. Package atbegshi is used for that purpose.

\RequirePackage{pdftexcmds}% support LuaTeX
\makeatletter
\edef\jobsize{\pdf@filesize{\jobname.pdf}}
\makeatother

\documentclass{article}

\usepackage{siunitx}
\DeclareBinaryPrefix{\kibi}{Ki}{10}
\DeclareBinaryPrefix{\mebi}{Mi}{20}
\DeclareBinaryPrefix{\gibi}{Gi}{30}
\DeclareSIUnit\byte{B}

\makeatletter
\newcommand*{\printjobsize}{%
  \@ifundefined{xform@jobsize}{%
    \begingroup
      \sbox0{%
        \sisetup{detect-mode=false,mode=text}%
        \pdfincludechars\font{0123456789 ()}%
        \pdfincludechars\font{\si{\kibi\byte}\si{\mebi\byte}\si{\gibi\byte}}%
        \ifx\jobsize\@empty
          \textbf{??}%
        \else
          \expandafter\num\expandafter{\jobsize}~bytes (%
          \ifnum\numexpr(\jobsize+512)/1024\relax<10 %
          \else
            \ifnum\numexpr(\jobsize+524288)/1048576\relax<10 %
              \expandafter\SI\expandafter{\the\numexpr(\jobsize+512)/1024\relax
            \else
              \ifnum\numexpr(\jobsize+536870912)/1073741824\relax<10 %
                \expandafter\SI\expandafter{\the\numexpr(\jobsize+524288)/10485
              \else
                \expandafter\SI\expandafter{\the\numexpr(\jobsize+536870912)/10
              \fi
            \fi
            )%
          \fi
        \fi
      }%
      \pdfcompresslevel=0\relax
      \immediate\pdfxform0\relax
      \xdef\xform@jobsize{\the\pdflastxform}%
    \endgroup
  }{}%
  \pdfrefxform\xform@jobsize\relax
}
% Adding the file size as reference of the new reference class "jobsize"
% in the ".aux" file.
\newcommand*{\newjobsize}{\@newl@bel{jobsize}{jobsize}}
\AtBeginDocument{%
  \if@filesw
    \immediate\write\@mainaux{\string\providecommand\string\newjobsize[1]{}}%
    \immediate\write\@mainaux{\string\newjobsize{\jobsize}}%
  \fi
}
\makeatother

% Put the file size 10mm from the left margin and 10mm from the bottom
\usepackage{atbegshi}
\usepackage{picture}
\AtBeginShipout{%
  \AtBeginShipoutUpperLeft{%
    \put(10mm,\dimexpr-\paperheight+10mm\relax){% 
      \makebox(0,0)[lb]{File size: \printjobsize}%
    }%
  }%  
}

\usepackage{lipsum}

\begin{document}  
  \tableofcontents
  \section{Hello World}
  \lipsum[1-10]
\end{document}

First page with file size

share|improve this answer
    
Do you know how the text could be horizontally centered at the bottom of the page instead? (With the vertical distance from the bottom remaining the same.) –  MayGodBlessKnuth Aug 29 '12 at 12:21
    
\put(.5\paperwidth,...){\makebox(0,0)[b]{...}} should do it. –  Heiko Oberdiek Aug 29 '12 at 15:16

You can take the approach of the vc bundle to do this sort of thing. The basic idea is to use \write18 to call a shell script which writes the relevant macro definitions to a file which can then be used. Here's an example for getting the word count in your document.

First your tex document should look like this:

\documentclass{article}

\immediate\write18{./wc foo.tex}
\input{wc}
\begin{document}
Foo and things

Words in text: \texcount

\end{document}

And your wc file should look like this:

#!/bin/sh
# This is the 'wc' file inspired by 'vc' available on CTAN

texcount $1 | awk '/Words in text/ {print "\\gdef\\texcount{" $4 "}"}' > wc.tex

For this to work you'll need to add ./wc to your shell_escape_commands list in your texmf.cnf and make the file executable.

Now, every time you run latex on the file, it will call ./wc on the file foo.tex which will word count the file and extract the relevant information from it and make it accessible with the \texcount macro which is in the inputted wc.tex file. You can then use fanchdr or some other such package to put the info where you like.


I'm pretty sure this isn't the simplest or most robust way to get the right info out of textcount, but this is the method that the original vc bundle uses for getting stuff out of git and I was slavishly copying that…

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.