Algorithmicx:使用标志控制块开头的换行符

Algorithmicx:使用标志控制块开头的换行符

我定义了规则来自动生成 Isabelle 中 algpseudocode 的 latex。algospeudocode 包对于我想要做的事情来说非常有效,但我希望能够控制新块前面的换行。我开发的自动生成 latex 的机制在冗余的地方发出了 的条件版本\State,我称之为\ConditionalState。此命令定义如下:

\newif\ifjustaddnewline
\justaddnewlinefalse

\newcommand{\ConditionalState}{%
\ifjustaddnewline%
\else%
  \State%
  \justaddnewlinetrue%
\fi}%

的目的 \ConditionalState是避免连续换行。这正是我在这个例子中想要避免的。\ConditionalState在生成的乳胶中的位置是自动的。我编写了一组规则,用于生成使用 Isabelle 中形式化的 BNF 描述的程序的乳胶表示。以下是导致我想要展示的问题的规则子集:

  1. 刚打开算法块,就\ConditionalState发出了;
  2. 打开任意编程块后,\ConditionalState都会发出一个;
  3. 二进制命令(例如顺序组合)有两种形式:
    • 第一个将 a\ConditionalState放在逗号后面,并递归翻译左右分支;
    • 第二种方法不在\ConditionalState中缀符号后面放置 a ,而是递归地翻译分支;
  4. 语法的终端节点无需额外包装即可输出到 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}

相关内容