我定义了规则来自动生成 Isabelle 中 algpseudocode 的 latex。algospeudocode 包对于我想要做的事情来说非常有效,但我希望能够控制新块前面的换行。我开发的自动生成 latex 的机制在冗余的地方发出了 的条件版本\State
,我称之为\ConditionalState
。此命令定义如下:
\newif\ifjustaddnewline
\justaddnewlinefalse
\newcommand{\ConditionalState}{%
\ifjustaddnewline%
\else%
\State%
\justaddnewlinetrue%
\fi}%
的目的 \ConditionalState
是避免连续换行。这正是我在这个例子中想要避免的。\ConditionalState
在生成的乳胶中的位置是自动的。我编写了一组规则,用于生成使用 Isabelle 中形式化的 BNF 描述的程序的乳胶表示。以下是导致我想要展示的问题的规则子集:
- 刚打开算法块,就
\ConditionalState
发出了; - 打开任意编程块后,
\ConditionalState
都会发出一个; - 二进制命令(例如顺序组合)有两种形式:
- 第一个将 a
\ConditionalState
放在逗号后面,并递归翻译左右分支; - 第二种方法不在
\ConditionalState
中缀符号后面放置 a ,而是递归地翻译分支;
- 第一个将 a
- 语法的终端节点无需额外包装即可输出到 latex;
这些规则试图猜测发出 的正确时刻ConditionalState
。例如,假设 assignment 是一个终端,并且它嵌套在 while 中。当 while 打开时,这些规则会自动为赋值添加一个额外的行。因为 assignment 本身不会发出前面的ConditionalState
,所以用户可以选择两种顺序组合的“风格”之一:assign_left ;cassign_right 生成一个 latex 片段,其中两个赋值都在一行中,而assign_left ;nassign_right 将生成一个片段,其中每个赋值出现在不同的行中。顺序组合(;)中的装饰“c”和“n”用于区分两个可选的格式首选项。事实上,这些是同一操作的别名。
这种方法的问题是两个嵌套块之间有一个空行。出现这种情况的原因是第一个块\ConditionalState
在其范围的开始后立即添加了一个,而下一个块在打印块名称之前隐式地添加了一个新行。
下面的 MWE 展示了通过此方法生成的代码片段,清理后删除了不必要的内容。
\documentclass{article}
\usepackage{algorithm}
\usepackage{algpseudocode}
\begin{document}
\justaddnewlinefalse
\begin{algorithm}\caption{Hello Stack Tex Exhange!!}
\begin{algorithmic}[1]
\ConditionalState x:=1\justaddnewlinefalse;
\ConditionalState x:=2\justaddnewlinefalse;
\While{\textit{true}}\justaddnewlinefalse
\ConditionalState
\While{\textit{true}}\justaddnewlinefalse
\ConditionalState x:=3\justaddnewlinefalse;
\ConditionalState x:=4\justaddnewlinefalse
\EndWhile\justaddnewlinefalse
\EndWhile\justaddnewlinefalse
\end{algorithmic}
\end{algorithm}
\end{document}
上面的乳胶(经过一些清理)是从以下来源自动生成的:
我想要的是一种通过设置标志来控制 \While 块的方法,例如 justaddnewline
。如果justaddnewline
为真,则 \While 块在显示名称之前不应输入新行尽管。另一方面,如果此标志为假,则 \While 块应在打印之前断行尽管我相信这个修改会在包 algoritmicx.sty 中,我发现这有点难以理解(我只是一个普通的 latex 用户)。
下图显示了我想要获得的输出,提供与之前相同的输入:
请注意,while 循环之间的命令已经确保在新的 \While 块开始之前ConditionalState
标志为真。justaddnewline
非常感谢! :-)
答案1
你可以提前看看\While
立即地通过\ConditionalState
使用\@ifnextchar
:
\documentclass{article}
\usepackage{algorithm,algpseudocode}
\newif\ifjustaddnewline
\justaddnewlinefalse
\makeatletter
\newcommand{\ConditionalState}{%
% Check to see if \While immediately follows \ConditionalState...
\@ifnextchar\While{}{%
% ... if not...
\ifjustaddnewline%
\else%
\State%
\justaddnewlinetrue%
\fi}}%
\makeatother
\begin{document}
\justaddnewlinefalse
\begin{algorithm}\caption{Hello \TeX{} Stack Exhange!}
\begin{algorithmic}[1]
\ConditionalState x:=1\justaddnewlinefalse;
\ConditionalState x:=2\justaddnewlinefalse;
\While{\textit{true}}\justaddnewlinefalse
\ConditionalState
\While{\textit{true}}\justaddnewlinefalse
\ConditionalState x:=3\justaddnewlinefalse;
\ConditionalState x:=4\justaddnewlinefalse
\EndWhile\justaddnewlinefalse
\EndWhile\justaddnewlinefalse
\end{algorithmic}
\end{algorithm}
\end{document}