\documentclass[10pt]{article}

\usepackage{a4wide}
\usepackage{palatino}
\usepackage{euler}
\usepackage{amssymb}
\usepackage{stmaryrd}

\title{\EdiTeX: a MathML Editor Based on \TeX{} Syntax\\\small Description and Formal Specification}
\author{Paolo Marinelli\\Luca Padovani\\\small\{{\tt pmarinel},{\tt lpadovan}\}{\tt @cs.unibo.it}\\\small Department of Computer Science\\\small University of Bologna}
\date{}

\newcommand{\EdiTeX}{Edi\TeX}

\newcommand{\tmap}[1]{\llbracket#1\rrbracket}
\newcommand{\tadvance}{\vartriangle}
\newcommand{\tnext}{\rhd}
\newcommand{\G}{\texttt{g}}
\newcommand{\PNODE}{\texttt{p}}
\newcommand{\SNODE}{\texttt{s}}
\newcommand{\INODE}{\texttt{i}}
\newcommand{\NNODE}{\texttt{n}}
\newcommand{\ONODE}{\texttt{o}}
\newcommand{\CNODE}{\texttt{c}}
\newcommand{\TABLE}{\texttt{table}}
\newcommand{\SP}{\texttt{sp}}
\newcommand{\SB}{\texttt{sb}}
\newcommand{\CELL}{\texttt{cell}}
\newcommand{\ROW}{\texttt{row}}
\newcommand{\SLDROP}{\blacktriangleleft}
\newcommand{\SLDSCRIPT}{\blacktriangleleft_{s}}
\newcommand{\NLDROP}{\vartriangleleft}
\newcommand{\RGROUP}{\vartriangleleft_{rg}}
\newcommand{\NLDGP}{\vartriangleleft_{g}}
\newcommand{\NLDSCRIPT}{\vartriangleleft_{s}}
\newcommand{\NLDMACRO}{\vartriangleleft_{c}}
\newcommand{\NLDTABLE}{\vartriangleleft_{t}}

\begin{document}

\maketitle

\section{Introduction}

MathML~\cite{MathML1,MathML2,MathML2E} is an XML application for the
representation of mathematical expressions. As most XML applications,
MathML is unsuitable to be hand-written, except for the simplest
cases, because of its verbosity. In fact, the MathML specification
explicitly states that
\begin{quote}
``While MathML is human-readable, it is anticipated that, in all but
the simplest cases, authors will use equation editors, conversion
programs, and other specialized software tools to generate MathML''
\end{quote}

The statement about human readability of MathML is already too strong,
as the large number of mathematical symbols, operators, and
diacritical marks that are used in mathematical notation cause MathML
documents to make extensive use of Unicode characters that typically
are not in the ``visible'' range of common text editors. Such
characters may appear as entity references, whose name indicates
somehow the kind of symbol used, or character references or they are
directly encoded in the document encoding scheme (for instance,
UTF-8).

It is thus obvious that authoring MathML documents assumes the
assistance of dedicated tools. As of today, such tools can be
classified into two main categories:
\begin{enumerate}
  \item WYSIWYG (What You See Is What You Get) editors that allow the
    author to see the formatted document on the screen as it is
    composed;
  \item conversion tools that generate MathML markup from different
    sources, typically other markup languages for scientific
    documents, such as \TeX.
\end{enumerate}

While the former tools are certainly more appealing, especially to the
unexperienced user, as they give a direct visual feedback, the
existance of tools in the second category takes into account the large
availability of existing documents in \TeX{} format, and also the fact
that experienced or ``lazy'' users may continue to prefer the use of a
markup language other than MathML for editing, and generate MathML
only as a final step of the authoring process. The ``laziness'' is not
really intended as a way of being reluctant towards a new technology,
but rather as a justified convincement that WYSIWYG editors are ``nice
to look at'' but after all they may slow down the authoring process.
WYSIWYG editors often involve the use of menus, palettes of symbols,
and, in general, an extensive use of the pointing device (the mouse)
for completing most operations. The use of shortcuts is of little
help, as it implies very soon a challenging exercise for the fingers
and the mind. Moreover, authors \emph{cannot improve} their authoring
speed with time.  On the other side, the gap between the syntax of any
markup language for mathematics and mathematical notation may be
relevant, especially for large, non-trivial formulas and authoring is
a re-iterated process in which the author repeadtedly types the markup
in the editor, compiles, and looks at the result inside a pre-viewer.

\EdiTeX{} tries to synthesize the ``best of both worlds'' in a single
tool. The basic idea is that of creating a WYSIWYG editor in which
editing is achieved by typing \TeX{} markup as the author would do in
a text editor. The \TeX{} markup is tokenized and parsed on-the-fly
and a corresponding MathML representation is created and
displayed. This way, the author can see the rendered document as it
changes. The advantages of this approach can be summarized as follows:
\begin{itemize}
  \item the document is rendered concurrently with the editing, the
    user has an immediate feedback hence it is easier to spot errors;
  \item the author types in a concrete (and likely familiar) syntax
    improving the editing speed;
  \item the usual WYSIWYG mechanisms are still available. In
    particular, it is possible to select \emph{visually} a fragment of
    the document that needs re-editing, or that was left behind for
    subsequent editing.
\end{itemize}

\paragraph{The Name of the Game:} there is no reference to MathML in
the name ``\EdiTeX.'' In fact, the architecture of the editor is not
tied to MathML markup. Although we focus on MathML editing, by
changing a completely modularized component of the editor it is
virtually possible to generate any other markup language.

\paragraph{Acknowledgments.} Stephen M. Watt and Igor Rodionov for
their work on the \TeX{} to MathML conversion tool; Stan Devitt for an
illuminating discussion about the architecture of \TeX{} to XML
conversion tools; Claudio Sacerdoti Coen for the valuable feedback and
uncountable bug reports.

\section{Architecture}

\section{Customization}

\subsection{Short and Long Identifiers}

\subsection{The Dictionary}

\subsection{Stylesheets and Trasformations}

\subsection{Rendering}

\section{XML Representation of \TeX{} Markup}

\section{Tokens}

The following tokens are defined:

\begin{tabular}{lllp{0.5\textwidth}}
  \textbf{\TeX{}} & \textbf{Notation} & \textbf{Node} & \textbf{Description} \\
\hline
  \verb+{+ & $\mathrm{begin}$ & \texttt{g} & Beginning of a group \\
  \verb+}+ & $\mathrm{end}$ & & End of a group \\
  \verb+$+ & $\$$ & \texttt{math} & Math shift \\ %$ \\
  & &  & End-of-line \\
  \verb+#+$i$ & $p(i)$ & \texttt{p} & Parameter \\
  \verb+^+ & $\uparrow$ & \texttt{sp} & Superscript \\
  \verb+_+ & $\downarrow$ & \texttt{sb} & Subscript \\
  & $\square$ & & Space-like character that can be ignored \\
  & $s$ & \texttt{s} & Space-like character that may be significant \\
  letter & $i(v)$ & \texttt{i} & Identifier $v$ \\
  digit & $n(v)$ & \texttt{n} & Number $v$ \\
  other & $o(v)$ & \texttt{o} & Other character or operator $v$ \\
  \verb+~+ & $\sim$ & & Active character \\
  \verb+%+ & $\%$ & & Comment \\
  control & $c(v)\langle\alpha_1,\dots,\alpha_n\rangle$ & \texttt{c} & 
    Control sequence $v$ that expects the $\alpha_1,\dots,\alpha_n$ sequence of tokens. \\
  backspace & $\vartriangleleft$ & & \\
  backspace & $\blacktriangleleft$ & & \\
\end{tabular}

%% Some tokens are mapped directly into nodes of the TML tree. The following functions shows
%% the mapping:

\begin{tabular}{r@{\quad$=$\quad}l}
  $\tmap{\{}$ & \verb+g+ \\
  $\tmap{p(i)}$ & \verb+p[@index=+$i$\verb+]+ \\
  $\tmap{p_l(i)}$ & \verb+p[@index=+$i$\verb+][@left-open='1']+ \\
  $\tmap{p_r(i)}$ & \verb+p[@index=+$i$\verb+][@right-open='1']+ \\
  $\tmap{s}$ & \verb+s+ \\
  $\tmap{\uparrow}$ & \verb+sp+ \\
  $\tmap{\downarrow}$ & \verb+sb+ \\
  $\tmap{i(v)}$ & \verb+i[@value=+$v$\verb+]+ \\
  $\tmap{n(v)}$ & \verb+n[@value=+$v$\verb+]+ \\
  $\tmap{o(v)}$ & \verb+o[@value=+$v$\verb+]+ \\
  $\tmap{c(v)\langle\alpha_1,\dots,\alpha_n\rangle}$ & \verb+c[@name=+$v$\verb+][^+$\tmap{\alpha_1}\cdots\tmap{\alpha_n}$\verb+$]+\\
\end{tabular}
%$

%% \section{Description and Semantics of the Pattern Language}

%% \begin{eqnarray*}
%%   \mathit{NodeTest} & ::= & \mathtt{*} \\
%%   & | & \mathit{ElementType} \\
%%   & | & \mathtt{<}~\mathit{ElementTypePattern}~\mathtt{>} \\[1ex]
%%   \mathit{ElementTypePattern} & ::= & \mathtt{*} \\
%%   & | & \mathit{ElementType}~(\mathtt{|}~\mathit{ElementType})^* \\
%%   & | & \mathtt{!}\mathit{ElementType}~(\mathtt{|}~\mathit{ElementType})^*\\[1ex]
%%   \mathit{NodePattern} & ::= & \mathit{NodeTest}~\mathit{AttributeQualifier}^*\\[1ex]
%%   \mathit{AttributeQualifier} & ::= & \mathtt{[@}\mathit{AttributeTest}\mathtt{]}\\
%%   & | & \mathtt{[!@}\mathit{AttributeTest}\mathtt{]}\\[1ex]
%%   \mathit{AttributeTest} & ::= & \mathit{AttributeName} \\
%%   & | & \mathit{AttributeName}\mathtt{='}\mathit{Text}\mathtt{'}
%% \end{eqnarray*}

\section{Insert Rules}

\paragraph{Begin Group:} $\{$

\begin{description}
  \item{\verb+table/cursor+}\\
   create a \texttt{row} node, create a \texttt{cell} node, create a \texttt{g} node,
    append the cursor to the \texttt{g} node, append the \texttt{g} node to the \texttt{cell} node,
    append the \texttt{cell} node to the \texttt{row} node, append the \texttt{row} node to the
    \texttt{c} node 
  \item{\verb+cursor+} \\ create a \texttt{g} node, replace the cursor with the new \texttt{g} node,
    append the cursor to the new \texttt{g} node
\end{description}

% CASE: c/g[!@id]/cursor

% CASE: c/cursor

% ELSE:

% do_begin:
% CASE: c[@table='1']/cursor
% ELSE:
%   create a g node with id, replace the cursor with the fresh g and append
%   the cursor as only child of it

\paragraph{End Group:} $\}$

\begin{description}
  \item{\verb+g[@id]/cursor+}\\
  remove the cursor, put $\tadvance$ after the \texttt{g} node
  \item{\verb+row/cell/g/cursor+}\\
  remove the cursor, put $\tadvance$ after the \texttt{row} node
  \item{\verb+math/g[!@id]/cursor+}\\
  ?
  \item{\verb+cursor+}\\
  error ?
\end{description}

\paragraph{Math Shift:} $\$$

\begin{description}
  \item{\verb+tex/cursor+}\\
  create a \texttt{math} node, create a \texttt{g} node, append the \texttt{g} node
    as child of the \texttt{math} node, append the cursor as child of the \texttt{g} node
  \item{\verb+math[@display='1']/g[!@id][*#]/cursor+}\\
  append the cursor as last child of the \texttt{math} node
  \item{\verb+math/g[!@id][*#]/cursor+}\\
  remove the cursor
  \item{\verb+math[!display='1']/g[!@id]/cursor+}\\
  set \verb+display='1'+ in the \texttt{math} node
  \item{\verb+math/g[!@id]+}\\
  append the cursor after the \texttt{math} node
  \item{\verb+math/cursor+}\\
  remove the cursor
  \item{\verb+cursor+} \\
  error ?
\end{description}

% do_shift:
% CASE: tex/cursor
%   create a math node. create a g node. append g as child of math.
%   append the cursor as child of g
% CASE: math[@display='1']/g[!@id][*#]/cursor
%   append the cursor as last child of math
% CASE: math/g[!@id][*#]/cursor
%   remove the cursor. Editing is done
% CASE: math[!display='1']/g[!@id]/cursor
%   set the display attribute to '1'
% CASE: math/g[!@id]
%   append the cursor after math (?)
% CASE: math/cursor
%   remove the cursor. Editing is done
% ELSE:
%   error

\paragraph{Align:} $\&$

\begin{description}
  \item{\verb+g[@id]/cursor+}\\
  create a \texttt{row} node, create a \texttt{cell} node, create a \texttt{g} node,
    append the cursor to the new \texttt{g} node, append the \texttt{cell} node to the
    the \texttt{row} node ?
  \item{\verb+row/cell/g/cursor+}\\
  create the \texttt{g} node, create the \texttt{cell} node, append the cursor
    as child of the new \texttt{g} node, append the new \texttt{g} node to the new
    \texttt{cell} node after the old \texttt{cell} node
  \item{\verb+cursor+}\\
  error
\end{description}

% do_align:
% CASE: g[@id]/cursor
%   create a row node. create a cell node. create a g node. append the
%   cursor to g, append the g to cell, append the cell to row, ???
% CASE: row/cell/g/cursor
%   create a g node. create a cell node. appent the cursor to g,
%   append the g to cell, insert the new cell after the existing cell
% ELSE:
%   error

\paragraph{End-of-line:}

% do_eol:
%   ignored

\paragraph{Parameter:} $p(i)$
% do_parameter:
%   ignored

\paragraph{Superscript:} $\uparrow$

\begin{description}
  \item{\verb+<g|p>[^#]/cursor+}\\
  create a \SP{} node, create a \G{} node, replace the cursor with the \SP{} node,
    append the \G{} node as first child of the \SP{} node, append the cursor as last
    child of the \SP{} node
  \item{\verb+<g|p>[*#]/cursor+}\\
  create a \SP{} node, replace \texttt{*} with the \SP{} node, append \texttt{*} to
    the \SP{} node, append cursor to the \SP{} node
  \item{\verb+sp[^*#$][!@over='1']/cursor+}\\ %$
  set \verb+over='1'+ in the \SP{} node
  \item{\verb+sp[^*#$][@over='1']/cursor+}\\ %$
  error
  \item{\verb+cursor+}\\
  error ?
\end{description}
% do_superscript:
% CASE: g[^#]/cursor
%   create sp node. create g node, replace cursor with sp, append g to sp, append cursor to sp
% CASE: g[*#]/cursor
%   create sp node, replace * with sp, append * to sp, append cursor to sp
% CASE: sp[^*#$][!@over='1']/cursor
%   set over='1' in sp node
% CASE: sp[^*#$][@over='1']/cursor
%   error
% ELSE:
%   error ?

\paragraph{Subscript:} $\downarrow$

\begin{description}
  \item{\verb+<g|p>[^#]/cursor+}\\
  create a \SB{} node, create a \G{} node, replace the cursor with the \SB{} node,
    append the \G{} node as first child of the \SB{} node, append the cursor as last
    child of the \SB{} node
  \item{\verb+<g|p>[*#]/cursor+}\\
  create a \SB{} node, replace \texttt{*} with the \SB{} node, append \texttt{*} to
    the \SB{} node, append cursor to the \SB{} node
  \item{\verb+sb[^*#$][!@under='1']/cursor+}\\ %$
  set \verb+under='1'+ in the \SB{} node
  \item{\verb+sb[^*#$][@under='1']/cursor+}\\ %$
  error
  \item{\verb+cursor+}\\
  error ?
\end{description}
% do_subscript:
% CASE: g[^#]/cursor
%   create sb node. create g node, replace cursor with sb, append g to sb, append cursor to sb
% CASE: g[*#]/cursor
%   create sb node, replace * with sb, append * to sb, append cursor to sb
% CASE: sb[^*#$][!@under='1']/cursor
%   set over='1' in sb node
% CASE: sb[^*#$][@under='1']/cursor
%   error
% ELSE:
%   error ?

\paragraph{Ignorable space:} $\square$

% do_ignorable_space:
%   do nothing?

\paragraph{Space:} $s$

\begin{description}
  \item{\verb+cursor+}\\
  create \SNODE{} node, replace cursor with the \SNODE{} node, append
  $\tadvance$ after \SNODE{} node
\end{description}

% do_space
%   create s node, replace cursor with s, append \advance after s

\paragraph{Identifier:} $i(v)$

\begin{description}
  \item{\verb+cursor+}\\
  create an \INODE{}, set \verb+value=+$v$ in the \INODE{}, replace
  cursor with \INODE{}, append $\tadvance$ after the \INODE{} node
\end{description}

% do_identifier
%   create i node, replace cursor with i, append \advance after i

\paragraph{Number:} $n(v)$

\begin{description}
  \item{\verb+cursor+}\\
  create an \NNODE{}, set \verb+value=+$v$ in the \NNODE{}, replace
  cursor with \NNODE{}, append $\tadvance$ after the \NNODE{} node
\end{description}

% do_number
%   create n node, replace cursor with n, append \advance after n

\paragraph{Apostrophe:} $o({}')$

\begin{description}
  \item{\verb+<g/p>[(sp[*#$]/g[o[@name='prime']$])#]/cursor+}\\
  create a \ONODE{} node, set \verb+name='prime'+ in the \ONODE{},
    append the \ONODE{} to the innermost \G{} node
  \item{\verb+<g|p>[(sb[^sp[^*#$]/g[o[@name='prime']]$])#]/cursor+}\\
  create a \ONODE{} node, set \verb+name='prime'+ in the \ONODE{},
    append the \ONODE{} to the innermost \G{} node
  \item{\verb+<g|p>[*#]/cursor+}\\
  create a \ONODE{} node, set \verb+name='prime'+ in the \ONODE{},
    create a \SP{} node, create a \G{} node, replace \texttt{*} with \SP{} node,
    append the new \G{} node to the \SP{} node, append the \ONODE{}
    node to the new \G{} node
  \item{\verb+<g|p>[^#]/cursor+}\\
  error?
  \item{\verb+cursor+}\\
  cursor is not in a group, error?
\end{description}

% do_apostrophe
% CASE: g[(sp[^*#$]/g[o[@name='prime']$])#]/cursor
%   append a new o[@name='prime'] node to the inner g node
% CASE: g[(sb[^sp[^*#$]/g[o[@name='prime']]$])#]/cursor
%   append a new o[@name='prime'] node to the inner g node
% CASE: g[*#]/cursor
%   create sp node, create g node, replace * with sp, append * to sp, append g to sp,
%   append a new o[@name='prime'[ node to the new g node
% CASE: g[^#]/cursor
%   error?
% ELSE:
%   cursor is not in a group, error?

\paragraph{Other:} $o(v)$

create an \ONODE{}, set \verb+value=+$v$ in the \ONODE{}, replace
cursor with \ONODE{}, append $\tadvance$ after the \ONODE{} node

% do_other
%   create o node, replace cursor with o, append \advance after o

\paragraph{Active:} $\sim$

% do_active:
%   ignored ???

\paragraph{Comment:} $\%$

% do_comment:
%   ignored ???

\paragraph{Begin Environment:} $c(\mathtt{begin})\langle\alpha_1,\dots,\alpha_n\rangle$

\paragraph{End Environment:} $c(\mathtt{end})\langle\rangle$

\paragraph{Left Delimiter:} $c(\mathtt{left})\langle\alpha\rangle$

\paragraph{Right Delimiter:} $c(\mathtt{right})\langle\alpha\rangle$

\paragraph{Carriage-Return:} $c(\mathtt{cr})\langle\rangle$

\begin{description}
  \item{\verb+row/cell/g/cursor+}\\
  create a \ROW{} node, create a \CELL{} node, create a \G{}
    node, append the cursor to the new \G{} node, append the new \G{}
    node to the new \CELL{} node, append the new \CELL{} node to the
    new \ROW{} node, insert the new \ROW{} node after the old \ROW{} node
  \item{\verb+cursor+}\\
  ignored?
\end{description}

% do_cr:
% CASE: row/cell/g/cursor
%   create row node, create cell node, create g node,
%   append cursor to g, append g to cell, append cell to row,
%   insert new row after old row
% ELSE:
%   ignored ???

\paragraph{Macro:} $c(v)\langle\alpha_1,\dots,\alpha_n\rangle$

\begin{description}
  \item{\verb+<p|g>/cursor+}\\
  create a \CNODE{} node with the children corresponding to the pattern
  $\tmap{\alpha_1}$,\dots,$\tmap{\alpha_n}$, replace the cursor with
  the new \CNODE{} node. put $\tnext$ as the first child of the new
  \CNODE{} node

  \item{\verb+*/cursor+}\\
  create a \CNODE{} node with the children corresponding to the pattern
  $\tmap{\alpha_1}$,\dots,$\tmap{\alpha_n}$, replace the cursor with
  the new \CNODE{} node, put $\tnext$ as the first child of the new
  \CNODE{} node. If $n\ne0$ emit a warning (the macro has arguments but
  but the context wouldn't normally allow them to be entered)
\end{description}

% do_macro:
% CASE: g/cursor
%   create a c node with children corresponding to the pattern of the macro
%   append \nextparam as first child of the macro

\section{Left Drop Rules}

\paragraph{Normal Left Drop:} $\NLDROP$

\begin{description}

  \item{\verb+cursor+}\\
  replace the cursor with the $\NLDROP$.

\end{description}

\paragraph{Special Left Drop:} $\SLDROP$

\begin{description}

  %*******************************************************************************************************
  %************** rules handling the case in which the cursor has a preceding node ***********************
  %*******************************************************************************************************

  %************** cursor's parent is a group or a parameter (a p node)

  \item{\verb+<g|p>[(i|n|o|s|c[!*])#]/cursor+}\\
  remove the token.

  \item{\verb+<g|p>[g#]/cursor+}\\
  remove the cursor and append it to the \G{} node.

  \item{\verb+<g|p>[<sp|sb>#]cursor+}\\
  remove the cursor and append the $\SLDSCRIPT$

  \item{\verb+<g|p>[c[p[@right-open="1"]$]#]/cursor+}\\
  remove the cursor and append the it to the \PNODE{} node.

  % remember to add the rules handling the primes

  %*************************************************************************************************
  %*********** rules handling the case in which the cursor has no preceding nodes ******************
  %*************************************************************************************************

  \item{\verb+g[@id][^#$]/cursor+}\\
  replace the \G{} node with the cursor.

\end{description}

\section{Right Drop Rules}

\section{$\varepsilon$-rules}

\paragraph{Nromal Left Drop}

\begin{description}

  %**************************************************************************************
  %****************************** epsilon-rules with \NLDROP ****************************
  %**************************************************************************************

  %***************************** \NLDROP has no preceding nodes *************************

  \item{\verb+math[^#$]/+$\NLDROP$}\\
  replace the $\NLDROP$ with the cursor.

  \item{\verb+g[^#$]/+$\NLDROP$}\\
  replace the \G{} node with the $\NLDROP$.

  % this rule overrides the rule above
  \item{\verb+math/g[^#$]/+$\NLDROP$}\\
  replace the $\NLDROP$ with the cursor.

  \item{\verb+c/p[^#$]/+$\NLDROP$}\\
  remove the $\NLDROP$ and insert it before the \PNODE{} node.

  \item{\verb+cell[^#$]/+$\NLDROP$}\\
  replace the cell with the $\NLDROP_n$.

  \item{\verb+table[^#$]/+$\NLDROP$}\\
  replace the \TABLE{} node with the $\NLDROP$.

  \item{\verb+c[p[@left-open='1'][*]#$]/p[@right-open='1'][^#$]/+$\NLDROP$}\\
  replace the \CNODE{} node with the content of the first \PNODE{} node and insert the $\NLDROP$ after this content

  \item{\verb+c[p[@left-open='1'][!*]#$]/p[@right-open='1'][^#$]/+$\NLDROP$}\\
  replace the \CNODE{} node with the $\NLDROP$.

  \item{\verb+c[^#][!p(*)]/+$\NLDROP$}\\
  replace the \CNODE{} node with the $\NLDROP$.

  %************************* \NLDROP has at least one preceding node *********************

  % general rules

  % this rule should also handles the case where the \NLDROP is the third (and last) child of a script.
  \item{\verb+*[*#]/+$\NLDROP$}\\
  remove the $\NLDROP$ and append it as the last child of its ex preceding brother.

  % this rule overrides the one above
  \item{\verb+*[<i|n|o|s>#]/+$\NLDROP$}\\
  remove the $\NLDROP$ and replace the token with the $\NLDROP_n$.

  % special rules

  \item{\verb+<sp|sb>[^*#$]+/$\NLDROP$}\\
  replace the script node with its first child and insert the $\NLDROP$ after it.

  % this rule overrides the one above.
  \item{\verb+<sp|sb>[^g[!@id][!*]#$]/+$\NLDROP$}\\
  replace the script with the cursor.

  % this rule overrides the one above
  \item{\verb+*[sp[!@id][^*g[!@id][^o[@name='prime']++\verb+o[@name='prime']$]]#]/+$\NLDROP$}\\
  remove the last \ONODE{} node and replace the $\NLDROP$ with the cursor.%$\NLDROP_n$.

  \item{\verb+*[sp[!@id][^*g[!@id][^o[@name='prime']$]]#]/+$\NLDROP$}\\
  replace the script with its first child and replace the $\NLDROP$ with the cursor.%$\NLDROP_n$.

  \item{\verb+c[(i|n|o|s|c[!*])#]/+$\NLDROP$}\\
  move the $\NLDROP$ before the delimiter.

  % this rule is true for both right-open and parameterized macros.
  \item{\verb+c[p#]/+$\NLDROP$}\\
  move the $\NLDROP$ into the \PNODE{} node.

  %**************** \NLDROP has no preceding nodes, but has following nodes **************

  % general rule
  \item{\verb+*[^#*]/+$\NLDROP$}\\
  remove the $\NLDROP$ and insert it before its parent.

  % special rules

  \item{\verb+math/g[^#*]/+$\NLDROP$}\\
  replace the $\NLDROP$ with the cursor.

  % this rule is applicable to all macros.
  \item{\verb+c[^#][p[*]]/+$\NLDROP$}\\
  remove the $\NLDROP$ and insert it before the \CNODE{} node.

  %****************************************************************************************
  %***************************** epsilon-rules with \NLDROP_n *****************************
  %****************************************************************************************

  \item{\verb+*[*#]/+$\NLDROP_n$}\\
  replace the $\NLDROP_n$ with the cursor.

  \item{\verb+row[cell#]/+$\NLDROP_n$}\\
  remove the $\NLDROP_n$ and append the cursor as the last child of the \CELL{} node.

  \item{\verb+row[^#$]/+$\NLDROP_n$}\\
  replace the \ROW{} node with the $\NLDROP_n$

  \item{\verb+table[row#]/+$\NLDROP_n$}\\
  remove the $\NLDROP_n$ and append it as last child of the \ROW{} node.

  \item{\verb+table[^#$]/+$\NLDROP_n$}\\
  replace the \texttt{table} with the cursor.%$\NLDROP_n$.

  \item{\verb+g[@id][^#$]/+$\NLDROP_n$}\\
  replace the \G{} node with the $\NLDROP_n$.

\end{description}

\paragraph{Special Left Drop}

%\begin{description}

%\end{description}

\paragraph{Advance}

\begin{description}
  \item{\verb+g/+$\tadvance$}\\
  replace $\tadvance$ with the cursor

  \item{\verb+p[#$]/+$\tadvance$}\\ %$
  put $\tadvance$ after the \PNODE{} node

  \item{\verb+c[#p]/+$\tadvance$} \\
  remove $\tadvance$, put the cursor as first child of the \PNODE{} node

  \item{\verb+c[#*]/+$\tadvance$} \\ %$
  replace $\tadvance$ with the cursor 

  \item{\verb+c[#$]/+$\tadvance$} \\ %$
  move $\tadvance$ after the \CNODE{} node
\end{description}

\paragraph{Next Parameter}

\paragraph{Next Token}

%% \begin{description}
%%   \item{\verb+c[#p]/+$\tnext$} \\
%% \end{description}

% g[@id]/(c[#$][@right-open]/g[!@id][#$]/)+cursor  }   let p = cursor.parent() in remove; advance(p)

% c/g[!@id]/cursor
% c/cursor 
% */cursor  {   let g = new group in replace

% g[@id][^#$]/cursor  <=   cursor.parent().replace(cursor)
% g[@id][^#$]/cursor  <-   cursor
% (!g[@id][^#$])[A#B]/(g[@id][^#$]/)+cursor  <-  (!g[@id][^#$])[A#B]/cursor  

\end{document}
