4

I want to write the absolute pagenumber of a reference to a file. therefore i cant use \immediate\write. The problem is now i think that \write expands its parameters when a page is finished, but then i of course get the same counter number for all invocations on that page. There my question is: How do i pass the counter value from the time of the expansion of the command to \write?

    \documentclass{article}
    \usepackage{zref-savepos}
    \usepackage{zref-abspage}
    \usepackage{zref-user}

    \newcounter{acnt}

    \newwrite\tempfile
    \immediate\openout\tempfile=tmp.txt

    \makeatletter
    \newcommand\test{   
        \stepcounter{acnt}
        A \zsavepos{pos\arabic{acnt}}
        \write\tempfile{Nr \arabic{acnt} is on page \zref@extract{pos\arabic{acnt}}{abspage}}   
    }
    \makeatother

    \begin{document}

        \test
        \test
        \newpage
        \test
        \test
        \test

    \end{document}

And the output is:

    Nr 2 is on page 0
    Nr 2 is on page 0
    Nr 5 is on page 0
    Nr 5 is on page 0
    Nr 5 is on page 0

But it should be:

    Nr 1 is on page 1
    Nr 2 is on page 1
    Nr 3 is on page 2
    Nr 4 is on page 2
    Nr 5 is on page 2
3

The label written by \zsavepos only stores the properties posx and posy. Therefore the value for abspos is undefined and the default 0 is used. The reason for this is efficiency. If a label would store each kind of properties (lots of counter values, section titles, ...), the size of the .aux files and the memory imprint would be huge. Therefore zref allows and hopefully encourages label settings with the needed properties only.

Module zref-savepos maintains a property list savepos with properties posx and posy. This list can be extended:

\zref@addprops{savepos}{abspage}% global
\zref@localaddprops{savepos}{abspage}% local

The following example extends the list locally to avoid adding properties for \zsavepos labels, where they are not needed:

\documentclass{article}
\usepackage{zref-savepos}
\usepackage{zref-abspage}
\usepackage{zref-user}

\newcounter{acnt}

\newwrite\tempfile
\immediate\openout\tempfile=tmp.txt

\makeatletter
\newcommand\test{
    \stepcounter{acnt}
    A %
    \begingroup
      \zref@localaddprops{savepos}{abspage}%
      \zsavepos{pos\arabic{acnt}}%
    \endgroup
    \immediate\write\tempfile{%
      Nr \arabic{acnt} is on page
      \zref@extract{pos\arabic{acnt}}{abspage}%
    }%
}
\makeatother

\begin{document}

    \test
    \test
    \newpage
    \test
    \test
    \test

\end{document}

The result tmp.txt:

Nr 1 is on page 1
Nr 2 is on page 1
Nr 3 is on page 2
Nr 4 is on page 2
Nr 5 is on page 2

The example uses \immediate\write, because the test file does not show a reason for a deferred writing. Deferred writing is usually needed, if there are properties like page numbers, which are correct at shipout time. But the write command only writes the current counter value and a reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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