1 \documentclass[10pt]{article}
9 \title{A MathML Editor Based on \TeX{} Syntax\\Formal Specification}
10 \author{Paolo Marinelli\\Luca Padovani\\\small\{{\tt pmarinel},{\tt lpadovan}\}{\tt @cs.unibo.it}\\\small Department of Computer Science\\\small University of Bologna}
13 \newcommand{\tmap}[1]{\llbracket#1\rrbracket}
14 \newcommand{\tadvance}{\vartriangle}
15 \newcommand{\tnext}{\rhd}
16 \newcommand{\G}{\texttt{g}}
17 \newcommand{\PNODE}{\texttt{p}}
18 \newcommand{\SNODE}{\texttt{s}}
19 \newcommand{\INODE}{\texttt{i}}
20 \newcommand{\NNODE}{\texttt{n}}
21 \newcommand{\ONODE}{\texttt{o}}
22 \newcommand{\CNODE}{\texttt{c}}
23 \newcommand{\SP}{\texttt{sp}}
24 \newcommand{\SB}{\texttt{sb}}
25 \newcommand{\CELL}{\texttt{cell}}
26 \newcommand{\ROW}{\texttt{row}}
27 \newcommand{\SLDROP}{\hookleftarrow}
28 \newcommand{\NLDROP}{\leftarrow}
36 The following tokens are defined:
38 \begin{tabular}{lllp{0.5\textwidth}}
39 \textbf{\TeX{}} & \textbf{Notation} & \textbf{Node} & \textbf{Description} \\
41 \verb+{+ & $\mathrm{begin}$ & \texttt{g} & Beginning of a group \\
42 \verb+}+ & $\mathrm{end}$ & & End of a group \\
43 \verb+$+ & $\$$ & \texttt{math} & Math shift \\ %$ \\
45 \verb+#+$i$ & $p(i)$ & \texttt{p} & Parameter \\
46 \verb+^+ & $\uparrow$ & \texttt{sp} & Superscript \\
47 \verb+_+ & $\downarrow$ & \texttt{sb} & Subscript \\
48 & $\square$ & & Space-like character that can be ignored \\
49 & $s$ & \texttt{s} & Space-like character that may be significant \\
50 letter & $i(v)$ & \texttt{i} & Identifier $v$ \\
51 digit & $n(v)$ & \texttt{n} & Number $v$ \\
52 other & $o(v)$ & \texttt{o} & Other character or operator $v$ \\
53 \verb+~+ & $\sim$ & & Active character \\
54 \verb+%+ & $\%$ & & Comment \\
55 control & $c(v)\langle\alpha_1,\dots,\alpha_n\rangle$ & \texttt{c} &
56 Control sequence $v$ that expects the $\alpha_1,\dots,\alpha_n$ sequence of tokens. \\
57 backspace & $\vartriangleleft$ & & \\
58 backspace & $\blacktriangleleft$ & & \\
61 %% Some tokens are mapped directly into nodes of the TML tree. The following functions shows
64 \begin{tabular}{r@{\quad$=$\quad}l}
65 $\tmap{\{}$ & \verb+g+ \\
66 $\tmap{p(i)}$ & \verb+p[@index=+$i$\verb+]+ \\
67 $\tmap{p_l(i)}$ & \verb+p[@index=+$i$\verb+][@left-open='1']+ \\
68 $\tmap{p_r(i)}$ & \verb+p[@index=+$i$\verb+][@right-open='1']+ \\
69 $\tmap{s}$ & \verb+s+ \\
70 $\tmap{\uparrow}$ & \verb+sp+ \\
71 $\tmap{\downarrow}$ & \verb+sb+ \\
72 $\tmap{i(v)}$ & \verb+i[@value=+$v$\verb+]+ \\
73 $\tmap{n(v)}$ & \verb+n[@value=+$v$\verb+]+ \\
74 $\tmap{o(v)}$ & \verb+o[@value=+$v$\verb+]+ \\
75 $\tmap{c(v)\langle\alpha_1,\dots,\alpha_n\rangle}$ & \verb+c[@name=+$v$\verb+][^+$\tmap{\alpha_1}\cdots\tmap{\alpha_n}$\verb+$]+\\
79 %% \section{Description and Semantics of the Pattern Language}
82 %% \mathit{NodeTest} & ::= & \mathtt{*} \\
83 %% & | & \mathit{ElementType} \\
84 %% & | & \mathtt{<}~\mathit{ElementTypePattern}~\mathtt{>} \\[1ex]
85 %% \mathit{ElementTypePattern} & ::= & \mathtt{*} \\
86 %% & | & \mathit{ElementType}~(\mathtt{|}~\mathit{ElementType})^* \\
87 %% & | & \mathtt{!}\mathit{ElementType}~(\mathtt{|}~\mathit{ElementType})^*\\[1ex]
88 %% \mathit{NodePattern} & ::= & \mathit{NodeTest}~\mathit{AttributeQualifier}^*\\[1ex]
89 %% \mathit{AttributeQualifier} & ::= & \mathtt{[@}\mathit{AttributeTest}\mathtt{]}\\
90 %% & | & \mathtt{[!@}\mathit{AttributeTest}\mathtt{]}\\[1ex]
91 %% \mathit{AttributeTest} & ::= & \mathit{AttributeName} \\
92 %% & | & \mathit{AttributeName}\mathtt{='}\mathit{Text}\mathtt{'}
95 \section{Insert Rules}
97 \paragraph{Begin Group:} $\{$
100 \item{\verb+table/cursor+}\\
101 create a \texttt{row} node, create a \texttt{cell} node, create a \texttt{g} node,
102 append the cursor to the \texttt{g} node, append the \texttt{g} node to the \texttt{cell} node,
103 append the \texttt{cell} node to the \texttt{row} node, append the \texttt{row} node to the
105 \item{\verb+cursor+} \\ create a \texttt{g} node, replace the cursor with the new \texttt{g} node,
106 append the cursor to the new \texttt{g} node
109 % CASE: c/g[!@id]/cursor
116 % CASE: c[@table='1']/cursor
118 % create a g node with id, replace the cursor with the fresh g and append
119 % the cursor as only child of it
121 \paragraph{End Group:} $\}$
124 \item{\verb+g[@id]/cursor+}\\
125 remove the cursor, put $\tadvance$ after the \texttt{g} node
126 \item{\verb+row/cell/g/cursor+}\\
127 remove the cursor, put $\tadvance$ after the \texttt{row} node
128 \item{\verb+math/g[!@id]/cursor+}\\
130 \item{\verb+cursor+}\\
134 \paragraph{Math Shift:} $\$$
137 \item{\verb+tex/cursor+}\\
138 create a \texttt{math} node, create a \texttt{g} node, append the \texttt{g} node
139 as child of the \texttt{math} node, append the cursor as child of the \texttt{g} node
140 \item{\verb+math[@display='1']/g[!@id][*#]/cursor+}\\
141 append the cursor as last child of the \texttt{math} node
142 \item{\verb+math/g[!@id][*#]/cursor+}\\
144 \item{\verb+math[!display='1']/g[!@id]/cursor+}\\
145 set \verb+display='1'+ in the \texttt{math} node
146 \item{\verb+math/g[!@id]+}\\
147 append the cursor after the \texttt{math} node
148 \item{\verb+math/cursor+}\\
150 \item{\verb+cursor+} \\
156 % create a math node. create a g node. append g as child of math.
157 % append the cursor as child of g
158 % CASE: math[@display='1']/g[!@id][*#]/cursor
159 % append the cursor as last child of math
160 % CASE: math/g[!@id][*#]/cursor
161 % remove the cursor. Editing is done
162 % CASE: math[!display='1']/g[!@id]/cursor
163 % set the display attribute to '1'
165 % append the cursor after math (?)
167 % remove the cursor. Editing is done
171 \paragraph{Align:} $\&$
174 \item{\verb+g[@id]/cursor+}\\
175 create a \texttt{row} node, create a \texttt{cell} node, create a \texttt{g} node,
176 append the cursor to the new \texttt{g} node, append the \texttt{cell} node to the
177 the \texttt{row} node ?
178 \item{\verb+row/cell/g/cursor+}\\
179 create the \texttt{g} node, create the \texttt{cell} node, append the cursor
180 as child of the new \texttt{g} node, append the new \texttt{g} node to the new
181 \texttt{cell} node after the old \texttt{cell} node
182 \item{\verb+cursor+}\\
187 % CASE: g[@id]/cursor
188 % create a row node. create a cell node. create a g node. append the
189 % cursor to g, append the g to cell, append the cell to row, ???
190 % CASE: row/cell/g/cursor
191 % create a g node. create a cell node. appent the cursor to g,
192 % append the g to cell, insert the new cell after the existing cell
196 \paragraph{End-of-line:}
201 \paragraph{Parameter:} $p(i)$
205 \paragraph{Superscript:} $\uparrow$
208 \item{\verb+<g|p>[^#]/cursor+}\\
209 create a \SP{} node, create a \G{} node, replace the cursor with the \SP{} node,
210 append the \G{} node as first child of the \SP{} node, append the cursor as last
211 child of the \SP{} node
212 \item{\verb+<g|p>[*#]/cursor+}\\
213 create a \SP{} node, replace \texttt{*} with the \SP{} node, append \texttt{*} to
214 the \SP{} node, append cursor to the \SP{} node
215 \item{\verb+sp[^*#$][!@over='1']/cursor+}\\ %$
216 set \verb+over='1'+ in the \SP{} node
217 \item{\verb+sp[^*#$][@over='1']/cursor+}\\ %$
219 \item{\verb+cursor+}\\
224 % create sp node. create g node, replace cursor with sp, append g to sp, append cursor to sp
226 % create sp node, replace * with sp, append * to sp, append cursor to sp
227 % CASE: sp[^*#$][!@over='1']/cursor
228 % set over='1' in sp node
229 % CASE: sp[^*#$][@over='1']/cursor
234 \paragraph{Subscript:} $\downarrow$
237 \item{\verb+<g|p>[^#]/cursor+}\\
238 create a \SB{} node, create a \G{} node, replace the cursor with the \SB{} node,
239 append the \G{} node as first child of the \SB{} node, append the cursor as last
240 child of the \SB{} node
241 \item{\verb+<g|p>[*#]/cursor+}\\
242 create a \SB{} node, replace \texttt{*} with the \SB{} node, append \texttt{*} to
243 the \SB{} node, append cursor to the \SB{} node
244 \item{\verb+sb[^*#$][!@under='1']/cursor+}\\ %$
245 set \verb+under='1'+ in the \SB{} node
246 \item{\verb+sb[^*#$][@under='1']/cursor+}\\ %$
248 \item{\verb+cursor+}\\
253 % create sb node. create g node, replace cursor with sb, append g to sb, append cursor to sb
255 % create sb node, replace * with sb, append * to sb, append cursor to sb
256 % CASE: sb[^*#$][!@under='1']/cursor
257 % set over='1' in sb node
258 % CASE: sb[^*#$][@under='1']/cursor
263 \paragraph{Ignorable space:} $\square$
265 % do_ignorable_space:
268 \paragraph{Space:} $s$
271 \item{\verb+cursor+}\\
272 create \SNODE{} node, replace cursor with the \SNODE{} node, append
273 $\tadvance$ after \SNODE{} node
277 % create s node, replace cursor with s, append \advance after s
279 \paragraph{Identifier:} $i(v)$
282 \item{\verb+cursor+}\\
283 create an \INODE{}, set \verb+value=+$v$ in the \INODE{}, replace
284 cursor with \INODE{}, append $\tadvance$ after the \INODE{} node
288 % create i node, replace cursor with i, append \advance after i
290 \paragraph{Number:} $n(v)$
293 \item{\verb+cursor+}\\
294 create an \NNODE{}, set \verb+value=+$v$ in the \NNODE{}, replace
295 cursor with \NNODE{}, append $\tadvance$ after the \NNODE{} node
299 % create n node, replace cursor with n, append \advance after n
301 \paragraph{Apostrophe:} $o({}')$
304 \item{\verb+<g/p>[(sp[*#$]/g[o[@name='prime']$])#]/cursor+}\\
305 create a \ONODE{} node, set \verb+name='prime'+ in the \ONODE{},
306 append the \ONODE{} to the innermost \G{} node
307 \item{\verb+<g|p>[(sb[^sp[^*#$]/g[o[@name='prime']]$])#]/cursor+}\\
308 create a \ONODE{} node, set \verb+name='prime'+ in the \ONODE{},
309 append the \ONODE{} to the innermost \G{} node
310 \item{\verb+<g|p>[*#]/cursor+}\\
311 create a \ONODE{} node, set \verb+name='prime'+ in the \ONODE{},
312 create a \SP{} node, create a \G{} node, replace \texttt{*} with \SP{} node,
313 append the new \G{} node to the \SP{} node, append the \ONODE{}
314 node to the new \G{} node
315 \item{\verb+<g|p>[^#]/cursor+}\\
317 \item{\verb+cursor+}\\
318 cursor is not in a group, error?
322 % CASE: g[(sp[^*#$]/g[o[@name='prime']$])#]/cursor
323 % append a new o[@name='prime'] node to the inner g node
324 % CASE: g[(sb[^sp[^*#$]/g[o[@name='prime']]$])#]/cursor
325 % append a new o[@name='prime'] node to the inner g node
327 % create sp node, create g node, replace * with sp, append * to sp, append g to sp,
328 % append a new o[@name='prime'[ node to the new g node
332 % cursor is not in a group, error?
334 \paragraph{Other:} $o(v)$
336 create an \ONODE{}, set \verb+value=+$v$ in the \ONODE{}, replace
337 cursor with \ONODE{}, append $\tadvance$ after the \ONODE{} node
340 % create o node, replace cursor with o, append \advance after o
342 \paragraph{Active:} $\sim$
347 \paragraph{Comment:} $\%$
352 \paragraph{Begin Environment:} $c(\mathtt{begin})\langle\alpha_1,\dots,\alpha_n\rangle$
354 \paragraph{End Environment:} $c(\mathtt{end})\langle\rangle$
356 \paragraph{Left Delimiter:} $c(\mathtt{left})\langle\alpha\rangle$
358 \paragraph{Right Delimiter:} $c(\mathtt{right})\langle\alpha\rangle$
360 \paragraph{Carriage-Return:} $c(\mathtt{cr})\langle\rangle$
363 \item{\verb+row/cell/g/cursor+}\\
364 create a \ROW{} node, create a \CELL{} node, create a \G{}
365 node, append the cursor to the new \G{} node, append the new \G{}
366 node to the new \CELL{} node, append the new \CELL{} node to the
367 new \ROW{} node, insert the new \ROW{} node after the old \ROW{} node
368 \item{\verb+cursor+}\\
373 % CASE: row/cell/g/cursor
374 % create row node, create cell node, create g node,
375 % append cursor to g, append g to cell, append cell to row,
376 % insert new row after old row
380 \paragraph{Macro:} $c(v)\langle\alpha_1,\dots,\alpha_n\rangle$
383 \item{\verb+<p|g>/cursor+}\\
384 create a \CNODE{} node with the children corresponding to the pattern
385 $\tmap{\alpha_1}$,\dots,$\tmap{\alpha_n}$, replace the cursor with
386 the new \CNODE{} node. put $\tnext$ as the first child of the new
389 \item{\verb+*/cursor+}\\
390 create a \CNODE{} node with the children corresponding to the pattern
391 $\tmap{\alpha_1}$,\dots,$\tmap{\alpha_n}$, replace the cursor with
392 the new \CNODE{} node, put $\tnext$ as the first child of the new
393 \CNODE{} node. If $n\ne0$ emit a warning (the macro has arguments but
394 but the context wouldn't normally allow them to be entered)
399 % create a c node with children corresponding to the pattern of the macro
400 % append \nextparam as first child of the macro
402 \section{Left Drop Rules}
404 \paragraph{Normal Left Drop:} $\NLDROP$
407 \item{\verb+/cursor+}\\
409 \item{\verb+math/cursor+}\\
411 \item{\verb+g[!@id][_*#_]/cursor+}\\
412 replace the cursor with the $\NLDROP$.
413 \item{\verb+g[!@id][^#$]/cursor+}\\
414 replace the cursor with the $\NLDROP$
415 \item{\verb+g[@id][_*#_]/cursor+}\\
416 replace the cursor with the $\NLDROP$.
417 \item{\verb+g[@id][^#$]/cursor+}\\
418 replace the cursor with the $\NLDROP$.
419 \item{\verb+c[_*#_]/cursor+}\\
420 replace the cursor with the $\NLDROP$.
421 \item{\verb+sp[^*#$]/cursor+}\\
422 replace the cursor with the $\NLDROP$.
423 \item{\verb+c/p/cursor+}\\
424 replace the cursor with the $\NLDROP$.
427 \paragraph{Special Left Drop:} $\SLDROP$
429 \item{\verb+/cursor+}\\
431 \item{\verb+math/cursor+}\\
433 \item{\verb+g[!@id][_*#_]/cursor+}\\
434 replace the cursor with the $\SLDROP$.
435 \item{\verb+g[!@id][^#$]/cursor+}\\
436 replace the cursor with the $\SLDROP$
437 \item{\verb+g[@id][_*#_]/cursor+}\\
438 replace the cursor with the $\SLDROP$.
439 \item{\verb+g[@id][^#$]/cursor+}\\
440 replace the cursor with the $\SLDROP$.
441 \item{\verb+c[_*#_]/cursor+}\\
442 replace the cursor with the $\SLDROP$.
443 \item{\verb+sp[^*#$]/cursor+}\\
444 replace the cursor with the $\SLDROP$.
445 \item{\verb+c[p#]/cursor+}\\
446 remove the cursor and append the $\SLDROP$ to the \PNODE{} node.
447 \item{\verb+c[<i|n|o|s|c>#]/cursor+}\\
448 remove the cursor and append it before the \INODE{}, \NNODE{}, \ONODE{}, \SNODE{} or \CNODE{} node.
449 \item{\verb+c/p/cursor+}\\
450 repace the cursor with the $\SLDROP$.
453 \section{Right Drop Rules}
455 \section{$\varepsilon$-rules}
457 \paragraph{Nromal Left Drop}
461 %drop_prev_script(false). The results aren't \NLDROP's parent dependent.
462 \item{\verb+.[<sp|sb>#]/+$\NLDROP$}\\
463 remove the $\NLDROP$ and append it to the preceding script.
465 %drop_prev_group(false). The results are \NLDROP's parent independent.
466 \item{\verb+.[g#]/+$\NLDROP$}\\
467 remove the $\NLDROP$ and append it to the \G{} node.
469 %drop_prev_macro(false). The results aren't \NLDROP's parent dependent, unless the macro is undefined.
470 \item{\verb+.[c[@pattern+$\sim$\verb+')'][g$]#]/+$\NLDROP$}\\
471 remove the $\NLDROP$ and append it to the \G{} node.
472 \item{\verb+.[c[@pattern='(]'][^g[^$]$]#]/+$\NLDROP$}\\
473 remove the \CNODE{} node.
474 \item{\verb+.[c[@pattern='(]'][^g[_]$]#]/+$\NLDROP$}\\
475 replace the \CNODE{} node with the content of the \G{} node.
476 \item{\verb+.[c[*]#]/+$\NLDROP$}\\
477 remove the $\NLDROP$ and append it to the \CNODE{} node.
478 \item{\verb+.[c[^$]#]/+$\NLDROP$}\\
479 remove the $\NLDROP$ and replace the \CNODE{} with the cursor.
481 %drop_prev_macro(false), when the macro is undefined and the NLDROP's parent is not a group with id
482 \item{\verb+<!g[@id]>[c[@undefined='1']#]/+$\NLDROP$}\\
483 remove the $\NLDROP$ and replace the \CNODE{} node with the cursor.
485 %drop_prev_macro(false), when the macro is undefined and the \NLDROP's parent is a group with id.
486 \item{\verb+g[@id][^c[@undefined='1']#$]/+$\NLDROP$}\\
487 remove the \CNODE{} node.
488 \item{\verb+g[@id][^c[@undefined='1']#._]+$\NLDROP$}\\
489 remove the $\NLDROP$ and replace the \CNODE{} node with the cursor.
490 \item{\verb+g[@id][_.c[@undefined='1']#]/+$\NLDROP$}\\
491 remove the $\NLDROP$ and replace the \CNODE{} node with the cursor.
493 %drop_prev_token(false), when the \NLDROP's parent is not a group with id.
494 \item{\verb+<!g[@id]>[_<i|n|o|s>#_]/+$\NLDROP$}\\
495 replace the node preceding the $\NLDROP$ with the cursor and remove the $\NLDROP$.
497 %drop_prev_token(false), when the cursor's parent is a group with id.
498 \item{\verb+g[@id][^<i|n|o|s>#$]/+$\NLDROP$}\\
499 remove the $\NLDROP$ and replace the \INODE{}, \NNODE{}, \ONODE{} or \SNODE{} with the $\NLDROP$.
500 \item{\verb+g[@id][^<i|n|o|s>#._]/+$\NLDROP$}\\
501 remove the $\NLDROP$ and replace the \INODE{}, \NNODE{}, \ONODE{} or \SNODE{} with the cursor.
502 \item{\verb+g[@id][_.<i|n|o|s>#]/+$\NLDROP$}\\
503 remove the $\NLDROP$ and replace the \INODE{}, \NNODE{}, \ONODE{} or \SNODE{} with the cursor.
506 \item{\verb+g[@id][^#$]/+$\NLDROP$}\\
507 replace the \G{} node with the $\NLDROP$.
509 %situations where the \NLDROP is a script's child.
510 \item{\verb+<sp|sb>[^g[^$]#$]/+$\NLDROP$}\\
511 replace the \SP{} or \SB{} node with the $\NLDROP$.
512 \item{\verb+<sp|sb>[^<!g[^$]#$>]/+$\NLDROP$}\\
513 replace the \SP{} or \SB{} with the non-\G{} node and insert the $\NLDROP$ after it.
515 %situations where the \NLDROP is a macro's child.
516 \item{\verb+c[p#]/+$\NLDROP$}\\
517 remove the $\NLDROP$ and append it to the \PNODE{} node.
518 \item{\verb+c[<i|n|o|s|c>#]/+$\NLDROP$}\\
519 remove the $\NLDROP$ and insert it before the \INODE{}, \NNODE{}, \ONODE{}, \SNODE{} or the \CNODE node.
520 \item{\verb+c[^#][p[*]]/+$\NLDROP$}\\
521 nothing to drop. Not all the parameters are empty.
522 \item{\verb+c[!p[*]][^#]/+$NLDROP$}\\
523 replace the macro with the $\NLDROP$.
525 %situations where the cursor is a phantom group's child and has no preceding node.
526 \item{\verb+math/g[!@id][^#$]/+$\NLDROP$}\\
528 \item{\verb+c[@pattern='()'][^g[^$]#$]/g[!@id][^#$]/+$\NLDROP$}\\
529 replace the \CNODE{} node with the $\NLDROP$
530 \item{\verb+c[@pattern='()'][^g[*]#$]/g[!@id][^#$]/+$\NLDROP$}\\
531 remove the $\NLDROP$, insert the $\NLDROP$ after the \CNODE{} node replace the \CNODE{} node with the content of the first \G{} node.
532 \item{\verb+c[@pattern='[)'][^#$]/g[!@id][^#$]/+$\NLDROP$}\\
533 replace the \CNODE{} node with the $\NLDROP$.
534 \item{\verb+c[@pattern='(]']/g[^#$]/+$\NLDROP$}\\
536 \item{\verb+c[@table='1']/p[^#$]/row[^#$]/cell[^#$]/g[!@id][^#$]/+$\NLDROP$}\\
537 replace the \CNODE{} with the cursor.
538 \item{\verb+c[@table='1']/p[row[cell[^g[!@id]$]$]#_]/row[^#$]/cell[^#$]/g[!@id][^#$]/+$\NLDROP$}\\
539 remove the \ROW{} node in which the $\NLDROP$ is and append the cursor to the \G{} node.
540 \item{\verb+c[@table='1']/p[^#row_]/row[^#$]/cell[^#$]/g[!@id][^#$]/+$\NLDROP$}\\
542 \item{\verb+row[_cell[^g[!@id]$]#_]/cell[^#$]/g[!@id][^#$]/+$\NLDROP$}\\
543 remove the cell in which the $\NLDROP$ is and append the cursor to the \G{} node of the preceding \CELL{} node.
544 \item{\verb+row[^#cell_]/cell[^#$]/g[!@id][^#$]/+$\NLDROP$}\\
546 \item{\verb+sp[^*#$]/g[^#$]/+$\NLDROP$}\\
547 replace the \SP{} node with it's first child and insert the cursor after it.
548 \item{\verb+sp[^*#$]/g[o#_]/+$\NLDROP$}\\
549 remove the \ONODE{}, remove the $\NLDROP$ and insert the cursor after the \SP{} node.
551 %situations where \NLDROP is a p's child
552 \item{\verb+c/p[^#$]/+$\NLDROP$}\\
553 remove the $\NLDROP$ and insert it before the \PNODE{} node.
557 \paragraph{Special Left Drop}
561 %drop_prev_script(true). The results aren't cursor's parent dependent.
562 \item{\verb+.[<sp|sb>#]/+$\SLDROP$}\\
563 remove the $\SLDROP$ and append it to the preceding script.
565 %drop_prev_group(true). The results are cursor's parent independent.
566 \item{\verb+.[g#]/+$\SLDROP$}\\
567 remove the $\SLDROP$ and append it to the \G{} node.
569 %drop_prev_macro(true). The results aren't cursor's parent dependent.
570 \item{\verb+.[c[undefined='1']#]/+$\SLDROP$}\\
571 remove the $\SLDROP$ and replace the \CNODE{} with the cursor.
572 \item{\verb+.[c[@pattern~')'][g$]#]/+$\SLDROP$}\\
573 remove the $\SLDROP$ and append the cursor to the \G{} node.
574 \item{\verb+.[c[@pattern='(]'][^g[^$]$]#]/+$\SLDROP$}\\
575 remove the \CNODE{} node and replace the $\SLDROP$ with the cursor.
576 \item{\verb+.[c[@pattern='(]'][^g[_]$]#]/+$\SLDROP$}\\
577 replace the \CNODE{} node with the content of the \G{} node and replace the $\SLDROP$ with the cursor.
578 \item{\verb+.[c[*]#]/+$\SLDROP$}\\
579 remove the $\SLDROP$ and append it to the \CNODE{} node.
580 \item{\verb+.[c[^$]#]/+$\SLDROP$}\\
581 remove the $\SLDROP$ and replace the \CNODE{} with the cursor.
582 %here, we have to return the macro's name to the lexer.
584 %drop_prev_token(true). The results aren't \SLDROP's parent dependent.
585 \item{\verb+.[_<i|n|o|s>#_]/+$\SLDROP$}\\
586 replace the node preceding the $\SLDROP$ with the cursor and remove the $\SLDROP$.
588 %situations where the \SLDROP is a script's child.
589 \item{\verb+<sp|sb>[^g[@id][^$]#$]/+$\SLDROP$}\\
590 replace the \SP{} or \SB{} node with the \G{} node and insert the cursor after it.
591 \item{\verb+<sp|sb>[^<g[!@id][^$]#$>]/+$\SLDROP$}\\
592 replace the \SP{} or \SB{} with the cursor.
593 \item{\verb+<sp|sb>[^*#$]/+$\SLDROP$}\\
594 replace the \SP{} or \SB{} node with it's first child and insert the cursor after it.
596 %situations where the \SLDROP is a macro's child.
597 \item{\verb+c[p#]/+$\SLDROP$}\\
598 remove the $\SLDROP$ and append it to the \PNODE{} node.
599 \item{\verb+c[<i|n|o|s|c>#]/+$\SLDROP$}\\
600 remove the $\SLDROP$ and insert the cursor before the \INODE{}, \NNODE{}, \ONODE{}, \SNODE{} or the \CNODE node.
601 \item{\verb+c[^#][p[*]]/+$\SLDROP$}\\
602 nothing to drop. Not all the parameters are empty.
603 \item{\verb+c[!p[*]][^#]/+$SLDROP$}\\
604 replace the macro with the cursor.
606 %situations where the \SLDROP is a phantom group's child and has no preceding node.
607 \item{\verb+math/g[!@id][^#$]/+$\SLDROP$}\\
609 \item{\verb+c[@pattern='()'][^g[^$]#$]/g[!@id][^#$]/+$\SLDROP$}\\
610 replace the \CNODE{} node with the cursor.
611 \item{\verb+c[@pattern='()'][^g[*]#$]/g[!@id][^#$]/+$\SLDROP$}\\
612 replace the \CNODE{} with the content of the first group and insert the cursor after it.
613 \item{\verb+c[@pattern='[)'][^#$]/g[!@id][^#$]/+$\SLDROP$}\\
614 replace the \CNODE{} node with the cursor.
615 \item{\verb+c[@pattern='(]']/g[^#$]/+$\SLDROP$}\\
617 \item{\verb+c[@table='1']/p[^#$]/row[^#$]/cell[^#$]/g[!@id][^#$]/+$\SLDROP$}\\
618 replace the \ROW{} with the cursor.
619 \item{\verb+c[@table='1']/p[row[cell[^g[!@id]$]$]#_]/row[^#$]/cell[^#$]/g[!@id][^#$]/+$\SLDROP$}\\
620 remove the \ROW{} node in which the $\SLDROP$ is and append the cursor to the \G{} node.
621 \item{\verb+c[@table='1']/p[^#row_]/row[^#$]/cell[^#$]/g[!@id][^#$]/+$\SLDROP$}\\
623 \item{\verb+row[_cell[^g[!@id]$]#_]/cell[^#$]/g[!@id][^#$]/+$\SLDROP$}\\
624 remove the cell in which the $\SLDROP$ is and append the cursor to the \G{} node of the preceding \CELL{} node.
625 \item{\verb+row[^#cell_]/cell[^#$]/g[!@id][^#$]/+$\SLDROP$}\\
627 \item{\verb+sp[^*#$]/g[^#$]/+$\SLDROP$}\\
628 replace the \SP{} node with it's first child and insert the cursor after it.
629 \item{\verb+sp[^*#$]/g[o#_]/+$\SLDROP$}\\
630 remove the \ONODE{}, remove the $\SLDROP$ and insert the cursor after the \SP{} node.
632 %situations where the \SLDROP is a p's child
633 \item{\verb+c/p[^#$]/+$\SLDROP$}\\
634 remove the $\SLDROP$ and insert it before the \PNODE{}.
641 \item{\verb+g/+$\tadvance$}\\
642 replace $\tadvance$ with the cursor
644 \item{\verb+p[#$]/+$\tadvance$}\\ %$
645 put $\tadvance$ after the \PNODE{} node
647 \item{\verb+c[#p]/+$\tadvance$} \\
648 remove $\tadvance$, put the cursor as first child of the \PNODE{} node
650 \item{\verb+c[#*]/+$\tadvance$} \\ %$
651 replace $\tadvance$ with the cursor
653 \item{\verb+c[#$]/+$\tadvance$} \\ %$
654 move $\tadvance$ after the \CNODE{} node
657 \paragraph{Next Parameter}
659 \paragraph{Next Token}
661 %% \begin{description}
662 %% \item{\verb+c[#p]/+$\tnext$} \\
665 % g[@id]/(c[#$][@right-open]/g[!@id][#$]/)+cursor } let p = cursor.parent() in remove; advance(p)
669 % */cursor { let g = new group in replace
671 % g[@id][^#$]/cursor <= cursor.parent().replace(cursor)
672 % g[@id][^#$]/cursor <- cursor
673 % (!g[@id][^#$])[A#B]/(g[@id][^#$]/)+cursor <- (!g[@id][^#$])[A#B]/cursor