Here is my attempt to generate a pseudocode for *algorithmicx* package.

## Current features

- Functions (as
`SetDelayed`

)
`Set`

`If`

with 2 and 3 arguments
`While`

`Do`

(any number of variables of any type) **New!**
`Return`

`Module`

, `With`

, and `Block`

`CompoundExpression`

(`;`

)
- Test functions (
`EvenQ`

, etc., and `Not@EvenQ`

, etc.) **New!**
- Indentation

## Code

```
ClearAll[pseudocode, pscd]
SetAttributes[{pseudocode, pscd, texstring}, HoldFirst];
indent[n_] := "\n" <> ConstantArray[" ", n];
pscd[SetDelayed[f_[x___], code_], n_: 0, m_: 0] :=
indent[n] <> "\\Function{" <> pscd@f <> "}{" <>
Riffle[pscd@Hold@x, ","] <> "}\n" <> pscd[code, n + m, m] <>
indent[n] <> "\\EndFunction\n";
(*SetDelayed as a function*)
pscd[pattern_, n_: 0, m_: 0] /; Head@Unevaluated@pattern === Pattern :=
pscd /@ pattern // First;
(*remove patterns from arguments of functions*)
pscd[(Module | With | Block)[{vars___}, code_], n_: 0, m_: 0] :=
Cases[Hold@vars, s_ /; Head@Unevaluated@s === Set :> pscd[s, n, m]] <>
pscd[code, n, m];
(*remove everything from Module,With,and Block except code and setting of variables*)
pscd[set_, n_: 0, m_: 0] /; Head@Unevaluated@set === Set :=
indent[n] <> "\\State " <>
Riffle[pscd@# &@ReleaseHold[Hold @@@ Hold@set], " $\\gets$ "] <> "\n";
(*Set*)
pscd[CompoundExpression[code___], n_: 0, m_: 0] :=
Riffle[pscd[Hold@code, n, m], "\n"] <> "\n"
(*...;...;*)
pscd[If[cond_, true_], n_: 0, m_: 0] :=
indent[n] <> "\\If{" <> pscd@cond <> "}\n" <> pscd[true, n + m, m] <>
indent[n] <> "\\EndIf\n";
(*if*)
pscd[If[cond_, true_, false_], n_: 0, m_: 0] :=
indent[n] <> "\\If{" <> pscd@cond <> "}\n" <> pscd[true, n + m, m] <>
indent[n] <> "\\Else\n" <> pscd[false, n + m, m] <> indent[n] <>
"\\EndIf\n";
(*if... else*)
pscd[While[cond_, code_], n_: 0, m_: 0] :=
indent[n] <> "\\While{" <> pscd@cond <> "}\n" <>
pscd[code, n + m, m] <> indent[n] <> "\\EndWhile\n";
(*while*)
pscd[Do[code_, args__, arg1_], n_: 0, m_: 0] :=
pscd[Do[Do[code, arg1], args], n, m];
(*nested do*)
pscd[Do[code_, {i2_}], n_: 0, m_: 0] :=
indent[n] <> "\\Do{" <> pscd@i2 <> "}\n" <> pscd[code, n + m, m] <>
indent[n] <> "\\EndDo\n";
pscd[Do[code_, {i_, i2_}], n_: 0, m_: 0] :=
pscd[Do[code, {i, 1, i2}], n, m];
pscd[Do[code_, {i_, i1_, i2_}], n_: 0, m_: 0] :=
indent[n] <> "\\For{" <> pscd@i <> " = " <> pscd@i1 <> " \\ldots " <>
pscd@i2 <> "}\n" <> pscd[code, n + m, m] <> indent[n] <>
"\\EndFor\n";
pscd[Do[code_, {i_, i1_, i2_, di_}], n_: 0, m_: 0] :=
indent[n] <> "\\For{" <> pscd@i <> " = " <> pscd@i1 <> ", " <>
texstring[i1 + di] <> " \\ldots " <> pscd@i2 <> "}\n" <>
pscd[code, n + m, m] <> indent[n] <> "\\EndFor\n";
pscd[Do[code_, {i_, l_List}], n_: 0, m_: 0] :=
indent[n] <> "\\For{" <> pscd@i <> " = " <>
Riffle[pscd /@ l, ", "] <> "}\n" <> pscd[code, n + m, m] <>
indent[n] <> "\\EndFor\n";
(*do*)
pscd[q_[x_], n_: 0, m_: 0] /; (Last@# == "Q" && LowerCaseQ@#[[-2]] &)@
Characters@ToString@Unevaluated@q :=
pscd@x <> " is " <> Riffle[StringCases[ToString@q,
A_?UpperCaseQ ~~ b__?LowerCaseQ :> ToLowerCase@A <> b], " "]
(* convert EvenQ[x] to "x is even" and so on *)
pscd[Not@q_[x_], n_: 0, m_: 0] /; (Last@# == "Q" && LowerCaseQ@#[[-2]] &)@
Characters@ToString@Unevaluated@q :=
pscd@x <> " is not " <> Riffle[StringCases[ToString@q,
A_?UpperCaseQ ~~ b__?LowerCaseQ :> ToLowerCase@A <> b], " "]
(* convert Not@EvenQ[x] to "x is not even" and so on *)
pscd[Return[x_], n_: 0, m_: 0] :=
indent[n] <> "\\State \\textbf{return} " <> pscd@x <> "\n";
(*return*)
pscd[h_Hold, n_: 0, m_: 0] :=
List @@ Function[{x}, pscd[x, n, m], HoldAll] /@ h
(*Automatically transform Hold[x,y,...] to {pscd[x],pscd[y],...}*)
pscd[code_, n_: 0, m_: 0] := texstring@HoldForm@code;
(*default*)
texstring[code_] := "$" <> code~ToString~TeXForm <> "$";
(*sometimes we need to convert without holding *)
Options[pseudocode] = {Indentation -> 2};
pseudocode[code_, OptionsPattern[]] :=
CellPrint@TextCell[StringReplace[
"\\begin{algorithmic}\n" <>
pscd[code, OptionValue@Indentation, OptionValue@Indentation] <>
"\\end{algorithmic}", "\n" .. :> "\n"], "Output"];
```

