chrmatt / algpseudocodex

LaTeX package for typesetting pseudocode.
38 stars 2 forks source link

Custom algorithm block definitions from algorithmcx do not render properly #3

Open zsusag opened 3 years ago

zsusag commented 3 years ago

Hi!

I'm trying to write an algorithm with custom switch and case statements and in algorithmicx I'm able to write the following using \algdef:

\algnewcommand\algorithmicswitch{\textbf{switch}}
\algnewcommand\algorithmiccase{\textbf{case}}
\algdef{SE}[SWITCH]{Switch}{EndSwitch}[1]{\algorithmicswitch\ #1\ \algorithmicdo}{\algorithmicend\ \algorithmicswitch}%
\algdef{SE}[CASE]{Case}{EndCase}[1]{\algorithmiccase\ #1}{\algorithmicend\ \algorithmiccase}%
\algtext*{EndSwitch}%
\algtext*{EndCase}%

However, when I do so the following code gets rendered as so:

\documentclass[letterpaper,10pt]{article}

\usepackage{algpseudocodex}
\usepackage{algorithm}
\usepackage{tikz}

\algnewcommand\algorithmicswitch{\textbf{switch}}%
\algnewcommand\algorithmiccase{\textbf{case}}%
\algdef{SE}[SWITCH]{Switch}{EndSwitch}[1]{\algorithmicswitch\ #1\ \algorithmicdo}{\algorithmicend\ \algorithmicswitch}%
\algdef{SE}[CASE]{Case}{EndCase}[1]{\algorithmiccase\ #1}{\algorithmicend\ \algorithmiccase}%
\algtext*{EndSwitch}%
\algtext*{EndCase}%

\begin{document}
\begin{algorithm}[H]
  \caption{Test Example}
  \begin{algorithmic}[1]
    \Function{Foo}{x}
    \While{x != 0}
    \State $x = x-1$
    \Switch{x}
    \Case{0}
    \EndCase
    \Case{1}
    \EndCase
    \EndSwitch
    \EndWhile
    \EndFunction
  \end{algorithmic}
\end{algorithm}
\end{document}

2021-06-29-165243_373x234_scrot

Additionally, the document does not compile if I have \State ... in between the the case statements or the switch statements.

Do you have any workarounds for this? Thank you in advance! I'm switching to your package because highlighting code seems to be so much easier! :)

chrmatt commented 3 years ago

Thanks for your interest in the package! The reason you encounter these issues is that the package internally redefines several commands and it is not intended to work with custom \algdef definitions. I should probably add commands for defining custom commands. As a workaround, you can mimic the way commands are defined in the package. For your example, the following works for me:

\documentclass[letterpaper,10pt]{article}

\usepackage{algpseudocodex}
\usepackage{algorithm}
\usepackage{tikz}

\algnewcommand\algorithmicswitch{\textbf{switch}}%
\algnewcommand\algorithmiccase{\textbf{case}}%

\makeatletter
\algdef{SE}[SWITCH]{Switch}{EndSwitch}[1]{\algpx@startIndent\algpx@startCodeCommand\algorithmicswitch\ #1\ \algorithmicdo}{\algpx@endIndent\algpx@startCodeCommand\algorithmicend\ \algorithmicswitch}%
\algdef{SE}[CASE]{Case}{EndCase}[1]{\algpx@startIndent\algpx@startCodeCommand\algorithmiccase\ #1}{\algpx@endIndent\algpx@startCodeCommand\algorithmicend\ \algorithmiccase}%

\ifbool{algpx@noEnd}{%
  \algtext*{EndSwitch}%
  \algtext*{EndCase}%
  %
  % end indent line after (not before), to get correct y position for multiline text in last command
  \apptocmd{\EndSwitch}{\algpx@endIndent}{}{}%
  \apptocmd{\EndCase}{\algpx@endIndent}{}{}%
}{}%

\pretocmd{\Switch}{\algpx@endCodeCommand}{}{}
\pretocmd{\Case}{\algpx@endCodeCommand}{}{}

% for end commands that may not be printed, tell endCodeCommand whether we are using noEnd
\ifbool{algpx@noEnd}{%
  \pretocmd{\EndSwitch}{\algpx@endCodeCommand[1]}{}{}%
  \pretocmd{\EndCase}{\algpx@endCodeCommand[1]}{}{}%
}{%
  \pretocmd{\EndSwitch}{\algpx@endCodeCommand[0]}{}{}%
  \pretocmd{\EndCase}{\algpx@endCodeCommand[0]}{}{}%
}%
\makeatother

\begin{document}
\begin{algorithm}[H]
  \caption{Test Example}
  \begin{algorithmic}[1]
    \Function{Foo}{x}
    \While{x != 0}
      \State $x = x-1$
      \Switch{x}
        \Case{0}
          \State test 0
        \EndCase
        \Case{1}
          \State test 1
        \EndCase
      \EndSwitch
    \EndWhile
    \EndFunction
  \end{algorithmic}
\end{algorithm}
\end{document}