PseudoTex is a compiler that translates pseudocode into its LaTex representation
In university I had to do a few reports in LaTex that had pseudocode. Translating the simple pseudocode to the LaTex commands was a huge struggle so I decided to make this tool that translates a simple pseudocode language into the LaTex equivalent commands. I hope it makes your life easier :grin:.
The pseudocode that PseudoTex follows is somewhat formalized in this paper by João Leitão (check caveats).
For now there are two ways of installing PseudoTex, either by using cargo
or by downloading the latest binary release.
shell
λ ~/ $ cargo install pseudotex
Go to the repository Releases page and download the binary (Linux or macOS).
```shell λ ~/ $ pseudotex --help PseudoTex 1.0 Bruno Anjos bruno.vale.anjos@gmail.com pseudocode transpiler to latex representation
USAGE: pseudotex [OPTIONS]
FLAGS: -h, --help Prints help information -V, --version Prints version information
OPTIONS: -i, --input file name to read content from -o, --output
One main difference from the language described in the paper, is that every statement has to be followed by a semi colon. I believe this can be changed in the future, but since this made the parser easier to build i decided to take this approach.
If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome.
Project dependencies: - LALRPOP - clap - algorithm2e LaTex Package
Here is a small example (check example_protocol.pseudo)
```pseudo state: parents // these are parents ; services; myId; fallback;
upon init do: fallback = getFallback(); myId = randomString();
upon event Receive(QUALITYNOTASSURED, service, location) do: newChild = getNodeClosestTo(location); trigger Send(DEPLOY_SERVICE, newChild, service, myself); call addChild(service, newChild);
upon event Receive(DEPLOY_SERVICE, service, sender) do: if service !in services: services = services unite {service}; end call updateParent(service, sender);
procedure updateParent(service, parent): if service.Parent == parent: return; end parents = parents unite {parent}; service.parent = parent; foreach child in service.children: trigger Send(GRANDPARENT, child, service, parent, myself); end
upon event Receive(GRANDPARENT, service, grandparent, sender) do: service.grandparent = grandparent;
procedure updateChildren(service): orderedChild = order(service.children); foreach child in service.children: trigger Send(SIBLINGS, child, service, orderedChild); end
procedure addChild(service, child): if child !in children: children = children unite {child}; end
if child !in service.children:
service.children = service.children unite {child};
servicesByChild[child] = servicesByChild[child] unite {service};
call updateChildren(service);
end
```
This pseudocode generates the following LaTeX:
```Latex \documentclass{article} \usepackage[utf8]{inputenc} \usepackage[ruled,vlined,linesnumbered]{algorithm2e} \usepackage{amssymb} \begin{document} {{\DontPrintSemicolon \SetAlgoNoLine \LinesNumberedHidden \SetFuncSty{textbf} \begin{algorithm}[ht] \BlankLine \BlankLine \BlankLine
\SetKwFunction{FunctionID}{State} \SetKwProg{Fn}{}{:}{} \Fn{\FunctionID}{ parents // these are parents \;services \;myId \;fallback }
\;\SetKwFunction{FunctionID}{Init} \SetKwProg{Fn}{Upon }{ do:}{} \Fn{\FunctionID}{ fallback $\longleftarrow$ \FuncSty{getFallback(}\ArgSty{}\FuncSty{)} \;myId $\longleftarrow$ \FuncSty{randomString(}\ArgSty{}\FuncSty{)} }
\;\SetKwFunction{FunctionID}{Receive} \SetKwProg{Fn}{Upon event }{ do:}{} \Fn{\FunctionID{QUALITY_NOT_ASSURED, service, location}}{ newChild $\longleftarrow$ \FuncSty{getNodeClosestTo(}\ArgSty{location}\FuncSty{)} \;\FuncSty{Trigger} \FuncSty{Send(}\ArgSty{DEPLOY_SERVICE, newChild, service, myself}\FuncSty{)} \;\FuncSty{Call addChild(}\ArgSty{service, newChild}\FuncSty{)} }
\;\SetKwFunction{FunctionID}{Receive} \SetKwProg{Fn}{Upon event }{ do:}{} \Fn{\FunctionID{DEPLOY_SERVICE, service, sender}}{ \If{service $\notin$ services}{services $\longleftarrow$ services $\cup$ {service}} \;\FuncSty{Call updateParent(}\ArgSty{service, sender}\FuncSty{)} }
\;\SetKwFunction{FunctionID}{updateParent} \SetKwProg{Fn}{Procedure }{:}{} \Fn{\FunctionID{service, parent}}{ \If{service.Parent == parent}{return} \;parents $\longleftarrow$ parents $\cup$ {parent} \;service.parent $\longleftarrow$ parent \;\ForEach{child $\in$ service.children}{\FuncSty{Trigger} \FuncSty{Send(}\ArgSty{GRANDPARENT, child, service, parent, myself}\FuncSty{)}} }
\;\SetKwFunction{FunctionID}{Receive} \SetKwProg{Fn}{Upon event }{ do:}{} \Fn{\FunctionID{GRANDPARENT, service, grandparent, sender}}{ service.grandparent $\longleftarrow$ grandparent }
\;\SetKwFunction{FunctionID}{updateChildren} \SetKwProg{Fn}{Procedure }{:}{} \Fn{\FunctionID{service}}{ orderedChild $\longleftarrow$ \FuncSty{order(}\ArgSty{service.children}\FuncSty{)} \;\ForEach{child $\in$ service.children}{\FuncSty{Trigger} \FuncSty{Send(}\ArgSty{SIBLINGS, child, service, orderedChild}\FuncSty{)}} }
\;\SetKwFunction{FunctionID}{addChild} \SetKwProg{Fn}{Procedure }{:}{} \Fn{\FunctionID{service, child}}{ \If{child $\notin$ children}{children $\longleftarrow$ children $\cup$ {child}} \;\If{child $\notin$ service.children}{service.children $\longleftarrow$ service.children $\cup$ {child} \;servicesByChild[child] $\longleftarrow$ servicesByChild[child] $\cup$ {service} \;\FuncSty{Call updateChildren(}\ArgSty{service}\FuncSty{)}} }
\BlankLine \BlankLine \BlankLine \end{algorithm} \end{document} ```
Which ultimately generates the following pdf:
The code in this project is licensed under GPL-3.0.