8 stable releases
1.1.5 | Dec 21, 2020 |
---|---|
1.1.4 | Dec 20, 2020 |
1.0.1 | Nov 26, 2020 |
#1864 in Parser implementations
370KB
743 lines
PseudoTex
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 😁.
The pseudocode that PseudoTex follows is somewhat formalized in this paper by João Leitão (check caveats).
Installing
For now there are two ways of installing PseudoTex, either by using cargo
or by downloading the latest binary release.
Using cargo
λ ~/ $ cargo install pseudotex
Using latest release
Go to the repository Releases page and download the binary (Linux or macOS).
Running
λ ~/ $ 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 <input> file name to read content from
-o, --output <output> file name to write content to
Caveats
Semi Colons
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.
TODO
- Add more symbols
- Add tests
- Add test automation per commit
- Add subscript
Contributing
If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome.
Links
Project dependencies:
Example
Here is a small example (check example_protocol.pseudo)
state:
parents // these are parents ;
services;
myId;
fallback;
upon init do:
fallback = getFallback();
myId = randomString();
upon event Receive(QUALITY_NOT_ASSURED, 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:
\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:
Licensing
The code in this project is licensed under GPL-3.0.
Dependencies
~4–5.5MB
~100K SLoC