From fe29944c3d5256062708e9b1ae62dc378f9d9993 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Mon, 9 May 2022 03:01:47 +0000
Subject: CTAN sync 202205090301

---
 macros/latex/contrib/simplebnf/simplebnf.sty | 126 +++++++++++++++++++++------
 1 file changed, 100 insertions(+), 26 deletions(-)

(limited to 'macros/latex/contrib/simplebnf/simplebnf.sty')

diff --git a/macros/latex/contrib/simplebnf/simplebnf.sty b/macros/latex/contrib/simplebnf/simplebnf.sty
index a8ae523036..fd7b707ff7 100644
--- a/macros/latex/contrib/simplebnf/simplebnf.sty
+++ b/macros/latex/contrib/simplebnf/simplebnf.sty
@@ -13,11 +13,13 @@
 \RequirePackage{mathtools}
 \ProvidesExplPackage
   {simplebnf}
-  {2020/09/01}
-  {0.2.0}
+  {2022/05/07}
+  {0.3.0}
   {A simple package to format Backus–Naur form}
 
-\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}
+\cs_generate_variant:Nn \regex_split:nnNTF {nVNTF}
+\cs_generate_variant:Nn \regex_split:NnN {NVN}
+
 \tl_new:N \g__simplebnf_defeq_tl
 \tl_gset:Nn \g__simplebnf_defeq_tl { \ensuremath{\Coloneqq} }
 
@@ -32,6 +34,9 @@
 \seq_new:N \l__keypairs_seq
 \bool_new:N \l__first_rhs
 
+\regex_new:N \g_simplebnf_rhs_newline_r
+\regex_new:N \g_simplebnf_rhs_nb_r
+
 %% Typeset a single rhs of a production.
 %% \l__first_rhs = true  => `::=' already typeset
 %% \l__first_rhs = false => move to a newline and typeset `|'
@@ -43,15 +48,18 @@
       \bool_set_false:N \l__first_rhs
     }
     {
-      \tl_put_right:Nn \l__table_tl { \\ & \g__simplebnf_defor_tl & }
+      \tl_put_right:Nn \l__table_tl { \\ && \g__simplebnf_defor_tl & }
     }
 
