3

I defined rules to automatically generate latex for algpseudocode from Isabelle. The package algospeudocode works quite well for what I want to do, but I would like to be able to control the break of line preceding new blocks. The mechanism I develop to automatically generate latex issues a conditonal version of the \State, which I call \ConditionalState, in redundant places. This command is defined as follows:

\newif\ifjustaddnewline
\justaddnewlinefalse

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

The purpose of \ConditionalState is to avoid line breaks in a row. This is exactly what I want to avoid in this example. The placement of \ConditionalState in the generated latex is automatic. I encoded a set of rules for generating the latex representation of programs described using a BNF formalised in Isabelle. Here is the subset of rules which lead to the issue I want to show:

  1. Just after opening the algorithmic block, a \ConditionalState is issued;
  2. After opening any programming block, a \ConditionalState is issued;
  3. Binary commands, such as sequential composition, come in two flavours:
    • The first places a \ConditionalState just after the comma, and recursively translates the left and right branch;
    • The second doesn't place a \ConditionalState after the infix symbol, it just recursively translates the branches;
  4. Terminal nodes of the grammar are output to latex without additional wrapping;

These rules try to guess the right moment of issuing a ConditionalState. For example, consider that assignment is a terminal, and it is nested in a while. These rules add automatically an extra line for assignments when the while opens. Because assignment itself does not issue a preceding ConditionalState, the user can choose one of the two "flavours" of sequential composition: assign_left ;c assign_right generates a latex snippet where both assignments are in a single line, while assign_left ;n assign_right will generate a snippet where each assignment appears in a different line. The decorations "c" and "n" in the sequential composition (;) are used to distinguish between the two optional formatting preferences. In fact these are aliases for the same operation.

The problem in this approach is that two nested blocks have a empty line between them. This occurs because the first block adds a \ConditionalState just after the begin of its scope, and the next block implicetely adds a new line before printing the name of the block.

The following MWE shows a illustration of a snippet generated by this method, cleaned to remove unnecessary stuff.

\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}

This latex above (with some cleaning) is automatically generated from the following source:

enter image description here

What I want is a way of controlling the \While block by setting a flag, say, justaddnewline. If justaddnewline is true, then the \While block should not enter a new line before showing the name while. On the other hand, if this flag is false, then the \While block should break the line before printing while. I believe this modification would be in the package algoritmicx.sty, which I found a bit difficult to understand (I am just an average user of latex).

The next picture shows the output I want to obtain, giving the same input as before:

enter image description here

Note that the command ConditionalState between the while loops already ensure that the flag justaddnewline will be true before the start of the new \While block.

Thank you very much! :-)

0

1 Answer 1

2

You can peek ahead and see whether a \While immediately follows a \ConditionalState by using \@ifnextchar:

enter image description here

\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}
1
  • Thanks for the quick reply Werner! It works exactly as expected and also helped me to discover the \@ifnextchar, which can be useful in future! Thanks!
    – Diego Dias
    Commented Oct 7, 2016 at 11:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .