From 09fb10e18bc08cea7aa46f661f3643b4bc6cde4c Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 13 Nov 2021 21:13:55 +0000 Subject: formal-grammar (12nov21) git-svn-id: svn://tug.org/texlive/trunk@61046 c570f23f-e606-0410-a88d-b1316a301751 --- .../source/latex/formal-grammar/formal-grammar.dtx | 384 +++++++++++++++++++++ .../source/latex/formal-grammar/formal-grammar.ins | 49 +++ 2 files changed, 433 insertions(+) create mode 100644 Master/texmf-dist/source/latex/formal-grammar/formal-grammar.dtx create mode 100644 Master/texmf-dist/source/latex/formal-grammar/formal-grammar.ins (limited to 'Master/texmf-dist/source/latex/formal-grammar') diff --git a/Master/texmf-dist/source/latex/formal-grammar/formal-grammar.dtx b/Master/texmf-dist/source/latex/formal-grammar/formal-grammar.dtx new file mode 100644 index 00000000000..92bf02e8710 --- /dev/null +++ b/Master/texmf-dist/source/latex/formal-grammar/formal-grammar.dtx @@ -0,0 +1,384 @@ +% \iffalse meta-comment +% Copyright (C) 2021 by Martin Vassor +% This file may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either +% version 1.3 of this license or (at your option) any later +% version. The latest version of this license is in: +% +% http://www.latex-project.org/lppl.txt +% +% and version 1.3 or later is part of all distributions of +% LaTeX version 2005/12/01 or later. +% +% \fi + + + +% \iffalse +%\NeedsTeXFormat{LaTeX2e} +%\ProvidesPackage{formal-grammar}[2021/11/10 v1.0 A package to typeset formal grammars] +%\RequirePackage{xparse} +%\RequirePackage{float} +%\RequirePackage{xcolor} +%\RequirePackage{colortbl} +%\RequirePackage{array} +%\definecolor{LightCyan}{rgb}{0.8,1,1} +%<*driver> +\documentclass{ltxdoc} +\usepackage{formal-grammar} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{formal-grammar.dtx} +\end{document} +% +% \fi +% +% \CheckSum{83} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2021/11/21}{Initial version for publication} +% +% \GetFileInfo{formal-grammar.sty} +% +% \title{The \textsf{formal-grammar} package\thanks{This document +% corresponds to \textsf{formal-grammar}~\fileversion, +% dated \filedate.}} +% \author{Martin Vassor\\ \texttt{bromind+ctan@gresille.org}} +% +% \maketitle +% +%\iffalse +%% \begin{abstract} +%% The \textsf{formal-grammar} package provides commands to typeset formal grammars. +%% \end{abstract} +%\fi +% \tableofcontents +% +% \section{Introduction} +% +% This package provides a new environment (|grammar|) and associated commands to +% typeset BNF grammars. It allows to easily write formal grammars, for instance +% the syntax of the \(\lambda\) calculus is given in Grammar~\ref{gr:lambda}. +% +%\begin{grammar}[\(\lambda\) calculus syntax][][gr:lambda] +% \firstcase{T}{\nonterm{V}}{Variable} +% \highlight +% \otherform{(\nonterm{T}\ \nonterm{T})}{Application} +% \highlight +% \otherform{\lambda \nonterm{V}\cdot\nonterm{T}}{Abstraction} +% \downplay +% \firstcase{V}{x, y, \dots}{Variables} +%\end{grammar} +% +% \section{Usage} +% \subsection{Basic usage} +% +% \paragraph{Creating a grammar.} +% We first start creating a grammar using the |grammar| environment. +% +% \DescribeEnv{grammar} +% This is the main environment to write your grammar. |grammar| accepts 3 +% optional arguments: the first one is a possible caption; the second is a +% positionning option; and the third is a label. +% +% If none of the optional arguments is provided, the grammar is inlined (i.e. +% not in a float environment. If the first argument is set (the optional +% caption), the grammar is typeset in a float, captionned with the provided +% caption. +% The second optional argument is a positionning option (one of \texttt{t}, +% \texttt{b}, \texttt{p}, \texttt{h}, etc.). The default is \texttt{p}. +% The last argument is a label, used to reference the grammar elsewhere in the +% document. +% +% The grammar can then be populated using two basic constructs: |firstcase| and +% |otherform|. +% +% \DescribeMacro{\firstcase} +% The |firstcase| command creates a new non-terminal of the grammar. It takes 3 mandatory +% arguments: the letter(s) of the non-terminal, the definition, and an +% explanation. +% \DescribeMacro{\otherform} +% On the other hand, |otherform| create an alternative for the preceding +% non-terminal, on a new line. It takes two arguments: the definition of the +% alternative, and an explanation. For instance, the following grammar typesets +% as the grammar in Grammar~\ref{gr:simple_grammar}. +% \begin{verbatim} +% \begin{grammar}[A simple grammar][t][gr:simple_grammar] +% \firstcase{A}{()}{Parenthesis} +% \otherform{\{\}}{Curly brackets} +% \end{grammar} +% \end{verbatim} +% \begin{grammar}[A simple grammar][t][gr:simple_grammar] +% \firstcase{A}{()}{Parenthesis} +% \otherform{\{\}}{Curly brackets} +% \end{grammar} +% +% \paragraph{Referencing non-terminals} +% +% \DescribeMacro{\nonterm} +% This allows you to typeset a symbol as a non-terminal. In the current version, +% the default typesetting is to wrap in a \verb+\mathcal+ command. This allow +% to reference those non-terminals, both in grammar rules and elsewhere in the +% document. Notice that, since the typesetting is just a wrapper over +% \verb+\mathcal+, it should be used in a math environment. For instance, the +% only non-terminal of Grammar~\ref{gr:simple_grammar} is \(\nonterm{A}\) +% (\verb+\(\nonterm{A}\)+). +% +% +% \subsection{Advanced capabilities} +% In this subsection, we will explain the more advanced capabilities of the +% package. These would allow to typeset more complex grammars such as the one +% displayed in Grammar~\ref{gr:advanced_grammar}. +% +% \begin{grammar}[A more advanced grammar][t][gr:advanced_grammar] +% \firstcase{B}{(\nonterm{B})\gralt \{\nonterm{B}\}}{Nested parenthesis or brackets} +% \firstcasesubtil{\(\nonterm{C}_1\)}{\nonterm{B}}{Example of subtil non-terminal} +% \highlight +% \firstcase{D}{\nonterm{B}}{An interesting line} +% \downplay +% \otherform{\nonterm{D}}{An uninteresting line} +% \otherform{\lochighlight{\nonterm{D} + \nonterm{D}} +% \gralt \nonterm{A}}{Important item} +% \end{grammar} +% +% \paragraph{Variants on the same line.} +% \DescribeMacro{\gralt} +% When variants are short and simple, it is possible to display multiple of them +% on the same line using |\gralt|. For instance, the first line of +% Grammar~\ref{gr:advanced_grammar} is typeset with the following command: +% \begin{verbatim} +% \firstcase{B}{(\nonterm{B})\gralt \{\nonterm{B}\}}{Nested parenthesis or brackets} +% \end{verbatim} +% \paragraph{Subtle typesetting of non-terminals} +% Since nonterminal are, by default, typeset using \verb+\mathcal+, it can lead +% to the usual issues of \verb+\mathcal+ (typically, for lowercases). Therefore, we provide \emph{subtle} +% variants of |\firstcase| and |\nonterm|, in which the non-terminal symbol is +% not typeset (i.e. as the user, you have to typeset it manually). +% +% \DescribeMacro{\nontermsubtil} +% This is equivalent to |\nonterm|, but where typesetting is left to the user. +% In the current implementation does nothing. However users are encouraged to +% use it for future modifications of the package. For instance, it is possible +% to typeset a non-terminal with a number index as follow +% \(\nontermsubtil{\nonterm{C}_1}\) with the following command: +% \verb+\(\nontermsubtil{\nonterm{C}_1}\)+ +% +% \DescribeMacro{\firstcasesubtil} +% The subtil variant of |\firstcase|. Works similarly, except that the +% non-terminal (i.e. the first argument) is not embedded in a \verb+\mathcal+ +% macro. For instance, the \(\nontermsubtil{\nonterm{C}_1}\) in +% Grammar~\ref{gr:advanced_grammar} is typeset with the following command: +% \begin{verbatim} +% \firstcasesubtil{\(\nonterm{C}_1\)}{\nonterm{B}}{Example of subtil non-terminal} +% \end{verbatim} +% +% \paragraph{Highlighting and downplaying variants} +% Three commands are provided to highlight or downplay some part of a grammar. +% |\highlight| highlights a whole line, |\loghighlight| highlights a part of a +% line, while |\downplay| downplays a line. +% +% \DescribeMacro{\downplay} +% \DescribeMacro{\highlight} +% The two commands |\highlight| and |\downplay| work similarly: when used before +% a |\firstcase|, |\firstcasesubtil|, or |\otherform|, the next line is +% highlighted in blue, or printed in light grey. For instance, in +% Grammar~\ref{gr:advanced_grammar}, the rule for non-terminal \(\nonterm{D}\) +% is typeset with: +% \begin{verbatim} +% \highlight +% \firstcase{D}{\nonterm{B}}{An interesting line} +% \downplay +% \otherform{\nonterm{D}}{An uninteresting line} +% \end{verbatim} +% +% \DescribeMacro{\lochighlight} +% For more local highlighting, it is possible to use |\lochighlight|, which +% prints some part of a rule in red. The last line of +% Grammar~\ref{gr:advanced_grammar}, which contains such local highlight, is +% typeset with the following command: +% \begin{verbatim} +% \otherform{\lochighlight{\nonterm{D} + \nonterm{D}} +% \gralt \nonterm{A}}{Important item} +% \end{verbatim} +% +% \StopEventually{\PrintIndex} +% +% \section{Implementation} +% +% \begin{environment}{floatgrammar} +% This is a new float that contains floating grammars. This is needed so that +% they are labeled with 'Grammar'. +% \begin{macrocode} +\newfloat{floatgrammar}{t b h p}{.gram} +\floatname{floatgrammar}{Grammar} +% \end{macrocode} +% \end{environment} +% +%\iffalse +%% Taken from https://tex.stackexchange.com/a/26364/107341 +%\fi +% +% \begin{macro}{\@rowstyle} +% The default \verb+rowstyle+ is empty. +% \begin{macrocode} +\newcommand*{\@rowstyle}{} +% \end{macrocode} +% \end{macro} +% + +% \begin{macro}{\rowstyle} +% An internal command used to set the style of a row. In addition, we add column +% types to reset the style (\verb:=:) and to keep the style from one column to +% the other (\verb:+:). +% \begin{macrocode} +\newcommand*{\rowstyle}[1]{% sets the style of the next row + \gdef\@rowstyle{#1}% + \@rowstyle\ignorespaces% +} +% \end{macrocode} +% \begin{macrocode} +\newcolumntype{=}{% resets the row style + >{\gdef\@rowstyle{}}% +} + +\newcolumntype{+}{% adds the current row style to the next column + >{\@rowstyle}% +} +% \end{macrocode} +% \end{macro} +%\iffalse +%% End of stackexchange +%\fi +% +% \begin{environment}{grammar} +% This is the implementation of the |grammar| environment. The main difficulty +% is to check whether optional arguments are provided. If the first is provided, +% we embed the grammar into a \verb+floatgrammar+; then if the second argument +% is provided, we use it as the position, (otherwise, we use \verb+p+). Finally, +% if the third argument is provided, we use it as a label. +% \begin{macrocode} +\ExplSyntaxOn +%% 1st argument: caption (makes it float) +%% 2nd argument: positionning option (`p` by default) +%% 3rd argument: label + \NewDocumentEnvironment{grammar} {o o o} + { + \IfNoValueTF{#1} { + }{ + \IfNoValueTF{#2}{ + \begin{floatgrammar}[p] + } { + \begin{floatgrammar}[#2] + } + \centering + } + + \begin{tabular}{=l +r +l +l} + }{ + \end{tabular} + + \IfNoValueTF{#1} { + \linebreak + } { + \caption{#1} + \IfNoValueTF{#3}{ + } { + \label{#3} + } + \end{floatgrammar} + } + } +\ExplSyntaxOff +% \end{macrocode} +% \end{environment} + +% \begin{macro}{\firstcase} +% The |\firstcase| is typeset as a new line in the array, which first cell is +% the symbol of the non-terminal, the second cell is just \(::=\), the third +% cell is the rule (it is directly printed, without any modification), and the +% last cell is the description of the rule, in greyish color. +% \begin{macrocode} +\newcommand{\firstcase}[3]{\(\mathcal{#1}\) & \(::=\) & \(#2\) & {\itshape \color{gray!90!black} #3}\\} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\firstcasesubtil} +% The |\firstcasesubtil| is implemented similarly to |\firstcase|, except that +% the first argument is not surrounded by \verb+\mathcal+. +% \begin{macrocode} +\newcommand{\firstcasesubtil}[3]{#1 & \(::=\) & \(#2\) & {\itshape \color{gray!90!black} #3}\\} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\otherform} +% Adds a line with an empty first cell, and which second cell is just a pipe. +% The third and fourth cells are similar to |\firstcase|. +% \begin{macrocode} +\newcommand{\otherform}[2]{& \(|\) & \(#1\) & {\itshape \color{gray!90!black} #2}\\} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\nonterm} +% Typesets in \verb+\mathcal+. +% \begin{macrocode} +\newcommand{\nonterm}[1]{\mathcal{#1}} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\nontermsubtil} +% Does nothing right now. +% \begin{macrocode} +\newcommand{\nontermsubtil}[1]{#1} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\gralt} +% |\gralt| is simply a pipe surrounded by large spaces. +% \begin{macrocode} +\newcommand{\gralt}[0]{\quad |\quad } +% \end{macrocode} +% \end{macro} + + +% \begin{macro}{\highlight} +% We simply set the row color to LightCyan. +% \begin{macrocode} +\newcommand{\highlight}[0]{\rowcolor{LightCyan}} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\lochighlight} +% We simply surround the argument with red. +% \begin{macrocode} +\newcommand{\lochighlight}[1]{{\color{red} #1}} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\downplay} +% We simply apply a style that write in light grey for the row. +% \begin{macrocode} +\newcommand{\downplay}[0]{\rowstyle{\color{white!80!black}}} +% \end{macrocode} +% \end{macro} +% +% +% \Finale +\endinput diff --git a/Master/texmf-dist/source/latex/formal-grammar/formal-grammar.ins b/Master/texmf-dist/source/latex/formal-grammar/formal-grammar.ins new file mode 100644 index 00000000000..23254393efb --- /dev/null +++ b/Master/texmf-dist/source/latex/formal-grammar/formal-grammar.ins @@ -0,0 +1,49 @@ +%% +%% Copyright (C) 2021 by Martin Vassor +%% + +%% This file may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either +%% version 1.3 of this license or (at your option) any later +%% version. The latest version of this license is in: +%% +%% http://www.latex-project.org/lppl.txt +%% +%% and version 1.3 or later is part of all distributions of +%% LaTeX version 2005/12/01 or later. +%% + +\input docstrip.tex +\keepsilent +\usedir{tex/latex/formal-grammar} +\preamble +This is a generated file. +Copyright (C) 2021 by Martin Vassor + +This file may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either +version 1.3 of this license or (at your option) any later +version. The latest version of this license is in: + + http://www.latex-project.org/lppl.txt + +and version 1.3 or later is part of all distributions of +LaTeX version 2005/12/01 or later. + +\endpreamble + +\generate{\file{formal-grammar.sty}{\from{formal-grammar.dtx}{package}}} + +\Msg{*********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the} +\Msg{* following file into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space formal-grammar.sty} +\Msg{*} +\Msg{* To produce the documentation run the file grammar.dtx} +\Msg{* through LaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*********************************************************} +\endbatchfile -- cgit v1.2.3