0

I need to obtain the logical number of a certain page by its absolute page number.

For example, in a document with 9 pages whose logical page numbers like this: I II 1 2 3 4 A B C, At the the part of the fifth page, using of \getlogicalpn{7} will get the logical number of the seventh page -- A.

My solution is: construct a keyval list(\pagelist in codes) of all pages first. Key denotes to the absolute page number, value is the related logical page number. Then consult \pagelist by a key to get its value.

My try fails. Please see the comments in the following codes. Any better ideas about this?

Codes:

\documentclass{article}
\usepackage{geometry,fancyhdr}
\pagestyle{fancy}\fancyhf{}

\ExplSyntaxOn % obtain the page-list \prop_new:N \pagelist \AddToHook{shipout/after}{ \prop_gput:Nxx \pagelist {\the\ReadonlyShipoutCounter} {\thepage} }

% defination of \getlogicalpn \NewExpandableDocumentCommand{\getlogicalpn}{m}{ \prop_get:NnN \pagelist {#1} _temp _temp } \ExplSyntaxOff

\lhead{absPage: \the\numexpr\ReadonlyShipoutCounter+1\relax} \chead{Logical Page: \thepage} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document} \tableofcontents \pagenumbering{Roman}%----------------- \section{S1} first page\par \clearpage \section{S2} sencond page\par \clearpage \pagenumbering{arabic}%---------------- \section{S3} third page\par \clearpage \section{S4} fourth page\par \clearpage \section{S5} fifth page\par

% Test if the logical page number can be aquired in advance. \ExplSyntaxOn pagelist~is:~|\meaning\pagelist|\par \prop_get:NnNTF \pagelist{7} _temp {_temp}{no~such~key}\par \ExplSyntaxOff

%Typeset of "A" is wanted, but this causes codes fail to compile. \getlogicalpn{7}

% Test if the macro is expandable. % Typeset of \rule{1in}{5pt} is wanted. % It fails. How to make it work? \rule{\getlogicalpn{3} in}{5pt} \clearpage \section{S6} sixth page\par \clearpage \pagenumbering{Alph}%------------------ \section{S7} seventh page\par \clearpage \section{S8} eighth page\par \clearpage \section{S9} nineth page\par \end{document}

lyl
  • 2,727
  • Why not just use \label and \pageref? – Werner Oct 20 '22 at 06:57
  • @ Werner ♦ I need \getlogicalpn being used anywhere for any page, and it should be expandable. – lyl Oct 20 '22 at 07:04
  • Are you really sure you want to specify the absolute page number, given that if you shift the content around the target will change? If you do, why don't you just hard code the values (I, II etc.) directly into the document? – user202729 Oct 20 '22 at 09:59
  • Possible duplicate of https://tex.stackexchange.com/questions/659781/how-to-get-the-physical-absolute-page-number – John Kormylo Oct 20 '22 at 15:27
  • @user202729 I have no idea how to forsee the pagenumbering format(Arabic, Roman, Alph...etc) of a latter page. This is the reason why I post this question. Would you say more about hard code the values (I, II etc.)? – lyl Oct 21 '22 at 03:12

1 Answers1

1

Here it is, if you insist.

The key is that the information is not known until shipout time, therefore you need to write the information to the aux file then read it in the next compilation pass.

%! TEX program = lualatex
\documentclass{article}
\usepackage{geometry,fancyhdr}
\errorcontextlines=100
\pagestyle{fancy}\fancyhf{}

\ExplSyntaxOn \makeatletter \prop_new:N \pagelist \cs_new_protected:Npn\addpagelist #1 #2 { \prop_gput:Nnn\pagelist {#1}{#2} } % we could also write this which is actually slightly faster but I put explicit argument for clarity %\cs_new_protected:Npn\addpagelist
%{ % \prop_gput:Nnn\pagelist
%} \write@mainaux{\unexpanded{\providecommand\addpagelist[2]{}}} % later if you remove this block of code you don't get error, it just silently do nothing \AddToHook{shipout/after}{ % https://tex.stackexchange.com/questions/10919/what-is-the-basic-mechanism-for-writing-something-to-an-aux-file \write@mainaux{\addpagelist{\the\ReadonlyShipoutCounter}{\thepage}} }

% defination of \getlogicalpn \NewExpandableDocumentCommand{\getlogicalpn}{m}{ \prop_item:Nn \pagelist {#1} } \makeatother \ExplSyntaxOff

\lhead{absPage: \the\numexpr\ReadonlyShipoutCounter+1\relax} \chead{Logical Page: \thepage} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document} \tableofcontents \pagenumbering{Roman}%----------------- \section{S1} first page\par \clearpage \section{S2} sencond page\par \clearpage \pagenumbering{arabic}%---------------- \section{S3} third page\par \clearpage \section{S4} fourth page\par \clearpage \section{S5} fifth page\par

% Test if the logical page number can be aquired in advance. \ExplSyntaxOn pagelist~is:~|\meaning\pagelist|\par \prop_get:NnNTF \pagelist{7} _temp {_temp}{no~such~key}\par \ExplSyntaxOff

%Typeset of "A" is wanted, but this causes codes fail to compile. \getlogicalpn{7}

% Test if the macro is expandable. % Typeset of \rule{1in}{5pt} is wanted. % It fails. How to make it work? \rule{\getlogicalpn{3} in}{5pt}

\rule{1 in}{5pt} \clearpage \section{S6} sixth page\par \clearpage \pagenumbering{Alph}%------------------ \section{S7} seventh page\par \clearpage \section{S8} eighth page\par \clearpage \section{S9} nineth page\par \end{document}

Maybe using zref would be easier. e.g. https://tex.stackexchange.com/a/4258/250119

user202729
  • 7,143