-  \regex_split:nnNTF { : } { #1 } \l_tmpa_seq
+  \tl_set:Nn \l_tmpa_tl { #1 }
+  \regex_replace_once:nnN { ^\s+ } {} \l_tmpa_tl
+  \regex_replace_once:nnN { \s+$ } {} \l_tmpa_tl
+  \regex_split:nVNTF { : } \l_tmpa_tl \l_tmpa_seq
     {
       \seq_pop_left:NNT \l_tmpa_seq \l_tmpa_tl
         {
-          \tl_set:Nx \l_tmpa_tl { \bnfexpr { \l_tmpa_tl } }
-          \tl_put_right:NV \l__table_tl \l_tmpa_tl
+          \regex_replace_all:NnN \g_simplebnf_rhs_nb_r { \c{g__simplebnf_defor_tl} } \l_tmpa_tl
+          \tl_put_right:Nx \l__table_tl { \bnfexpr { \l_tmpa_tl } }
         }
 
       \tl_put_right:Nn \l__table_tl { & }
@@ -63,34 +71,67 @@
         }
     }
     {
-      \tl_put_right:Nn \l__table_tl { \bnfexpr { #1 } &}
+      \regex_replace_all:NnN \g_simplebnf_rhs_nb_r { \c{g__simplebnf_defor_tl} } \l_tmpa_tl
+
+      \tl_put_right:Nx \l__table_tl { \bnfexpr { \l_tmpa_tl } }
+      \tl_put_right:Nn \l__table_tl { & }
+    }
+}
+
+%% Typeset a single lhs of a production.
+%% #1 - lhs : either term or (term : annotation)
+\cs_new:Nn \simplebnf_typeset_lhs:n
+{
+  \tl_set:Nx \l_tmpa_tl { #1 }
+  \regex_replace_once:nnN { ^\s+ } {} \l_tmpa_tl
+  \regex_replace_once:nnN { \s+$ } {} \l_tmpa_tl
+
+  \regex_split:nVNTF { : } \l_tmpa_tl \l_tmpa_seq
+    {
+      \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl
+      \tl_put_right:Nx \l__table_tl
+        {
+          \bnfannot{\l_tmpa_tl}
+        }
+      \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl
+      \tl_put_right:Nx \l__table_tl
+        {
+          & \bnfexpr { \l_tmpa_tl }
+        }
+    }
+    {
+      \tl_put_right:Nx \l__table_tl
+        {
+          & \bnfexpr { \l_tmpa_tl }
+        }
     }
 }
 
 \NewDocumentCommand \bnfexpr { m } { \texttt { #1 } }
 \NewDocumentCommand \bnfannot { m } { \textit{ #1 } }
 
-\NewDocumentEnvironment { bnfgrammar } { +b }
+%% Typeset a BNF grammar.
+%% #1 - tabular specification (llcll)
+%% #2 - regexp for newline separator for rhses
+%% #2 - regexp for non-breaking separator for rhses
+%% #3 - grammar
+\NewDocumentEnvironment { bnfgrammar } { O{llcll} O{[^\|]\|[^\|]} O{\|\|} +b }
   {
+    \regex_gset:Nn \g_simplebnf_rhs_newline_r { #2 }
+    \regex_gset:Nn \g_simplebnf_rhs_nb_r { #3 }
+
     %% \l__input_seq is a list of term definitions.
-    \regex_split:nnN { ;; } { #1 } \l__input_seq
+    \regex_split:nnN { ;; } { #4 } \l__input_seq
     \begin{center}
       \tl_set:Nn \l__table_tl
         {
-          \begin{tabular}{lcll}
+          \begin{tabular}{#1}
         }
+
     \bool_set_true:N \l_tmp_first_term % Is this the first term in this grammar?
     \seq_map_inline:Nn \l__input_seq
       {
-        %% \l__term_seq    - (term, rhses)...
-        %% \l__term_tl     - term
-        %% \l__keypairs_tl - rhses
-        \regex_split:nnN { ::= } { ##1 } \l__term_seq
-        \seq_pop_left:NN \l__term_seq \l__term_tl
-        \seq_pop_left:NN \l__term_seq \l__keypairs_tl
-
-        \regex_replace_once:nnN { ^\s+ } {} \l__term_tl
-
+        %% If not-first, add newline
         \bool_if:NTF \l_tmp_first_term
           {
             \bool_set_false:N \l_tmp_first_term
@@ -98,15 +139,48 @@
           {
             \tl_put_right:Nn \l__table_tl { \\ }
           }
-        \tl_put_right:Nx \l__table_tl
+
+        \regex_split:nnNTF { ::= } { ##1 } \l__term_seq
+          % Parse a ::= definition
           {
-            \bnfexpr { \l__term_tl } & \g__simplebnf_defeq_tl &
+            %% \l__term_seq    - (lhs, rhses)...
+            %% \l__term_tl     - lhs
+            %% \l__keypairs_tl - rhses
+            \seq_pop_left:NN \l__term_seq \l__term_tl
+            \seq_pop_left:NN \l__term_seq \l__keypairs_tl
+
+            \simplebnf_typeset_lhs:n{\l__term_tl}
+            \tl_put_right:Nx \l__table_tl
+              {
+                & \g__simplebnf_defeq_tl &
+              }
+            %% \l__keypairs_seq - (rhs:annot | rhs)...
+            \regex_split:NVN \g_simplebnf_rhs_newline_r \l__keypairs_tl \l__keypairs_seq
+
+            \bool_set_true:N \l__first_rhs
+            \seq_map_function:NN \l__keypairs_seq \simplebnf_typeset_rhs:n
           }
-        %% \l__keypairs_seq - (rhs:annot | rhs)...
-        \seq_set_split:NnV \l__keypairs_seq { | } \l__keypairs_tl
+          {
+            % Else, parse a \in declaration
+            \regex_split:nnNTF { \c{in} } { ##1 } \l__term_seq
+              {
+                %% \l__term_seq - (lhs, rhs)
+                \seq_pop_left:NN \l__term_seq \l_tmpa_tl
 
-        \bool_set_true:N \l__first_rhs
-        \seq_map_function:NN \l__keypairs_seq \simplebnf_typeset_rhs:n
+                \simplebnf_typeset_lhs:n{\l_tmpa_tl}
+                \tl_put_right:Nn \l__table_tl
+                  {
+                    & $\in$ & $
+                  }
+                \seq_pop_left:NN \l__term_seq \l_tmpa_tl
+                \tl_put_right:NV \l__table_tl \l_tmpa_tl
+                \tl_put_right:Nn \l__table_tl
+                  {
+                    $ &
+                  }
+              }
+              { \msg_error:nn {simplebnf} { Could not parser ##1 } }
+          }
       }
 
     \tl_put_right:Nn \l__table_tl { \end{tabular} }
-- 
cgit v1.2.3

