我需要通过某个页面的绝对页码获取该页面的逻辑编号。
例如在一个有 9 页的文档中,其逻辑页码如下:I II 1 2 3 4 A B C
,在第五页的部分,使用\getlogicalpn{7}
将获得第七页的逻辑页码—— A
。
我的解决方案是:先构造一个所有页面的keyval list
(\pagelist
代码中),key表示绝对页码,value表示对应的逻辑页码,然后\pagelist
通过key查询得到value。
我的尝试失败了。请参见以下代码中的注释。对此还有更好的想法吗?
代碼:
\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}
答案1
如果你坚持的话,它就在这儿。
关键是直到发货时才知道这些信息,因此您需要将信息写入辅助文件,然后在下一次编译过程中读取它。
%! 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}
也许使用zref
会更容易。例如https://tex.stackexchange.com/a/4258/250119