Page Numbering – Getting the Absolute Page Number with Zref and LaTeX3 for Accurate Referencing

expansionlatex3page-numberingzref

Within a larger project, I want to set a string equal to the current absolute page number, like this

\documentclass[10pt]{article}

\usepackage{zref-abspage}
\usepackage{zref-user}

\ExplSyntaxOn

\NewDocumentEnvironment{intfig} { > { \SplitArgument { 1 } { , } } m!o }
{
  % Apparently, this is required because the page number isn't fixed until shipout.
  \zlabel{ randomname }

  % Error: "\zref doesn't match its definition."
  \str_set:Nx \l_intfig_filespec_str { \zref[abspage]{ randomname } }

  % This works as expected.
  \zref[abspage]{ randomname }
}{ }

\ExplSyntaxOff

\begin{document}
\begin{intfig}{bogus}
\end{intfig}
\end{document}

There is something going here, probably having to do with expansion, that I can't figure out. On that subject, maybe someone knows of a document that's more expository than the interface3 document, which is cryptic when you're starting out.

If it matters, in the actual code, the randomname used above will be a string too, like \l_intfig_figname_str. I wanted to keep the example minimal.

Best Answer

You need to use the expandable version of \zref, in this case \zref@extractdefault.

\documentclass[10pt]{article}
\usepackage[papersize={4cm,6cm},margin=1cm,bottom=2cm]{geometry}

\usepackage{zref-abspage}
\usepackage{zref-user}

\ExplSyntaxOn

\int_new:N \g__intfig_unique_int

\NewDocumentEnvironment{intfig} { > { \SplitArgument { 1 } { , } } m!o }
 {
  \int_gincr:N \g__intfig_unique_int
  \zlabel{ intfig-\int_to_arabic:n { \g__intfig_unique_int } }
  \str_set:Nx \l_intfig_filespec_str
   {
    \use:c { zref@extractdefault } { intfig-\int_to_arabic:n { \g__intfig_unique_int } } { abspage } { 0 }
   }
  \str_use:N \l_intfig_filespec_str
}{ }

\ExplSyntaxOff

\begin{document}
\begin{intfig}{bogus}
  Text
\end{intfig}

\clearpage
\pagenumbering{Roman}

\begin{intfig}{bogus}
  Text
\end{intfig}

\end{document}

The geometry package is just to make a smaller picture.

The integer variable is used to provide a unique label to every call of the environment.

enter image description here

Related Question