我对 LaTeX 中的回滚机制有点困惑。我想让用户测试我的包未来的重大更改,同时我也想将未来的更改保留在同一个包文件中。所以我尝试了以下演示文件:
\begin{filecontents*}[force]{demo.sty}
\NeedsTeXFormat{LaTeX2e}[2018-04-01]
\DeclareRelease{v2026}{2026-01-01}{demo.sty}
\DeclareCurrentRelease{}{2022-01-01}
\IfTargetDateBefore{2026-01-01}{\newcommand\test{old}}{\newcommand\test{new}}
\end{filecontents*}
\documentclass{article}
%\usepackage{demo}[=v2026] % the result is "new" even if I write \IfTargetDateBefore{2027-01-01}
%\usepackage{demo}[=2026-01-01] % the result is "new"
%\usepackage{demo} % the result is "new" but I expect it would be "old"
%\usepackage{demo}[=2022-01-01] % ! LaTeX Error: Suspicious rollback date given.
\begin{document}
\test
\end{document}
问题是:
\DeclareRelease
(1)使用相同的包文件是否正确\DeclareCurrentRelease
?
(2)为什么不使用和\IfTargetDateBefore
中的日期作为目标日期?\DeclareRelease
\DeclareCurrentRelease
(3)对于\DeclareRelease
,我在宣布释放时已给出了 和name
,date
但奇怪的是\usepackage{demo}[=<name>]
和\usepackage{demo}[=<date>]
仍然表现不同。
[更新]根据 Frank Mittelbach 的回答,我还有另一个问题:
(4) 对于此用例,在后面提供\DeclareFutureRelease{<name>}{<date>}
命令是个好主意吗\DeclareCurrentRelease
?此命令不包含参数<file>
,它仅将 映射到<name>
以便<date>
可以\IfTargetDateBefore
使用它。一般来说,<name>
诸如 比诸如beta
更容易记住。<date>
2026-01-01
答案1
LaTeX 中的回滚机制是一种轻量级的“回滚”机制,而不是前滚机制,尽管它确实以有限的受限方式支持前滚。
特别是,它只适用于明确要求按日期回滚的情况,但确实如此不是如果没有,则执行任何操作,如果您对命名版本有请求,那么它只会跳转到该版本,并且再次不查看日期。
此外,所有发布日期必须(如记录所示)按递增顺序排列,例如,您不能将当前发布日期设为 2022 年,而将上一版本设为 2026 年。请参阅 https://www.latex-project.org/publications/2018-FMi-TUB-tb122mitt-version-rollback.pdf。
我稍微扩充了你的例子并对案例进行了评论,希望有所帮助。
该机制支持“未来版本”的唯一形式是只给它们一个名称而不给日期,然后告诉您的用户试用“v2023-beta”,而这样的文件里面 \IfTargetDateBefore
没有任何效果。
\begin{filecontents}[force]{demo.sty}
\NeedsTeXFormat{LaTeX2e}[2018-04-01]
\DeclareRelease{v2025}{2025-01-01}{demo0.sty}
\DeclareRelease{v2026}{2026-01-01}{demo.sty}
\DeclareRelease{v2027}{2027-01-01}{demo2.sty}
\DeclareCurrentRelease{}{2022-01-01}
\typeout{testing for \pkgcls@innerdate}
\IfTargetDateBefore{2025-12-31}{\renewcommand\testa{\typeout{testa=old}}}{\renewcommand\testa{\typeout{testa=new}}}
\IfTargetDateBefore{2026-01-01}{\renewcommand\testb{\typeout{testb=old}}}{\renewcommand\testb{\typeout{testb=new}}}
\IfTargetDateBefore{2027-01-01}{\renewcommand\testc{\typeout{testc=old}}}{\renewcommand\testc{\typeout{testc=new}}}
\end{filecontents}
\documentclass{article}
\providecommand\testa{\typeout{testa=unset}}
\providecommand\testb{\typeout{testb=unset}}
\providecommand\testc{\typeout{testc=unset}}
\makeatletter
\let\pkgcls@debug\typeout
\makeatother
\usepackage{demo}[=v2026] % the result is "new" even if I write \IfTargetDateBefore{2027-01-01}
%
% no release date give so \IfTargetDateBefore is always new because the assumption is that the named release contains the current code for that name
%\usepackage{demo}[=2026-01-01] % the result is "new"
%
% this is correct because the new code was at 2026-01-01 and not before
\usepackage{demo} % the result is "new" but I expect it would be "old"
%
% no request for rollback so current file is used with the assumption that everything is "new" any \IfTargetDateBefore contains old code in its first argument.
%\usepackage{demo}[=2022-01-01] % ! LaTeX Error: Suspicious rollback date given.
%
% first dated release is for 2025 so LaTeX complains (because release dates have to be ordered by date).
\begin{document}
\testa \testb \testc
\end{document}
打开内部调试后,你会得到类似
LaTeX Warning: Writing or overwriting file `./demo.sty'.
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/article.cls
Document Class: article 2021/10/04 v1.4n Standard LaTeX document class
(/usr/local/texlive/2022/texmf-dist/tex/latex/base/size10.clo))
--- File loaded request (\usepackage or ...)
1: demo
2:
3: =v2026
4: sty
(./demo.sty
---\DeclareRelease:
1: v2025
2: 2025-01-01
3: demo0.sty
Label doesn't match
---\DeclareRelease:
1: v2026
2: 2026-01-01
3: demo.sty
Result: use demo.sty
(./demo.sty
testing for \maxdimen
Include code introduced on 2025-12-31
Include code introduced on 2026-01-01
Include code introduced on 2027-01-01
))
--- File loaded request (\usepackage or ...)
1: l3backend-pdftex
2:
3:
4: def
(/usr/local/texlive/2022/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def)
(./rollback.aux)
testa=new
testb=new
testc=new
从上面。
回答你帖子结尾的问题:
(1) 只要您不通过随机排列日期来混淆算法,它就会起作用,但这有点毫无意义,因为如果您完全不使用该\DeclareRelease
行就可以达到同样的效果,因为它会下降到当前版本并使用(\IfTargetReleaseBefore
如果要求发布日期)。
(2)因为这将需要更多的测试,从而使得每个包处理速度更慢(坦率地说,因为你的想法没有被视为用例)。
(3)命名和日期发布选择的行为不同,因为“命名”版本假设它指向的文件包含命名版本的“当前”代码,因此\IfTarget...
选择了新的代码分支。