For indentation I use `n`

and `m`

variables. `n`

is the current indentation and `m`

is the step of the indentation.

## Examples

### Example 1

```
pseudocode[
max[a_, b_] := Module[{r},
If[a > b, r = a, r = b];
Return[r]]
]
```

Output:

```
\begin{algorithmic}
\Function{$\max$}{$a$,$b$}
\If{$a>b$}
\State $r$ $\gets$ $a$
\Else
\State $r$ $\gets$ $b$
\EndIf
\State \textbf{return} $r$
\EndFunction
\end{algorithmic}
```

### Example 2

```
pseudocode[
gcd[a_, b_] := Module[{r = Mod[a, b], x = a, y = b},
While[r != 0,
x = y;
y = r;
r = Mod[x, y]
];
Return[y]
]
]
```

Output:

```
\begin{algorithmic}
\Function{$\gcd$}{$a$,$b$}
\State $r$ $\gets$ $(a \bmod b)$
\State $x$ $\gets$ $a$
\State $y$ $\gets$ $b$
\While{$r\neq 0$}
\State $x$ $\gets$ $y$
\State $y$ $\gets$ $r$
\State $r$ $\gets$ $(x \bmod y)$
\EndWhile
\State \textbf{return} $y$
\EndFunction
\end{algorithmic}
```

### Example 3

```
Do[i = i + n + m + k + l, {n, 10}, {m, 5, 20}, {k, m, 30, 2},
{l, {1, 3, 5, 8}}, {40}] // pseudocode
```

Output:

```
\begin{algorithmic}
\For{$n$ = $1$ \ldots $10$}
\For{$m$ = $5$ \ldots $20$}
\For{$k$ = $m$, $m+2$ \ldots $30$}
\For{$l$ = $1$, $3$, $5$, $8$}
\Do{$40$}
\State $i$ $\gets$ $i+n+m+k+l$
\EndDo
\EndFor
\EndFor
\EndFor
\EndFor
\end{algorithmic}
```

### Example 4

```
If[! HermitianMatrixQ[H], H = H + ConjugateTranspose[H]] // pseudocode
```

Output:

```
\begin{algorithmic}
\If{$H$ is not hermitian matrix}
\State $H$ $\gets$ $H+H^{\dagger}$
\EndIf
\end{algorithmic}
```

$\LaTeX$ example file:

```
\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{algpseudocode}
\algrenewcommand\textproc{}% Disable uppercase in functions
%necessary for "do ... times" constructions
\algblockdefx[DO]{Do}{EndDo}[1]{\textbf{do} #1 \textbf{times}}{\textbf{end do}}
\begin{document}
\begin{algorithmic}
...
\end{algorithmic}
\end{document}
```

Let me know if you find a bug!

4+1, but I always wanted a package able to do it the other way around and can interpret my

"Now get all those solutions"pseudocode comments – Dr. belisarius – 2013-10-29T06:09:20.217Me too! Alas that direction is much much harder :/ I have a friend who believes that smart and visual programming languages in the next 10 years will have this ability. – M.R. – 2013-10-29T06:21:13.000

Perhaps

`SpokenString`

or`CompilePrint`

could come in handy. – Simon Woods – 2013-10-29T11:52:09.3573But now with all those upvotes you sure gotta deliver ;-) – Yves Klett – 2013-10-29T13:35:53.353

7IMO this is problematic due to the ill-defined nature of "pseudocode", dependent as it is on the expectations of the audience. I actually dislike pseudocode descriptions in papers since normally they are written in an inappropriately procedural style and often contain various bugs due to the fact that they can't actually be executed to check for correctness. I would suggest translating to some widely used, free and open language such as Python and providing the code in the supplementary materials. Another good alternative to pseudocode is a flowchart. – Oleksandr R. – 2013-10-29T19:14:06.017

This could be extremely useful for writing papers :) Please someone answer this question! – user5601 – 2013-10-31T17:58:19.683