diff options
author | Karl Berry <karl@freefriends.org> | 2022-11-13 21:23:27 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-11-13 21:23:27 +0000 |
commit | 38c0458b0227cb97b88876955527ad3bfcde94f1 (patch) | |
tree | 3c6c2881c7778e1049b02b04c627833c84cfcf46 /Master/texmf-dist | |
parent | dd89769c5e3ff93f9a9b97e727858cb06ed095dc (diff) |
eolang (13nov22)
git-svn-id: svn://tug.org/texlive/trunk@65006 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist')
-rw-r--r-- | Master/texmf-dist/doc/latex/eolang/eolang.pdf | bin | 1106103 -> 1415294 bytes | |||
-rw-r--r-- | Master/texmf-dist/source/latex/eolang/eolang.dtx | 492 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/eolang/eolang.sty | 280 |
3 files changed, 603 insertions, 169 deletions
diff --git a/Master/texmf-dist/doc/latex/eolang/eolang.pdf b/Master/texmf-dist/doc/latex/eolang/eolang.pdf Binary files differindex 73fcd9885e1..763d5bf07b6 100644 --- a/Master/texmf-dist/doc/latex/eolang/eolang.pdf +++ b/Master/texmf-dist/doc/latex/eolang/eolang.pdf diff --git a/Master/texmf-dist/source/latex/eolang/eolang.dtx b/Master/texmf-dist/source/latex/eolang/eolang.dtx index 3b2db126a48..49a30283bb3 100644 --- a/Master/texmf-dist/source/latex/eolang/eolang.dtx +++ b/Master/texmf-dist/source/latex/eolang/eolang.dtx @@ -50,7 +50,7 @@ %<package>\NeedsTeXFormat{LaTeX2e} %<package>\ProvidesPackage{eolang} %<*package> -[2022-11-05 0.4.0 Formulas and Graphs for EO Programming Language] +[2022-11-13 0.5.0 Formulas and Graphs for EO Programming Language] %</package> %<*driver> \documentclass{ltxdoc} @@ -100,8 +100,8 @@ % \usepackage{eolang} % \begin{document} % \begin{phiquation*} -% a -> [[ -% ^ !-> $.b, +% a -> [[ % it's abstract! +% ^ !-> $.b.^{^2}, 0-> TRUE, % b -> [[ c -> |fn|(56), % @ -> |hello|($), % \Delta ..> 01-FE-C3 ]]]],\\ @@ -141,15 +141,22 @@ % \end{itemize} % Also, a few symbols are supported for $\varphi$PU architecture: % \begin{itemize}\setlength\itemsep{0em} -% \item ``|-abc>|'' maps to ``$\xrightarrow{\text{\sffamily\scshape abc}}$'' -% (|\xrightarrow{\text{\sffamily\scshape abc}}|), +% \item ``|-abc>|'' maps to ``$\phiSlot{abc}$'' +% (|\phiSlot{abc}|), % \item ``|:=|'' maps to ``$\vDash$'' % (|\vDash|). % \end{itemize} +% Before any arrow you can put a number, which will be rendered as |\alpha| with an index. + +% Numbers are automatically converted to fixed-width font, no need to always decorate them with vertical bars. + +% |TRUE| and |FALSE| are automatically converted to fixed-width font too. + % \DescribeMacro{\phiq} % The command |\phiq| lets you inline a $\varphi$-calculus expressions % using the same simple plain-text notation: +% \docshotOptions{firstline=4,lastline=10} % \begin{docshot} % \documentclass{article} % \pagestyle{empty} @@ -171,12 +178,12 @@ % \usepackage{eolang} % \begin{document} % \begin{sodg} -% v0 \\ v0=> \\ v0!A +% v0 \\ v0===> \\ v0!!A % v1 xy:v0,-.8,2.8 data:42 \\ =>v1 % v0->v1 a:x rho % v2 xy:v0,+1,+1 atom:\xi.x+1 % v1->v2 a:|hi| bend:-15 -% v2->v0 pi bend:10 +% v2->v0 pi bend:10 % a comment % \end{sodg} % \end{document} % \end{docshot} @@ -195,6 +202,7 @@ % \item ``|box:<txt>|'' attaches a ``|<box>|'' to it, % \item ``|xy:<v>,<r>,<d>|'' places this vertex in a position relative to the vertex ``|<v>|,'' % shifting it right by ``|<r>|'' and down by ``|<d>|'' centimetres. +% \item ``|+:<v>|'' makes a copy of an existing vertex and all its kids. % \end{itemize} % The following markers are supported for an edge: @@ -208,11 +216,17 @@ % It is also possible to put transformation arrows to the graph, with the help of ``|v0=>v1|'' syntax. The arrow % will be placed exactly between two vertices. You can also put an arrow from a vertex to the right, -% saying for example ``|v3=>|'', of from the left to the vertes, by saying for example ``|=>v5|.'' +% saying for example ``|v3=>|'', of from the left to the vertes, by saying for example ``|=>v5|.'' If you +% want the arrow to stay further away from the vertex than usually, use a few ``|=|'' symbols, for example ``|===>v0|.'' % You can also put a marker at the left side of a vertex, using ``|v5!A|'' syntax, where ``|v5|'' is the vertex % and ``|A|'' is the text in the marker. They are useful when you put a few graphs on a picture -% explaining how one graph is transformed to another one and so forth. +% explaining how one graph is transformed to another one and so forth. You can make a distance between the vertex +% and the marker a bit larger by using a few exclamation marks, +% for example ``|v5!!!A|'' will make a distance three times bigger. + +% You can make a clone of an existing vertex together with all its dependants, by using this syntax: ``|v0+a|.'' +% Here, we make a copy of ``|v0|'' and call it ``|v0a|.'' See the example below. % Be aware, unrecognized markers are simply ignored, without any error reporting. @@ -223,6 +237,7 @@ % \eolang{} language. It understands |anonymous| mode of \href{https://ctan.org/pkg/acmart}{acmart} and prints itself % differently, to double-blind your paper. There is also |\phic| command to print % the name of \phic{}, also sensitive to |anonymous| mode. The macro |\xmir| prints "XMIR". +% \docshotOptions{firstline=4,lastline=10} % \begin{docshot} % \documentclass[anonymous]{acmart} % \thispagestyle{empty} @@ -230,22 +245,53 @@ % \begin{document} % In our research we use \eolang{}, \\ % an experimental object-oriented \\ -% dataflow language, \phic{}, \\ -% as its formal foundation, and \xmir{} \\ -% --- its XML-based presentation. +% dataflow language, \phic{}, as its \\ +% formal foundation, and \xmir{} --- \\ +% its XML-based presentation. % \end{document} % \end{docshot} % \DescribeMacro{\phiConst} -% A simple commands is defined to help you render an arrow for a constant attribute. -% It is recommende not to use it directly, but use |!->| instead. However, if you +% \DescribeMacro{\phiWave} +% \DescribeMacro{\phiDotted} +% A few simple commands are defined to help you render arrows. +% It is recommende not to use them directly, but use |!->| instead. However, if you % want to use |\phiConst|, wrap it in |\mathrel| for better display: +% \docshotOptions{firstline=6,lastline=12} % \begin{docshot} % \documentclass{article} % \pagestyle{empty} +% \usepackage[paperwidth=3in]{geometry} % \usepackage{eolang} -% \begin{document} -% \phiq{[[ x \mathrel{\phiConst} y ]]} +% \begin{document}\noindent +% If $x$ is an identifier and $y$ is +% an objects, then $x \phiConst y$ +% makes $y$ a constant, +% $x \phiWave y$ makes it a decoratee +% of arbitrary number of control-flow +% objects, while $x \phiDotted y$ +% makes it a special attribute. +% \end{document} +% \end{docshot} + +% \DescribeMacro{\phiMany} +% Sometimes you may need to simplify the way you describe an object: +% \docshotOptions{firstline=6,lastline=14} +% \begin{docshot} +% \documentclass{article} +% \pagestyle{empty} +% \usepackage[paperwidth=3in]{geometry} +% \usepackage{eolang} +% \begin{document}\noindent +% The expression +% \phiq{[[ 1-> x_1, +% 2-> x_2, \dots, +% \alpha_n -> x_n ]]} +% and expression +% \phiq{[[ \alpha_i +% \phiMany{->}{i=1}{n} x_i ]]} +% are syntactically different but +% semantically equivalent. % \end{document} % \end{docshot} @@ -269,6 +315,7 @@ % new lines in the formula. If you don't want this to happen and want to parse % the next line as the a continuation of the current line, you can use a single % backslash as it's done here: +% \docshotOptions{firstline=6,lastline=11} % \begin{docshot} % \documentclass{article} % \usepackage{amsmath} @@ -286,6 +333,7 @@ % This is how you can use |\dfrac| from |amsmath| for large inference rules, % with the help of |\begin{split}| and |\end{split}|: +% \docshotOptions{firstline=6,lastline=15} % \begin{docshot} % \documentclass{article} % \usepackage{amsmath} @@ -295,11 +343,11 @@ % \begin{phiquation*} % \dfrac{\begin{split} % x->[[@->y, z->42, -% \alpha_0->?, \alpha_1->42]] +% 0->?, 1->42]] % \end{split}}{\begin{split} % x->[[@->y, z->?, f ~> |pi|( -% \alpha_0->[[ \psi !-> |hello|(12) ]], -% \alpha_1->42)]] +% 0->[[ \psi !-> |hello|(12) ]], +% 1->42)]] % \end{split}}\text{R2}. % \end{phiquation*} % \end{document} @@ -320,8 +368,28 @@ % \end{document} % \end{docshot} +% It's possible to use |\label| inside |phiquation| environment: +% \docshotOptions{firstline=6,lastline=13} +% \begin{docshot} +% \documentclass{article} +% \usepackage[paperwidth=3in]{geometry} +% \usepackage{eolang} +% \pagestyle{empty} +% \begin{document}\noindent +% Discriminant can be calculated using +% the following simple formula: +% \begin{phiquation} +% D = b{^2} - 4ac. +% \label{d} +% \end{phiquation} +% Eq.~\ref{d} is also widely used in +% number theory and polynomial factoring. +% \end{document} +% \end{docshot} + % The |phiquation| environment will automatically align formulas by the first % arrow, if there are only left-aligned formulas: +% \docshotOptions{firstline=5,lastline=10} % \begin{docshot} % \documentclass{acmart} % \usepackage{eolang} @@ -330,23 +398,109 @@ % \begin{phiquation*} % x(\pi) -> [[\lambda ..> f_1]], \\ % x(a,b,c) -> [[ \alpha_0 -> ?, \ -% @ -> |hello|($) ]], \\ +% @ -> |hello|($), x -> |FALSE| ]], \\ % \Delta = |43-09|. % \end{phiquation*} % \end{document} % \end{docshot} -% Inside |phiquation| environment you can use labels too (just put |\label| after the formula): +% If not a single line is indented in |phiquation|, all formulas will be centered: +% \docshotOptions{firstline=5,lastline=9} +% \begin{docshot} +% \documentclass{acmart} +% \usepackage{eolang} +% \thispagestyle{empty} +% \begin{document} +% \begin{phiquation*} +% [[ b -> ? ]], \\ +% [[ @ -> TRUE, \Delta ..> 42 ]], \\ +% \Delta = |43-09|. +% \end{phiquation*} +% \end{document} +% \end{docshot} + +% You can make a copy of a vertex together with its kids: +% \docshotOptions{firstline=5,lastline=15} +% \begin{docshot} +% \documentclass{article} +% \pagestyle{empty} +% \usepackage{eolang} +% \begin{document} +% \begin{sodg} +% v0 \\ v0!!A +% v1 xy:v0,.7,1 +% v0->v1 a:x bend:-10 +% v2 xy:v1,-1.3,.8 +% v1->v2 a:|foo| bend:-20 +% v0+a xy:v0,3,0 +% v3a xy:v0a,-.7,1 +% v0a->v3a a:e bend:-15 +% v0=>v0a \\ v0a!B +% \end{sodg} +% \end{document} +% \end{docshot} + +% You can make a copy from a copy: +% \docshotOptions{firstline=5,lastline=15} % \begin{docshot} % \documentclass{article} +% \pagestyle{empty} % \usepackage{eolang} -% \usepackage[paperwidth=2in]{geometry} +% \begin{document} +% \begin{sodg} +% v0 +% v1 xy:v0,.7,1 +% v0->v1 a:x bend:-10 +% v0+a xy:v0,3,0 \\ v0=>v0a +% v2a xy:v1a,-.8,1.3 +% v1a->v2a a:e +% v0a+b xy:v0a,3,0 \\ v0a=>v0b +% v3b xy:v2b,-1,-1 +% v2b->v3b a:\psi +% \end{sodg} +% \end{document} +% \end{docshot} + +% You can have ``broken'' edges, using ``|break|'' attribute of an edge. +% The attribute must have a value, which is the percentange of the path +% between vertices that the arrow should take (can't be more than 80 and less than 20). +% This may be convenient when you can't fit all edges into the graph, +% for example: +% \docshotOptions{firstline=5,lastline=14} +% \begin{docshot} +% \documentclass{article} % \pagestyle{empty} +% \usepackage{eolang} % \begin{document} -% \begin{phiquation} -% x -> [[\Delta -> 42]]. \label{eq:A} -% \end{phiquation} -% Eq.~\ref{eq:A} is easy to read. +% \begin{sodg} +% v0 +% v1 xy:v0,-1,1 +% v0->v1 a:x +% v2 xy:v0,0,1 +% v0->v2 a:y +% v3 xy:v0,1,1 +% v0->v3 a:z +% v3->v1 a:f bend:-75 break:30 +% \end{sodg} +% \end{document} +% \end{docshot} + +% You can add \href{https://en.wikipedia.org/wiki/PGF/TikZ}{TikZ} commands to |sodg| graph, for example: +% \docshotOptions{firstline=6,lastline=13} +% \begin{docshot} +% \documentclass{article} +% \pagestyle{empty} +% \usepackage{eolang} +% \usetikzlibrary{fit} +% \begin{document} +% \begin{sodg} +% v0 +% v1 xy:v0,-1,1 \\ v0->v1 +% v2 xy:v0,0,1 \\ v0->v2 +% v3 xy:v0,1,1 \\ v0->v3 +% \node[draw=red,rounded corners,\ +% dotted,fit=(v1) (v2)] {}; +% \end{sodg} % \end{document} % \end{docshot} @@ -424,6 +578,8 @@ % \changes{0.1.0}{2022/10/26}{A new Perl script "\texttt{eolang-phi.pl}" added for parsing of phi expressions.} % \changes{0.2.0}{2022/10/29}{Numbers automatically render as \texttt{\char`\\texttt}. No need to use vertical bars around them anymore.} % \changes{0.3.0}{2022/10/30}{New arrow added, that looks like \texttt{\char`\\leadsto}.} +% \changes{0.5.0}{2022/11/11}{Automated formatting of \texttt{TRUE} and \texttt{FALSE} added.} +% \changes{0.5.0}{2022/11/13}{A new syntax introduced for \texttt{\char`\\alpha}-attributes: \texttt{0->}.} % Then, we create a Perl script for |phiquation| processing using |VerbatimOut| from % \href{https://ctan.org/pkg/fancyvrb}{fancyvrb}: % \begin{macrocode} @@ -445,31 +601,16 @@ foreach my $t (@lines) { print '% ', $t, "\n"; } print '% ---', "\n"; -if ($env eq 'phiq') { - print '$'; -} else { - print '\begin{', $env, '}\begin{split}'; -} +$tex =~ s/%.*\n/\n/g; $tex =~ s/^\s+|\s+$//g; +my $gathered = (0 == $tex =~ /\n\s+/g); if ($env ne 'phiq') { $tex =~ s/\s+\\\n\s*//g; $tex =~ s/\\\\\n/\n\n/g; + $tex =~ s/\n*(\\label\{[^\}]+\})\n*/\1/g; } -$tex =~ s/([\s,>\(])([0-9A-F][0-9A-F-]*)/\1|\2|/g; -$tex =~ s/\?/\\varnothing{}/g; -$tex =~ s/@/\\varphi{}/g; $tex =~ s/&/\\sigma{}/g; -$tex =~ s/\^/\\rho{}/g; -$tex =~ s/\$/\\xi{}/g; -$tex =~ s/-([a-z]+)>/\\mathrel{\\xrightarrow{\\text{\\sffamily\\scshape \1}}}/g; -$tex =~ s/!->/\\mathrel{\\phiConst}/g; -$tex =~ s/->/\\mathrel{\\mapsto}/g; -$tex =~ s/~>/\\mathrel{\\phiWave}/g; -$tex =~ s/:=/\\mathrel{\\vDash}/g; -$tex =~ s/..>/\\mathrel{\\phiDotted}/g; -$tex =~ s/\|([^\|]+)\|/\\textnormal{\\texttt{\1}}{}/g; -$tex =~ s/\[\[/\\llbracket\\mathrel{}/g; -$tex =~ s/\]\]/\\mathrel{}\\rrbracket{}/g; +$tex =~ s/(\s|^)([0-9]+)(->|\.\.>|~>|:=|!->)/\1\\alpha_{\2} \3/g; if ($env ne 'phiq') { $tex =~ s/\\begin\{split\}\n/\\begin{split}&/g; $tex =~ s/\n\s*\\end\{split\}/\\end{split}/g; @@ -477,20 +618,57 @@ if ($env ne 'phiq') { $tex =~ s/\n/\\\\[-4pt]&/g; $tex =~ s/([^&\s])\s{2}([^\s])/\1 \2/g; $tex =~ s/\s{2}/ \\quad{}/g; - my @leads = $tex =~ /&[^\s]+\s/g; + my @leads = $tex =~ /&[^\s]+\s(->|:=|=)/g; my @eols = $tex =~ /&/g; $tex = '&' . $tex; if (0+@leads == 0+@eols && 0+@eols > 0) { - $tex =~ s/&([^\s]+)\s/\1&/g; + $tex =~ s/&([^\s\}]+)\s/\1&/g; + $gathered = 0; } } +$tex =~ s/\$/\\xi{}/g; +$tex =~ s/(?<!\{)\^/\\rho{}/g; +$tex =~ s/\[\[/\\llbracket\\mathrel{}/g; +$tex =~ s/\]\]/\\mathrel{}\\rrbracket{}/g; +$tex =~ s/([\s,>\(])([0-9A-F]{2}(?:-[0-9A-F]{2})+|[0-9]+(?:\.[0-9]+)?)/\1|\2|/g; +$tex =~ s/TRUE/|TRUE|/g; +$tex =~ s/FALSE/|FALSE|/g; +$tex =~ s/\?/\\varnothing{}/g; +$tex =~ s/@/\\varphi{}/g; +$tex =~ s/-([a-z]+)>/\\mathrel{\\phiSlot{\1}}/g; +$tex =~ s/!->/\\mathrel{\\phiConst}/g; +$tex =~ s/->/\\mathrel{\\mapsto}/g; +$tex =~ s/~>/\\mathrel{\\phiWave}/g; +$tex =~ s/:=/\\mathrel{\\vDash}/g; +$tex =~ s/\.\.>/\\mathrel{\\phiDotted}/g; +$tex =~ s/\|{2,}/|/g; +$tex =~ s/\|([^\|]+)\|/\\textnormal{\\texttt{\1}}{}/g; +if ($env eq 'phiq') { + print '$' if ($tex ne ''); +} else { + print '\begin{', $env, '}'; + if ($gathered) { + print '\begin{gathered}'; + } else { + print '\begin{split}'; + } +} +if ($gathered) { + $tex =~ s/(\\\\(?:\[[^\]]+\])?)&/\1/g; + $tex =~ s/^&//g; +} print $tex; if ($env eq 'phiq') { - print '$'; + print '$' if ($tex ne ''); } else { - print '\end{split}\end{', $env, '}'; + if ($gathered) { + print '\end{gathered}'; + } else { + print '\end{split}'; + } + print '\end{', $env, '}'; } -print '\endinput', "\n"; +print '\endinput%'; \end{VerbatimOut} \message{eolang: File with Perl script '\eolang@tmpdir/eolang-phi.pl' saved^^J}% @@ -556,6 +734,10 @@ print '\endinput', "\n"; % \changes{0.4.0}{2022/10/31}{Labels on the edges are automatically printed as math formulas. Also, boxes are prefixed with \texttt{\char`\\Delta} and \texttt{\char`\\lambda} commands.} % \changes{0.4.0}{2022/10/31}{Relative positioning of vertices fixed.} % \changes{0.4.0}{2022/10/31}{Transforming arrows added with \texttt{=>} syntax, also markers with exclamation mark syntax.} +% \changes{0.5.0}{2022/11/09}{New syntax introduced that allows to make clones of vertices and all their dependants.} +% \changes{0.5.0}{2022/11/09}{Now edges may have \texttt{break} attribute, to make them shorter.} +% \changes{0.5.0}{2022/11/10}{It is possible to use multiple ``equaltion sign'' symbols for transition arrows \texttt{=>}.} +% \changes{0.5.0}{2022/11/12}{It is possible to use tikz commands inside \texttt{sodg} environment.} % Then, we create a Perl script for |sodg| graphs processing using |VerbatimOut| from % \href{https://ctan.org/pkg/fancyvrb}{fancyvrb}: % \begin{macrocode} @@ -571,53 +753,78 @@ sub fmt { $tex =~ s/\|([^\|]+)\|/\\textnormal{\\texttt{\1}}/g; return $tex; } +sub vertex { + my ($v) = @_; + if (index($v, 'v0') == 0) { + return '\Phi'; + } else { + $v =~ s/^v/v_/g; + $v =~ s/[^0-9]$//g; + return $v; + } +} +sub tailor { + my ($t, $m) = @_; + $t =~ s/<([A-Z]?${m}[A-Z]?):([^>]+)>/\2/g; + $t =~ s/<[A-Z]+:[^>]+>//g; + return $t; +} open(my $fh, '<', $ARGV[0]); my $tex; { local $/; $tex = <$fh>; } -print '% This file is auto-generated', "\n"; -print '% There are ', length($tex), - ' chars in the input: ', $ARGV[0], "\n"; -print '% ---', "\n"; if (index($tex, "\t") > 0) { print "TABS are prohibited!"; exit 1; } +print '% This file is auto-generated', "\n%\n"; +print '% --- there are ', length($tex), + ' chars in the input (', $ARGV[0], "):\n"; foreach my $t (split (/\n/g, $tex)) { print '% ', $t, "\n"; } -print '% ---', "\n"; -$tex =~ s/^\s+|\s+$//g; +print "% ---\n"; $tex =~ s/\\\\/\n/g; +$tex =~ s/\\\n//g; $tex =~ s/(\\[a-zA-Z]+) +/\1/g; -$tex =~ s/\n\s+/\n/g; -my @cmds = split (/\n/g, $tex); +$tex =~ s/\n{2,}/\n/g; +my @cmds = split(/\n/g, $tex); +print '% --- before processing:' . "\n"; +foreach my $t (split (/\n/g, $tex)) { + print '% ', $t, "\n"; +} +print '% ---'; +print ' (' . (0+@cmds) . " lines)\n"; print '\begin{phicture}', "\n"; -foreach my $c (@cmds) { - my ($head, $tail) = split (/ /, $c, 2); +for (my $c = 0; $c < 0+@cmds; $c++) { + my $cmd = $cmds[$c]; + $cmd =~ s/^\s+//g; + $cmd =~ s/%.*//g; + my ($head, $tail) = split(/ /, $cmd, 2); my %opts = {}; - foreach my $p (split (/ /, $tail)) { - my ($q, $t) = split (/:/, $p); + foreach my $p (split(/ /, $tail)) { + my ($q, $t) = split(/:/, $p); $opts{$q} = $t; } if (index($head, '->') >= 0) { - print '\draw['; + my $draw = '\draw['; if (exists $opts{'pi'}) { - print ',phi-pi'; + $draw = $draw . '<MB:phi-pi><F:draw=none>'; if (not exists $opts{'a'}) { $opts{'a'} = '\pi'; } } - print ']'; + $draw = $draw . ']'; my ($from, $to) = split (/->/, $head); - print ' (', $from, ') '; + $draw = $draw . " (${from}) "; if (exists $opts{'bend'}) { - print 'edge [bend right=', num($opts{'bend'}), ']'; + $draw = $draw . 'edge [<F:draw=none,><MF:bend right=' . + num($opts{'bend'}) . '>]'; } else { - print '--'; + $draw = $draw . '--'; } if (exists $opts{'rho'} or exists $opts{'rrho'}) { - print ' pic[sloped,phi-rho]{parallel arrow={'; - print '-' if not exists $opts{'rrho'}; - print '0.3,-0.15}}'; + $draw = $draw . ' pic[sloped,phi-rho]{parallel arrow={'; + $draw = $draw . '-' if not exists $opts{'rrho'}; + $draw = $draw . '0.3,-0.15}}'; } if (exists $opts{'a'}) { my $a = $opts{'a'}; @@ -626,27 +833,102 @@ foreach my $c (@cmds) { } else { $a = fmt($a); } - print ' node [phi-attr] {', $a, '}'; + $draw = $draw . '<MB: node [phi-attr] {' . $a . '}>'; + } + if (exists $opts{'break'}) { + $draw = $draw . '<F: coordinate [pos=' . + ($opts{'break'} / 100) . '] (break)>'; + } + $draw = $draw . " (<MF:${to}><B:break-v>)"; + if (exists $opts{'break'}) { + print tailor($draw, 'F') . ";\n"; + print ' \node[outer sep=.1cm,inner sep=0cm] ' . + 'at (break) (break-v) {$' . vertex($to) . + '$};' . "\n"; + print ' ' . tailor($draw, 'B'); + } else { + print tailor($draw, 'M'); } - print ' (', $to, ')'; } elsif (index($head, '=>') >= 0) { - my ($from, $to) = split (/=>/, $head); + my ($from, $to) = split (/=+>/, $head); + my $size = () = $head =~ /=/g; if ($from eq '') { - print '\node [phi-arrow, left=.6cm of ' . - $to . ']'; + print '\node [phi-arrow, left=' . ($size * 0.6) . 'cm of ' . + $to . '.center]'; } elsif ($to eq '') { - print '\node [phi-arrow, right=.6cm of ' . - $from . ']'; + print '\node [phi-arrow, right=' . ($size * 0.6) . 'cm of ' . + $from . '.center]'; } else { print '\node [phi-arrow] at ($(' . $from . ')!0.5!(' . $to . ')$)'; } print '{}'; } elsif (index($head, '!') >= 0) { - my ($v, $marker) = split (/!/, $head); - print '\node [phi-marker, left=.6cm of ' . - $v . ']{' . fmt($marker) . '}'; - } else { + my ($v, $marker) = split (/!+/, $head); + my $size = () = $head =~ /!/g; + print '\node [phi-marker, left=' . + ($size * 0.6) . 'cm of ' . + $v . '.center]{' . fmt($marker) . '}'; + } elsif (index($head, '+') >= 0) { + my ($v, $suffix) = split (/\+/, $head); + my @friends = ($v); + foreach my $c (@cmds) { + $e = $c; + $e =~ s/^\s+//g; + my $h = $e; + $h = substr($e, 0, index($e, ' ')) if index($e, ' ') >= 0; + foreach my $f (@friends) { + my $add = ''; + if (index($h, $f . '->') >= 0) { + $add = substr($h, index($h, '->') + 2); + } + if ($h =~ /->\Q${f}\E$/) { + $add = substr($h, 0, index($h, '->')); + } + if (index($e, ' xy:' . $f . ',') >= 0) { + $add = $h; + } + if (index($add, '+') == -1 + and $add ne '' + and not(grep(/^\Q${add}\E$/, @friends))) { + push(@friends, $add); + } + } + } + my @extra = (); + foreach my $e (@cmds) { + $m = $e; + if ($m =~ /^\s*\Q${v}\E\s/) { + next; + } + if ($m =~ /^\s*[^\s]+\+/ and not($m =~ /^\s*\Q${head}\E\s/)) { + next; + } + foreach my $f (@friends) { + my $h = $f; + $h =~ s/[a-z]$//g; + if ($m =~ s/^(\s*)\Q${f}\E\+\Q${suffix}\E\s?/\1${h}${suffix} /g) { + last; + } + $m =~ s/^(\s*)\Q${f}\E\s/\1${h}${suffix} /g; + $m =~ s/^(\s*)\Q${f}\E->/\1${h}${suffix}->/g; + $m =~ s/\sxy:\Q${f}\E,/ xy:${h}${suffix},/g; + $m =~ s/->\Q${f}\E\s/->${h}${suffix} /g; + } + if ($m ne $e) { + push(@extra, ' ' . $m); + } + } + splice(@extra, 0, 0, @extra[-1]); + splice(@extra, -1, 1); + splice(@extra, 0, 0, '% clone of ' . $v . ' (' . $head . + '), friends: [' . join(', ', @friends) . '] in ' . + (0+@cmds) . ' lines'); + splice(@cmds, $c, 1, @extra); + print '% cloned ' . $v . ' at line no.' . $c . + ' (+' . (0+@extra) . ' lines -> ' . + (0+@cmds) . ' lines total)'; + } elsif ($head =~ /^v[0-9]+[a-z]?$/) { print '\node['; if (exists $opts{'xy'}) { my ($v, $right, $down) = split(/,/, $opts{'xy'}); @@ -663,7 +945,7 @@ foreach my $c (@cmds) { } print ',' . $loc . '='; print abs(num($down)) . 'cm and ' . - abs(num($right)) . 'cm of ' . $v; + abs(num($right)) . 'cm of ' . $v . '.center'; } if (exists $opts{'data'}) { print ',phi-data'; @@ -693,25 +975,24 @@ foreach my $c (@cmds) { } print ']'; print ' (', $head, ')'; - print ' {$'; - if (index($head, 'v0') == 0) { - print '\Phi'; - } else { - $name = $head; - $name =~ s/^v/v_/g; - $name =~ s/[^0-9]$//g; - print $name; - } - print '$}'; + print ' {$' . vertex($head) . '$}'; if (exists $opts{'box'}) { print ' node[phi-box] at ('; print $head, '.south east) {'; print $opts{'box'}, '}'; } + } else { + print $cmd; } print ";\n"; } -print '\end{phicture}', "\n", '\endinput'; +print '\end{phicture}%', "\n"; +print "% --- after processing:\n%"; +foreach my $c (@cmds) { + print '% ', $c, "\n"; +} +print '% --- (' . (0+@cmds) . " lines)\n"; +print '\endinput%'; \end{VerbatimOut} \message{eolang: File with Perl script '\eolang@tmpdir/eolang-sodg.pl' saved^^J}% @@ -735,12 +1016,11 @@ print '\end{phicture}', "\n", '\endinput'; \RequirePackage{tikz} \usetikzlibrary{arrows} \usetikzlibrary{shapes} + \usetikzlibrary{snakes} \usetikzlibrary{decorations} \usetikzlibrary{decorations.pathmorphing} - \usetikzlibrary{intersections} \usetikzlibrary{positioning} \usetikzlibrary{calc} - \usetikzlibrary{shapes.arrows} % \end{macrocode} % \end{macro} @@ -839,7 +1119,7 @@ print '\end{phicture}', "\n", '\endinput'; % \begin{macrocode} \newcommand\xmir{% \ifdefined\anon% - \anon[XML']{XMIR}% + \anon[XML$^+$]{XMIR}% \else% XMIR% \fi% @@ -868,6 +1148,24 @@ print '\end{phicture}', "\n", '\endinput'; % \end{macrocode} % \end{macro} +% \begin{macro}{\phiSlot} +% \changes{0.5.0}{2022/11/10}{New command \texttt{\char`\\phiSlot} added to denote a link to a slot in a basket.} +% Then, we define a command to render an arrow for a slot in a basket: +% \begin{macrocode} +\newcommand\phiSlot[1]{% + \xrightarrow{\text{\sffamily\scshape #1}}} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\phiMany} +% \changes{0.5.0}{2022/11/10}{New command \texttt{\char`\\phiMany} enables iterating over an arrow.} +% Then, we define a command to an arrow with iterating indecies: +% \begin{macrocode} +\newcommand\phiMany[3]{% + \overunderset{\scriptscriptstyle #3}{\scriptscriptstyle #2}{#1}} +% \end{macrocode} +% \end{macro} + % \begin{macro}{\phiDotted} % \changes{0.1.0}{2022/10/27}{New command \texttt{\char`\\phiDotted} added to denote a link to a special attribute.} % Then, we define a command to render an arrow for a special attribute, diff --git a/Master/texmf-dist/tex/latex/eolang/eolang.sty b/Master/texmf-dist/tex/latex/eolang/eolang.sty index 087801f400f..1c58823608b 100644 --- a/Master/texmf-dist/tex/latex/eolang/eolang.sty +++ b/Master/texmf-dist/tex/latex/eolang/eolang.sty @@ -31,7 +31,17 @@ \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{eolang} -[2022-11-05 0.4.0 Formulas and Graphs for EO Programming Language] +[2022-11-13 0.5.0 Formulas and Graphs for EO Programming Language] + + + + + + + + + + @@ -99,31 +109,16 @@ foreach my $t (@lines) { print '% ', $t, "\n"; } print '% ---', "\n"; -if ($env eq 'phiq') { - print '$'; -} else { - print '\begin{', $env, '}\begin{split}'; -} +$tex =~ s/%.*\n/\n/g; $tex =~ s/^\s+|\s+$//g; +my $gathered = (0 == $tex =~ /\n\s+/g); if ($env ne 'phiq') { $tex =~ s/\s+\\\n\s*//g; $tex =~ s/\\\\\n/\n\n/g; + $tex =~ s/\n*(\\label\{[^\}]+\})\n*/\1/g; } -$tex =~ s/([\s,>\(])([0-9A-F][0-9A-F-]*)/\1|\2|/g; -$tex =~ s/\?/\\varnothing{}/g; -$tex =~ s/@/\\varphi{}/g; $tex =~ s/&/\\sigma{}/g; -$tex =~ s/\^/\\rho{}/g; -$tex =~ s/\$/\\xi{}/g; -$tex =~ s/-([a-z]+)>/\\mathrel{\\xrightarrow{\\text{\\sffamily\\scshape \1}}}/g; -$tex =~ s/!->/\\mathrel{\\phiConst}/g; -$tex =~ s/->/\\mathrel{\\mapsto}/g; -$tex =~ s/~>/\\mathrel{\\phiWave}/g; -$tex =~ s/:=/\\mathrel{\\vDash}/g; -$tex =~ s/..>/\\mathrel{\\phiDotted}/g; -$tex =~ s/\|([^\|]+)\|/\\textnormal{\\texttt{\1}}{}/g; -$tex =~ s/\[\[/\\llbracket\\mathrel{}/g; -$tex =~ s/\]\]/\\mathrel{}\\rrbracket{}/g; +$tex =~ s/(\s|^)([0-9]+)(->|\.\.>|~>|:=|!->)/\1\\alpha_{\2} \3/g; if ($env ne 'phiq') { $tex =~ s/\\begin\{split\}\n/\\begin{split}&/g; $tex =~ s/\n\s*\\end\{split\}/\\end{split}/g; @@ -131,20 +126,57 @@ if ($env ne 'phiq') { $tex =~ s/\n/\\\\[-4pt]&/g; $tex =~ s/([^&\s])\s{2}([^\s])/\1 \2/g; $tex =~ s/\s{2}/ \\quad{}/g; - my @leads = $tex =~ /&[^\s]+\s/g; + my @leads = $tex =~ /&[^\s]+\s(->|:=|=)/g; my @eols = $tex =~ /&/g; $tex = '&' . $tex; if (0+@leads == 0+@eols && 0+@eols > 0) { - $tex =~ s/&([^\s]+)\s/\1&/g; + $tex =~ s/&([^\s\}]+)\s/\1&/g; + $gathered = 0; } } +$tex =~ s/\$/\\xi{}/g; +$tex =~ s/(?<!\{)\^/\\rho{}/g; +$tex =~ s/\[\[/\\llbracket\\mathrel{}/g; +$tex =~ s/\]\]/\\mathrel{}\\rrbracket{}/g; +$tex =~ s/([\s,>\(])([0-9A-F]{2}(?:-[0-9A-F]{2})+|[0-9]+(?:\.[0-9]+)?)/\1|\2|/g; +$tex =~ s/TRUE/|TRUE|/g; +$tex =~ s/FALSE/|FALSE|/g; +$tex =~ s/\?/\\varnothing{}/g; +$tex =~ s/@/\\varphi{}/g; +$tex =~ s/-([a-z]+)>/\\mathrel{\\phiSlot{\1}}/g; +$tex =~ s/!->/\\mathrel{\\phiConst}/g; +$tex =~ s/->/\\mathrel{\\mapsto}/g; +$tex =~ s/~>/\\mathrel{\\phiWave}/g; +$tex =~ s/:=/\\mathrel{\\vDash}/g; +$tex =~ s/\.\.>/\\mathrel{\\phiDotted}/g; +$tex =~ s/\|{2,}/|/g; +$tex =~ s/\|([^\|]+)\|/\\textnormal{\\texttt{\1}}{}/g; +if ($env eq 'phiq') { + print '$' if ($tex ne ''); +} else { + print '\begin{', $env, '}'; + if ($gathered) { + print '\begin{gathered}'; + } else { + print '\begin{split}'; + } +} +if ($gathered) { + $tex =~ s/(\\\\(?:\[[^\]]+\])?)&/\1/g; + $tex =~ s/^&//g; +} print $tex; if ($env eq 'phiq') { - print '$'; + print '$' if ($tex ne ''); } else { - print '\end{split}\end{', $env, '}'; + if ($gathered) { + print '\end{gathered}'; + } else { + print '\end{split}'; + } + print '\end{', $env, '}'; } -print '\endinput', "\n"; +print '\endinput%'; \end{VerbatimOut} \message{eolang: File with Perl script '\eolang@tmpdir/eolang-phi.pl' saved^^J}% @@ -201,53 +233,78 @@ sub fmt { $tex =~ s/\|([^\|]+)\|/\\textnormal{\\texttt{\1}}/g; return $tex; } +sub vertex { + my ($v) = @_; + if (index($v, 'v0') == 0) { + return '\Phi'; + } else { + $v =~ s/^v/v_/g; + $v =~ s/[^0-9]$//g; + return $v; + } +} +sub tailor { + my ($t, $m) = @_; + $t =~ s/<([A-Z]?${m}[A-Z]?):([^>]+)>/\2/g; + $t =~ s/<[A-Z]+:[^>]+>//g; + return $t; +} open(my $fh, '<', $ARGV[0]); my $tex; { local $/; $tex = <$fh>; } -print '% This file is auto-generated', "\n"; -print '% There are ', length($tex), - ' chars in the input: ', $ARGV[0], "\n"; -print '% ---', "\n"; if (index($tex, "\t") > 0) { print "TABS are prohibited!"; exit 1; } +print '% This file is auto-generated', "\n%\n"; +print '% --- there are ', length($tex), + ' chars in the input (', $ARGV[0], "):\n"; foreach my $t (split (/\n/g, $tex)) { print '% ', $t, "\n"; } -print '% ---', "\n"; -$tex =~ s/^\s+|\s+$//g; +print "% ---\n"; $tex =~ s/\\\\/\n/g; +$tex =~ s/\\\n//g; $tex =~ s/(\\[a-zA-Z]+) +/\1/g; -$tex =~ s/\n\s+/\n/g; -my @cmds = split (/\n/g, $tex); +$tex =~ s/\n{2,}/\n/g; +my @cmds = split(/\n/g, $tex); +print '% --- before processing:' . "\n"; +foreach my $t (split (/\n/g, $tex)) { + print '% ', $t, "\n"; +} +print '% ---'; +print ' (' . (0+@cmds) . " lines)\n"; print '\begin{phicture}', "\n"; -foreach my $c (@cmds) { - my ($head, $tail) = split (/ /, $c, 2); +for (my $c = 0; $c < 0+@cmds; $c++) { + my $cmd = $cmds[$c]; + $cmd =~ s/^\s+//g; + $cmd =~ s/%.*//g; + my ($head, $tail) = split(/ /, $cmd, 2); my %opts = {}; - foreach my $p (split (/ /, $tail)) { - my ($q, $t) = split (/:/, $p); + foreach my $p (split(/ /, $tail)) { + my ($q, $t) = split(/:/, $p); $opts{$q} = $t; } if (index($head, '->') >= 0) { - print '\draw['; + my $draw = '\draw['; if (exists $opts{'pi'}) { - print ',phi-pi'; + $draw = $draw . '<MB:phi-pi><F:draw=none>'; if (not exists $opts{'a'}) { $opts{'a'} = '\pi'; } } - print ']'; + $draw = $draw . ']'; my ($from, $to) = split (/->/, $head); - print ' (', $from, ') '; + $draw = $draw . " (${from}) "; if (exists $opts{'bend'}) { - print 'edge [bend right=', num($opts{'bend'}), ']'; + $draw = $draw . 'edge [<F:draw=none,><MF:bend right=' . + num($opts{'bend'}) . '>]'; } else { - print '--'; + $draw = $draw . '--'; } if (exists $opts{'rho'} or exists $opts{'rrho'}) { - print ' pic[sloped,phi-rho]{parallel arrow={'; - print '-' if not exists $opts{'rrho'}; - print '0.3,-0.15}}'; + $draw = $draw . ' pic[sloped,phi-rho]{parallel arrow={'; + $draw = $draw . '-' if not exists $opts{'rrho'}; + $draw = $draw . '0.3,-0.15}}'; } if (exists $opts{'a'}) { my $a = $opts{'a'}; @@ -256,27 +313,102 @@ foreach my $c (@cmds) { } else { $a = fmt($a); } - print ' node [phi-attr] {', $a, '}'; + $draw = $draw . '<MB: node [phi-attr] {' . $a . '}>'; + } + if (exists $opts{'break'}) { + $draw = $draw . '<F: coordinate [pos=' . + ($opts{'break'} / 100) . '] (break)>'; + } + $draw = $draw . " (<MF:${to}><B:break-v>)"; + if (exists $opts{'break'}) { + print tailor($draw, 'F') . ";\n"; + print ' \node[outer sep=.1cm,inner sep=0cm] ' . + 'at (break) (break-v) {$' . vertex($to) . + '$};' . "\n"; + print ' ' . tailor($draw, 'B'); + } else { + print tailor($draw, 'M'); } - print ' (', $to, ')'; } elsif (index($head, '=>') >= 0) { - my ($from, $to) = split (/=>/, $head); + my ($from, $to) = split (/=+>/, $head); + my $size = () = $head =~ /=/g; if ($from eq '') { - print '\node [phi-arrow, left=.6cm of ' . - $to . ']'; + print '\node [phi-arrow, left=' . ($size * 0.6) . 'cm of ' . + $to . '.center]'; } elsif ($to eq '') { - print '\node [phi-arrow, right=.6cm of ' . - $from . ']'; + print '\node [phi-arrow, right=' . ($size * 0.6) . 'cm of ' . + $from . '.center]'; } else { print '\node [phi-arrow] at ($(' . $from . ')!0.5!(' . $to . ')$)'; } print '{}'; } elsif (index($head, '!') >= 0) { - my ($v, $marker) = split (/!/, $head); - print '\node [phi-marker, left=.6cm of ' . - $v . ']{' . fmt($marker) . '}'; - } else { + my ($v, $marker) = split (/!+/, $head); + my $size = () = $head =~ /!/g; + print '\node [phi-marker, left=' . + ($size * 0.6) . 'cm of ' . + $v . '.center]{' . fmt($marker) . '}'; + } elsif (index($head, '+') >= 0) { + my ($v, $suffix) = split (/\+/, $head); + my @friends = ($v); + foreach my $c (@cmds) { + $e = $c; + $e =~ s/^\s+//g; + my $h = $e; + $h = substr($e, 0, index($e, ' ')) if index($e, ' ') >= 0; + foreach my $f (@friends) { + my $add = ''; + if (index($h, $f . '->') >= 0) { + $add = substr($h, index($h, '->') + 2); + } + if ($h =~ /->\Q${f}\E$/) { + $add = substr($h, 0, index($h, '->')); + } + if (index($e, ' xy:' . $f . ',') >= 0) { + $add = $h; + } + if (index($add, '+') == -1 + and $add ne '' + and not(grep(/^\Q${add}\E$/, @friends))) { + push(@friends, $add); + } + } + } + my @extra = (); + foreach my $e (@cmds) { + $m = $e; + if ($m =~ /^\s*\Q${v}\E\s/) { + next; + } + if ($m =~ /^\s*[^\s]+\+/ and not($m =~ /^\s*\Q${head}\E\s/)) { + next; + } + foreach my $f (@friends) { + my $h = $f; + $h =~ s/[a-z]$//g; + if ($m =~ s/^(\s*)\Q${f}\E\+\Q${suffix}\E\s?/\1${h}${suffix} /g) { + last; + } + $m =~ s/^(\s*)\Q${f}\E\s/\1${h}${suffix} /g; + $m =~ s/^(\s*)\Q${f}\E->/\1${h}${suffix}->/g; + $m =~ s/\sxy:\Q${f}\E,/ xy:${h}${suffix},/g; + $m =~ s/->\Q${f}\E\s/->${h}${suffix} /g; + } + if ($m ne $e) { + push(@extra, ' ' . $m); + } + } + splice(@extra, 0, 0, @extra[-1]); + splice(@extra, -1, 1); + splice(@extra, 0, 0, '% clone of ' . $v . ' (' . $head . + '), friends: [' . join(', ', @friends) . '] in ' . + (0+@cmds) . ' lines'); + splice(@cmds, $c, 1, @extra); + print '% cloned ' . $v . ' at line no.' . $c . + ' (+' . (0+@extra) . ' lines -> ' . + (0+@cmds) . ' lines total)'; + } elsif ($head =~ /^v[0-9]+[a-z]?$/) { print '\node['; if (exists $opts{'xy'}) { my ($v, $right, $down) = split(/,/, $opts{'xy'}); @@ -293,7 +425,7 @@ foreach my $c (@cmds) { } print ',' . $loc . '='; print abs(num($down)) . 'cm and ' . - abs(num($right)) . 'cm of ' . $v; + abs(num($right)) . 'cm of ' . $v . '.center'; } if (exists $opts{'data'}) { print ',phi-data'; @@ -323,25 +455,24 @@ foreach my $c (@cmds) { } print ']'; print ' (', $head, ')'; - print ' {$'; - if (index($head, 'v0') == 0) { - print '\Phi'; - } else { - $name = $head; - $name =~ s/^v/v_/g; - $name =~ s/[^0-9]$//g; - print $name; - } - print '$}'; + print ' {$' . vertex($head) . '$}'; if (exists $opts{'box'}) { print ' node[phi-box] at ('; print $head, '.south east) {'; print $opts{'box'}, '}'; } + } else { + print $cmd; } print ";\n"; } -print '\end{phicture}', "\n", '\endinput'; +print '\end{phicture}%', "\n"; +print "% --- after processing:\n%"; +foreach my $c (@cmds) { + print '% ', $c, "\n"; +} +print '% --- (' . (0+@cmds) . " lines)\n"; +print '\endinput%'; \end{VerbatimOut} \message{eolang: File with Perl script '\eolang@tmpdir/eolang-sodg.pl' saved^^J}% @@ -354,12 +485,11 @@ print '\end{phicture}', "\n", '\endinput'; \RequirePackage{tikz} \usetikzlibrary{arrows} \usetikzlibrary{shapes} + \usetikzlibrary{snakes} \usetikzlibrary{decorations} \usetikzlibrary{decorations.pathmorphing} - \usetikzlibrary{intersections} \usetikzlibrary{positioning} \usetikzlibrary{calc} - \usetikzlibrary{shapes.arrows} \newenvironment{phicture}% {\noindent\begin{tikzpicture}[ @@ -426,7 +556,7 @@ print '\end{phicture}', "\n", '\endinput'; \newcommand\xmir{% \ifdefined\anon% - \anon[XML']{XMIR}% + \anon[XML$^+$]{XMIR}% \else% XMIR% \fi% @@ -439,6 +569,12 @@ print '\end{phicture}', "\n", '\endinput'; \newcommand\phiWave{% \mapstochar\mathrel{\mspace{0.45mu}}\leadsto} +\newcommand\phiSlot[1]{% + \xrightarrow{\text{\sffamily\scshape #1}}} + +\newcommand\phiMany[3]{% + \overunderset{\scriptscriptstyle #3}{\scriptscriptstyle #2}{#1}} + \RequirePackage{trimclip} \RequirePackage{amsfonts} \makeatletter |