diff options
Diffstat (limited to 'macros/latex/contrib')
-rw-r--r-- | macros/latex/contrib/naive-ebnf/naive-ebnf.dtx | 185 | ||||
-rw-r--r-- | macros/latex/contrib/naive-ebnf/naive-ebnf.pdf | bin | 631010 -> 717864 bytes |
2 files changed, 132 insertions, 53 deletions
diff --git a/macros/latex/contrib/naive-ebnf/naive-ebnf.dtx b/macros/latex/contrib/naive-ebnf/naive-ebnf.dtx index d3105b2b87..922dd7a4f6 100644 --- a/macros/latex/contrib/naive-ebnf/naive-ebnf.dtx +++ b/macros/latex/contrib/naive-ebnf/naive-ebnf.dtx @@ -50,7 +50,7 @@ %<package>\NeedsTeXFormat{LaTeX2e} %<package>\ProvidesPackage{naive-ebnf} %<*package> -[2023-06-30 0.0.7 EBNF in Plain Text] +[2023-07-12 0.0.11 EBNF in Plain Text] %</package> %<*driver> \documentclass{ltxdoc} @@ -79,6 +79,9 @@ % % \maketitle % +% \textbf{\color{red}NB!} +% Large ENBF snippets may take too long to render! +% % \section{Introduction} % % This package helps render an @@ -92,7 +95,7 @@ % \begin{ebnf} % <$\lambda$-Expr> := <Var> \\ % || "$\lambda$" <Var> "." <Expr> \\ -% || "$\lparen$" <Expr> <Expr> "$\rparen$" +% || "\char`\(" <Expr> <Expr> "\char`\)" % \end{ebnf} % \end{document} % \end{docshot} @@ -106,6 +109,7 @@ % \item |"..."| denotes a terminal symbol; % \item |'...'| denotes a special non-printable terminal symbol, like |'EOL'|; % \item \texttt{(...\char`\|...)} denotes a series of options to choose from; +% \item |/.../| denotes a regular expression, like |/[a-z]+/|; % \item |[...]| denotes an optional substitution; % \item |{...}| denotes a zero or more times repetition; % \item \texttt{\char`\|\char`\|} denotes an indented vertical bar at the beginning of the string. @@ -120,6 +124,14 @@ % \item |$\vert$| instead of ``\texttt{\char`\|}''. % \end{itemize} +% They would look even better, if the following notation is used: +% \begin{itemize} +% \item |\char`\(| and |\char`\)| instead of ``|(|'' and ``|)|''; +% \item |\char`\<| and |\char`\>| instead of ``|<|'' and ``|>|''; +% \item |\char`\{| and |\char`\}| instead of ``|{|'' and ``|}|''; +% \item |\char`\[| and |\char`\]| instead of ``|[|'' and ``|]|''. +% \end{itemize} + % \DescribeMacro{width} % There is an optional argument of |ebnf| environment, which sets the width of the left-hand side of each rule % (the default width is |6em|): @@ -138,9 +150,9 @@ % \end{document} % \end{docshot} -% \DescribeMacro{\terminal} -% \DescribeMacro{\nonterminal} -% \DescribeMacro{\sterminal} +% \DescribeMacro{\EbnfTerminal} +% \DescribeMacro{\EbnfNonTerminal} +% \DescribeMacro{\EbnfSpecial} % Inside the text, terminals, non-terminals, and special terminals may be formatted using three supplementary commands: % \docshotOptions{firstline=6,lastline=10} % \begin{docshot} @@ -149,11 +161,11 @@ % \usepackage[paperwidth=3in]{geometry} % \usepackage{naive-ebnf} % \begin{document} -% The non-terminal \nonterminal{Var} +% The non-terminal \EbnfNonTerminal{Var} % in $\lambda$-calculus may be equal % to $v_1, v_2, \dots$. Application -% starts with \terminal{(} and ends -% with \terminal{)}. +% starts with \EbnfTerminal{(} and ends +% with \EbnfTerminal{)}. % \end{document} % \end{docshot} % It's possible to use them in math-mode too, for example: @@ -164,28 +176,62 @@ % \usepackage[paperwidth=3in]{geometry} % \usepackage{naive-ebnf} % \begin{document} -% If $\terminal{(} f_1 -% \nonterminal{$\lambda$-Var} -% \terminal{)}$ is always true, then +% If $\EbnfTerminal{(} f_1 +% \EbnfNonTerminal{$\lambda$-Var} +% \EbnfTerminal{)}$ is always true, then % $f_1$ is a tautology. % \end{document} % \end{docshot} +% \DescribeMacro{\EbnfRegex} +% A regular expression is possible too: +% \docshotOptions{firstline=6,lastline=11} +% \begin{docshot} +% \documentclass{article} +% \pagestyle{empty} +% \usepackage[paperwidth=4in]{geometry} +% \usepackage{naive-ebnf} +% \begin{document} +% \begin{ebnf}[1.5in] +% <data> := <bool> | <integer> | <byte> \\ +% <bool> := "TRUE" | "FALSE" \\ +% <integer> := /(+\char`\|-)?[0-9]+/ \\ +% <byte> := /[0-9a-f]\char`\{2\char`\}/ \\ +% \end{ebnf} +% \end{document} +% \end{docshot} + % Special symbols are interpreted correctly, if they stay inside quotes: -% \docshotOptions{} +% \docshotOptions{firstline=5,lastline=9} % \begin{docshot} % \documentclass{minimal} % \usepackage[T1]{fontenc} % \usepackage{naive-ebnf} -% \begin{document}\noindent +% \begin{document} % \begin{ebnf}[1.5in] % <X> := 'EOL' "'" "|" \\ -% <Y> := ">" "<" "]" "[" \\ +% <Y> := ">" "<" "[" "]" "/" "/" \\ % <Z> := "\LaTeX" "\textdollar" \\ % \end{ebnf} % \end{document} % \end{docshot} +% Nested brackets work fine too: +% \docshotOptions{firstline=5,lastline=10} +% \begin{docshot} +% \documentclass{minimal} +% \usepackage[T1]{fontenc} +% \usepackage{naive-ebnf} +% \begin{document} +% \begin{ebnf}[1.5in] +% <x> := ( "x" ( "y" | ( "z" | <z> ) ) ) \\ +% <y> := [ [ "x1" ] { /[a-z]+/ } ] \\ +% <z> := { { { <x> } <y> } <z> } \\ +% <t> := [ <x> ] [ <y> ] \\ +% \end{ebnf} +% \end{document} +% \end{docshot} + % \section{Package Options} % It's possible to configure the behavior of the package with the help of a few package options: @@ -251,13 +297,13 @@ % \end{macrocode} % \end{macro} -% \begin{macro}{\terminal} -% \changes{0.0.2}{2023/01/29}{New command \texttt{\char`\\terminal} added, to enable rendering terminal symbols outside of the \texttt{ebnf} environment.} +% \begin{macro}{\EbnfTerminal} +% \changes{0.0.2}{2023/01/29}{New command \texttt{\char`\\EbnfTerminal} added, to enable rendering terminal symbols outside of the \texttt{ebnf} environment.} % \changes{0.0.3}{2023/01/30}{Quotes fixed in both text and math modes.} -% Then, we a command to render a single terminal: +% Then, we define a command to render a single terminal: % \begin{macrocode} \makeatletter -\newcommand\terminal[1]{{% +\newcommand\EbnfTerminal[1]{{% \relax\ifmmode\else\ttfamily\fi% \ebnf@color{gray}{\relax\ifmmode\textsf{``}\else{\sffamily``}\fi}% #1% @@ -266,12 +312,12 @@ % \end{macrocode} % \end{macro} -% \begin{macro}{\nonterminal} -% \changes{0.0.2}{2023/01/29}{New command \texttt{\char`\\nonterminal} added, to enable rendering non-terminal symbols outside of the \texttt{ebnf} environment.} -% Then, we a command to render a single non-terminal: +% \begin{macro}{\EbnfTerminal} +% \changes{0.0.2}{2023/01/29}{New command \texttt{\char`\\EbnfNonTerminal} added, to enable rendering non-terminal symbols outside of the \texttt{ebnf} environment.} +% Then, we define a command to render a single non-terminal: % \begin{macrocode} \makeatletter -\newcommand\nonterminal[1]{{% +\newcommand\EbnfNonTerminal[1]{{% \ebnf@color{gray}{\relax\ifmmode\langle\else\(\langle\)\fi}% \relax\ifmmode\textsf{#1}\else{\sffamily#1}\fi% \ebnf@color{gray}{\relax\ifmmode\rangle\else\(\rangle\)\fi}}} @@ -279,12 +325,22 @@ % \end{macrocode} % \end{macro} -% \begin{macro}{\sterminal} -% \changes{0.0.6}{2023/05/27}{New command \texttt{\char`\\sterminal} added, to enable rendering of special non-printable terminal symbols outside of the \texttt{ebnf} environment.} -% Then, we a command to render a single non-terminal: +% \begin{macro}{\EbnfSpecial} +% \changes{0.0.6}{2023/05/27}{New command \texttt{\char`\\EbnfSpecial} added, to enable rendering of special non-printable terminal symbols outside of the \texttt{ebnf} environment.} +% Then, we define a command to render a single non-terminal: % \begin{macrocode} \makeatletter -\newcommand\sterminal[1]{{\relax\ifmmode\else\ttfamily\fi#1}}% +\newcommand\EbnfSpecial[1]{{\relax\ifmmode\else\ttfamily\fi#1}}% +\makeatother +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\EbnfRegex} +% \changes{0.0.8}{2023/07/11}{New command \texttt{\char`\\EbnfRegex} added, to enable rendering of regular expresions outside of the \texttt{ebnf} environment.} +% Then, we define a command to render a regular expression: +% \begin{macrocode} +\makeatletter +\newcommand\EbnfRegex[1]{{\relax\ifmmode\else\ttfamily\fi/#1/}}% \makeatother % \end{macrocode} % \end{macro} @@ -302,17 +358,22 @@ \newcommand\ebnf@terminal[1]{ \tl_set:Nn \l_ebnf_tl {} \tl_set_rescan:Nnn \l_ebnf_tl {} { #1 } - \terminal{\l_ebnf_tl} + \EbnfTerminal{\l_ebnf_tl} } -\newcommand\ebnf@sterminal[1]{ +\newcommand\ebnf@special[1]{ \tl_set:Nn \l_ebnf_tl {} \tl_set_rescan:Nnn \l_ebnf_tl {} { #1 } - \sterminal{\l_ebnf_tl} + \EbnfSpecial{\l_ebnf_tl} } \newcommand\ebnf@nonterminal[1]{ \tl_set:Nn \l_ebnf_tl {} \tl_set_rescan:Nnn \l_ebnf_tl {} { #1 } - \nonterminal{\l_ebnf_tl} + \EbnfNonTerminal{\l_ebnf_tl} +} +\newcommand\ebnf@regexp[1]{ + \tl_set:Nn \l_ebnf_tl {} + \tl_set_rescan:Nnn \l_ebnf_tl {} { #1 } + \EbnfRegex{\l_ebnf_tl} } \ExplSyntaxOff \newcommand\ebnf@to @@ -323,51 +384,69 @@ % \end{macrocode} % \begin{macro}{ebnf} -% \changes{0.0.4}{2023/02/03}{Any symbols are allowed inside \texttt{\char`\\nonterminal} commands and inside the \texttt{ebnf} environment, where non-terminals are mentioned.} +% \changes{0.0.4}{2023/02/03}{Any symbols are allowed inside \texttt{\char`\\EbnfNonTerminal} commands and inside the \texttt{ebnf} environment, where non-terminals are mentioned.} +% \changes{0.0.11}{2023/07/12}{Many bugs fixed in the area of regular expression matching.} % Then, we define the |ebnf| environment: % \begin{macrocode} \ExplSyntaxOn \cs_generate_variant:Nn \tl_replace_all:Nnn {Nx} \makeatletter \NewDocumentEnvironment{ebnf}{O{4em}+b} - {\tl_set:Nn\l__ebnf_tmp_tl{#2}} + {\tl_set:Nn\ebnf_tmp{#2}} {% - \regex_replace_all:nnN { ([^\ ])< } {\1\\textless{}} \l__ebnf_tmp_tl% - \regex_replace_all:nnN { >([^\ ]) } {\\textgreater{}\1} \l__ebnf_tmp_tl% - \regex_replace_all:nnN { ([^\ ])'([^\ ]) } {\1\\textquotesingle{}\2} \l__ebnf_tmp_tl% - \regex_replace_all:nnN { ([^\ ])\|([^\ ]) } {\1\\textbar{}\2} \l__ebnf_tmp_tl% + \regex_replace_all:nnN + { ([^\ ])/([^\ ]) } {\1\\slash{}\2} \ebnf_tmp% + \regex_replace_all:nnN + { ([^\ ])< } {\1\\textless{}} \ebnf_tmp% + \regex_replace_all:nnN + { >([^\ ]) } {\\textgreater{}\1} \ebnf_tmp% + \regex_replace_all:nnN + { ([^\ ])'([^\ ]) } {\1\\textquotesingle{}\2} \ebnf_tmp% + \regex_replace_all:nnN + { ([^\ ])\|([^\ ]) } {\1\\textbar{}\2} \ebnf_tmp% % - \regex_replace_all:nnN { \{\ (.+?)\ \} }% - {\c{ebnf@repetition}{\1}} \l__ebnf_tmp_tl% - \regex_replace_all:nnN { \(\ (.+?)\ \) }% - {\c{ebnf@grouping}{\1}} \l__ebnf_tmp_tl% - \regex_replace_all:nnN { \[\ (.+?)\ \] }% - {\c{ebnf@optional}{\1}} \l__ebnf_tmp_tl% + \regex_replace_all:nnN { \ /(.+?)/\ }% + {\c{ebnf@regexp}{\1}} \ebnf_tmp% + \cs_new:Npn\ebnf_curled{% + \regex_replace_all:nnNT + { \{\ (([^\ ]*(\ [^\}\{]|\ (\}|\{)[^\ ])?)*)\ \} }% + {\c{ebnf@repetition}{\1}} \ebnf_tmp \ebnf_curled}% + \ebnf_curled% + \cs_new:Npn\ebnf_brackets{% + \regex_replace_all:nnNT + { \(\ (([^\ ]*(\ [^\)\(]|\ (\)|\()[^\ ])?)*)\ \) }% + {\c{ebnf@grouping}{\1}} \ebnf_tmp \ebnf_brackets}% + \ebnf_brackets% + \cs_new:Npn\ebnf_squares{% + \regex_replace_all:nnNT + { \[\ (([^\ ]*(\ [^\]\[]|\ (\]|\[)[^\ ])?)*)\ \] }% + {\c{ebnf@optional}{\1}} \ebnf_tmp \ebnf_squares}% + \ebnf_squares% \regex_replace_all:nnN { (<[^>]+?>\ :=) }% - {\c{makebox}[#1][r]{\1}} \l__ebnf_tmp_tl% + {\c{makebox}[#1][r]{\1}} \ebnf_tmp% \regex_replace_all:nnN { <(.+?)> }% - {\c{ebnf@nonterminal}{\1}} \l__ebnf_tmp_tl% + {\c{ebnf@nonterminal}{\1}} \ebnf_tmp% \regex_replace_all:nnN { "(.+?)" }% - {\c{ebnf@terminal}{\1}} \l__ebnf_tmp_tl% + {\c{ebnf@terminal}{\1}} \ebnf_tmp% \regex_replace_all:nnN { '(.+?)' }% - {\c{ebnf@sterminal}{\1}} \l__ebnf_tmp_tl% + {\c{ebnf@special}{\1}} \ebnf_tmp% \regex_replace_all:nnN { \|(\|) }% - {\c{makebox}[#1][r]{ \1 }} \l__ebnf_tmp_tl% + {\c{makebox}[#1][r]{ \1 }} \ebnf_tmp% \regex_replace_all:nnN { \| }% - {\c{ebnf@alternation}{}} \l__ebnf_tmp_tl% + {\c{ebnf@alternation}{}} \ebnf_tmp% \regex_replace_all:nnN { := }% - {\c{ebnf@to}{}} \l__ebnf_tmp_tl% - \tl_put_left:Nn \l__ebnf_tmp_tl {\noindent} - \tl_put_right:Nn \l__ebnf_tmp_tl {} + {\c{ebnf@to}{}} \ebnf_tmp% + \tl_put_left:Nn \ebnf_tmp {\noindent} + \tl_put_right:Nn \ebnf_tmp {} \ifdefined\ebnf@trail% \newwrite\ebnf@write% \immediate\openout\ebnf@write\ebnf@trail\relax% - \immediate\write\ebnf@write{\unexpanded\expandafter{\l__ebnf_tmp_tl}}% + \immediate\write\ebnf@write{\unexpanded\expandafter{\ebnf_tmp}}% \immediate\closeout\ebnf@write% \message{naive-ebnf:\space pre-processed\space TeX \space saved\space to\space "\ebnf@trail"^^J}% \fi% - \l__ebnf_tmp_tl} + \ebnf_tmp} \makeatother \ExplSyntaxOff % \end{macrocode} diff --git a/macros/latex/contrib/naive-ebnf/naive-ebnf.pdf b/macros/latex/contrib/naive-ebnf/naive-ebnf.pdf Binary files differindex d15fe959a6..f017dfaa0d 100644 --- a/macros/latex/contrib/naive-ebnf/naive-ebnf.pdf +++ b/macros/latex/contrib/naive-ebnf/naive-ebnf.pdf |