延续邮政,我尝试使以下(简化的)代码正常工作。
- \timedelta 使用 2 个参数。
- 使用 \gdef 作为第一个参数是可以的。
- 使用 \gdef 作为第二个参数是 Nok。
我无法摆脱例外
21:段落在 \timedelta@i 完成之前结束。[]
\documentclass{article}
\makeatletter
\newcommand{\timedelta}[2]{\romannumeral0\timedelta@i#1:#2:}%
\def\timedelta@i #1:#2:#3:#4:%
{\expandafter\timedelta@ii\the\numexpr#3*60+#4-#1*60-#2.}%
\def\timedelta@ii#1{\expandafter\timedelta@iii\the\numexpr
\if-#11440\fi #1}%
\def\timedelta@iii#1.{\expandafter\timedelta@iv\the\numexpr
(#1 + 30)/60 -1.#1.}%
\def\timedelta@iv #1.#2.{\expandafter\timedelta@v\the\numexpr
100+#2-60*#1\expandafter.\the\numexpr100+#1.}
\def\timedelta@v 1#1.1#2.{ #2:#1}
\makeatother
\begin{document}
\gdef\routeStart{01:27}
\expandafter\timedelta\expandafter{\routeStart}{01:27}% ok
\gdef\routeStop{01:27}
\expandafter\timedelta{16:03}\expandafter{\routeStop}% nok -> Paragraph ended before \timedelta@i was complete.
\end{document}
我对第一个答案的编辑
如何“扩展”这两个论点?谢谢!
\timedelta{\routeStart}{\routeStop}
答案1
这可能会有所帮助:
\documentclass{article}
\makeatletter
\newcommand{\timedelta}[2]{\romannumeral0\timedelta@i#1:#2:}%
\def\timedelta@i #1:#2:#3:#4:%
{\expandafter\timedelta@ii\the\numexpr#3*60+#4-#1*60-#2.}%
\def\timedelta@ii#1{\expandafter\timedelta@iii\the\numexpr
\if-#11440\fi #1}%
\def\timedelta@iii#1.{\expandafter\timedelta@iv\the\numexpr
(#1 + 30)/60 -1.#1.}%
\def\timedelta@iv #1.#2.{\expandafter\timedelta@v\the\numexpr
100+#2-60*#1\expandafter.\the\numexpr100+#1.}
\def\timedelta@v 1#1.1#2.{ #2:#1}
\makeatother
\newcommand\timeatled[2]{\timedelta{#2}{#1}}
\newcommand\timedeltaON[2]{\expandafter\timedelta\expandafter{#1}{#2}}
\newcommand\timedeltaNO[2]{\expandafter\timeatled\expandafter{#2}{#1}}
\newcommand\timedeltaOO[2]{\expandafter\timedeltaNO\expandafter{#1}{#2}}
\newcommand\timedeltaXN[2]
{\expandafter\timedelta\expandafter{\romannumeral-`0#1}{#2}}
\newcommand\timedeltaNX[2]
{\expandafter\timeatled\expandafter{\romannumeral-`0#2}{#1}}
\newcommand\timedeltaXX[2]
{\expandafter\timedeltaNX\expandafter{\romannumeral-`0#1}{#2}}
\begin{document}
\gdef\routeStart{01:27}
\timedeltaON{\routeStart}{01:27}% ok
\timedeltaOO{\routeStart}{01:27}% ok
\timedeltaXX{\routeStart}{01:27}% ok
\gdef\routeStop{01:27}
\timedeltaNO{16:03}{\routeStop}% ok
\timedeltaOO{16:03}{\routeStop}% ok
\timedeltaXX{16:03}{\routeStop}% ok
\end{document}
LaTeX3 具有“生成变体”通用功能,可以一劳永逸地解决这些问题......
请注意,它\timedeltaXX
可以与自身嵌套(即作为其自身的第一个或第二个参数)。
答案2
您误用了\expandafter
。扩展宏的第二个参数的一种方法是,定义第二个宏,其中包含宏及其第一个参数,然后\expandafter
在执行第二个宏之前使用 s 扩展参数:
\documentclass{article}
\makeatletter
\newcommand{\timedelta}[2]{\romannumeral0\timedelta@i#1:#2:}%
\def\timedelta@i #1:#2:#3:#4:%
{\expandafter\timedelta@ii\the\numexpr#3*60+#4-#1*60-#2.}%
\def\timedelta@ii#1{\expandafter\timedelta@iii\the\numexpr
\if-#11440\fi #1}%
\def\timedelta@iii#1.{\expandafter\timedelta@iv\the\numexpr
(#1 + 30)/60 -1.#1.}%
\def\timedelta@iv #1.#2.{\expandafter\timedelta@v\the\numexpr
100+#2-60*#1\expandafter.\the\numexpr100+#1.}
\def\timedelta@v 1#1.1#2.{ #2:#1}
\makeatother
\begin{document}
\gdef\routeStart{01:27}
\expandafter\timedelta\expandafter{\routeStart}{01:27}% ok
\gdef\routeStop{01:27}
\def\tempmacro{\timedelta{16:03}}%
\expandafter\tempmacro\expandafter{\routeStop}%
%\expandafter\timedelta{16:03}\expandafter{\routeStop}% nok -> Paragraph ended before \timedelta@i was complete.
\end{document}
它\expandafter
的作用是(描述不准确)在第一个标记之前扩展第二个标记(如果它可以扩展)。在您的示例中,第一个参数的每个字符都是一个标记,因此正确的方法是使用 跳过每个字符\expandafter
,因此在这种情况下正确的使用方法\expandafter
是:
\expandafter\timedelta\expandafter{\expandafter1\expandafter6\expandafter:\expandafter0\expandafter3\expandafter}\expandafter{\routeStop}%
这真的很麻烦...