这是讨论的后续内容这里。Andrew 针对页码过大导致的问题提供了一个补丁(请参阅链接问题中他和 Ulrike 的回答)。
然而,即使有了他的补丁(包含在下面的 MWE 中),我现在又遇到了“尺寸太大”的问题,这次肯定不是由页面数量引起的,而是由 tikzmarks 的数量引起的(或者我推测是这样的)。它只在第二次运行时失败,所以它可能与值更改有关。
我还观察到,当我以较少的迭代次数运行一次,然后继续缓慢增加次数时,它根本不会失败(除非我删除辅助文件),我甚至可以一直运行到超出 TeX 容量为止。所以这似乎与重新运行它有关,但我没有任何线索。
% !TEX TS-program = xelatexmk
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
% Fix for error when pagenumber too large,
% from: https://tex.stackexchange.com/questions/484980/dimension-too-large-error-with-tikz-graphic-using-tikzmark-when-document-gets
\makeatletter
\tikzdeclarecoordinatesystem{pic}{%
\pgfutil@in@,{#1}%
\ifpgfutil@in@%
\tmk@labeldef#1\@nil
\else
\tmk@labeldef#1,(0pt,0pt)\@nil
\fi
\@ifundefined{save@pt@\tmk@label}{%
\tikz@scan@one@point\pgfutil@firstofone\tmk@def
}{%
\pgfsys@getposition{\csname save@pt@\tmk@label\endcsname}%
\save@orig@pic%
\pgfsys@getposition{\pgfpictureid}\save@this@pic%
\pgf@process{\pgfpointorigin\save@this@pic}%
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@process{\pgfpointorigin\save@orig@pic}%
\advance\pgf@x by -\pgf@xa
\advance\pgf@y by -\pgf@ya
\pgf@xa=\pgf@x
\pgf@ya=\pgf@y
\pgf@process%
{\pgfpointorigin\csname save@pt@\tmk@label @offset\endcsname}%
\advance\pgf@xa by \pgf@x
\advance\pgf@ya by \pgf@y
\@ifundefined{save@pg@\csname save@pt@\tmk@label\endcsname}{}{%
\@ifundefined{save@pg@\pgfpictureid}{}{%
\pgfkeysvalueof{/tikz/next page vector}%
\edef\tmk@pg{\the\numexpr \csname save@pg@\csname save@pt@\tmk@label\endcsname\endcsname - \csname save@pg@\pgfpictureid\endcsname\relax}%
\advance \pgf@xa by %
\tmk@pg\pgf@x\relax
\advance \pgf@ya by %
\tmk@pg\pgf@y\relax
}%
}%
\pgf@x=\pgf@xa
\pgf@y=\pgf@ya
\pgftransforminvert
\pgf@pos@transform{\pgf@x}{\pgf@y}%
}%
}
\makeatother
\tikzset{
next page=below,
brace/.style n args={2}{insert path={%
([xshift=0.15em,yshift=0.1pt+.5ex]#1) --
([xshift=-0.3pt,yshift=0.1pt+.5ex]#1) --
([xshift=-0.3pt,yshift=-0.1pt+.5ex]#2) --
([xshift=0.15em,yshift=-0.1pt+.5ex]#2) --
([xshift=0.15em,yshift=0.1pt+.5ex]#2) --
([xshift=0.3pt,yshift=0.1pt+.5ex]#2) --
([xshift=0.3pt,yshift=-0.1pt+.5ex]#1) --
([xshift=0.15em,yshift=-0.1pt+.5ex]#1) --
cycle}}}
% Setup for regular brackets:
\newcounter{tikzmkcnt}\setcounter{tikzmkcnt}{0} % counter to automatically set tikzmarks
\newif\iffirstmark
\newcommand{\bracketstart}{%
\stepcounter{tikzmkcnt}%
\tikzmark{a\thetikzmkcnt}%
\global\firstmarktrue
\iftikzmarkoncurrentpage{b\thetikzmkcnt}%
\else
\begin{tikzpicture}[remember picture,overlay,next page=below]%
% \clip (current page text area.south west) rectangle (current page text area.north east);
\fill[overlay,brace={pic cs:a\thetikzmkcnt}{pic cs:b\thetikzmkcnt}];
\end{tikzpicture}%
\fi
}
\newcommand{\bracketend}{%
\iffirstmark
\tikzmark{b\thetikzmkcnt}%
\global\firstmarkfalse
\fi
\begin{tikzpicture}[remember picture,overlay]%
% \clip (current page text area.south west) rectangle (current page text area.north east);
\fill[overlay,brace={pic cs:a\thetikzmkcnt}{0,0}];
\end{tikzpicture}%
}
%% First I thought it had to do with some weird interaction with zref as it was part of this code:
%\RequirePackage[user,savepos]{zref}
%\newcommand{\offset}[1]{ % setting offset
%\dimexpr\zposx{#1}sp-(\oddsidemargin+1in)\relax}
%\newcommand{\offsetmk}[1]{\leavevmode\zsaveposx{#1}} % defining offset point
%\newcounter{offsetmkcnt}\setcounter{offsetmkcnt}{0} % counter for automatic marks
%\newcommand{\onsetmark}{\bracketstart\stepcounter{offsetmkcnt}\offsetmk{\theoffsetmkcnt}\hspace{.15em}}
%\newcommand{\offsetline}{\hspace{\dimexpr\offset{\theoffsetmkcnt}\relax}\bracketend\hspace{.15em}}
%
%\newcommand{\Zftest}{test \onsetmark{}test\par \offsetline{}test \onsetmark{}test\par \offsetline{}test \par}
%\newcommand{\Tentests}{\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest\Zftest}
%% But then I realized that even this one produces the error:
\newcommand{\Tktest}{test \bracketstart{}test\par test \bracketend{}test \bracketstart{}test \par test test \bracketend{}test \par}
\newcommand{\Tentests}{\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest}
\newcommand{\Hundredtests}{\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests}
\parindent0pt
\begin{document}
%\Zftest
%\Tktest
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\end{document}
答案1
(我对这份文件非常好奇……)
这是一个更紧凑的 MWE:
% !TEX TS-program = xelatexmk
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\tikzset{
next page=below,
}
% Setup for regular brackets:
\newcounter{tikzmkcnt}\setcounter{tikzmkcnt}{0} % counter to automatically set tikzmarks
\newif\iffirstmark
\newcommand{\dotikzmark}{%
\stepcounter{tikzmkcnt}%
\tikzmark{a\thetikzmkcnt}%
TikZMark \thetikzmkcnt%
\newpage
\tikzmark{b\thetikzmkcnt}%
\tikz[remember picture, overlay] {\draw (pic cs:b\thetikzmkcnt) -- (pic cs:a\thetikzmkcnt);}
}
%% But then I realized that even this one produces the error:
\newcommand{\Tktest}{\dotikzmark}
\newcommand{\Tentests}{\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest\Tktest}
\newcommand{\Hundredtests}{\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests\Tentests}
\parindent0pt
\begin{document}
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\Hundredtests\Hundredtests\Hundredtests\Hundredtests\Hundredtests
\end{document}
问题是,当 tikzmark 位于不同的页面上时,软件包会尝试通过想象按照规范布局的页面next page
并计算正确的位移来将其放置在“正确”的位置。您面临的问题是,由于我稍后会解释的原因,当前页面和 tikzmark 页面相距很远,位移超出了尺寸限制。
我提出的解决办法是不要再这么聪明了。如果 tikzmark 在前面一页,它现在会像在即时下一页。我认为不这样做真的没有什么好处。这就是完美是优秀的敌人。
这是在最新版本中实现的在 github 上。
tikzmark 认为当前页面和 tikzmark 页面之间存在巨大差异的原因是,它通过将数据链接到图片 ID(用于计数文档中的图片)来跟踪信息。更改文档中的 tikz 图片数量意味着 tikzmarks 可能与错误的图片相关联(直到完成新运行并再次同步),因此页码将被错误计算(并且在您的情况下,变得非常大)。
一旦文档稳定下来,您的 tikzmarks 就会与正确的页面相关联,这就是为什么即使没有修复,错误也会在第二次运行时消失。