diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex | 460 |
1 files changed, 354 insertions, 106 deletions
diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex index a31b2db2183..316d2fe27e2 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex @@ -1,8 +1,8 @@ %% -%% Package: spectralsequences v1.1.1 2017-09-16 2017-09-16 +%% Package: spectralsequences v1.2.0 2017-09-16 2017-09-16 %% Author: Hood Chatham %% Email: hood@mit.edu -%% Date: 2017-09-16 +%% Date: 2017-12-10 %% License: Latex Project Public License %% %% File: sseqparsers.code.tex @@ -99,10 +99,12 @@ % Spaces matter to us, because \sseq@ifintexpr{1 1} is false but \sseqsifintexpr{11} is true % so we make spaces into catcode other and use \scantokens +\def\sseq@fexpsafenil{\@nx\sseq@fexpsafenil} + \def\sseq@ifintexpr#1{% \bgroup \sseq@tempcount\z@ - \sseq@ifintexpr@{needsint}#1\sseq@nil% + \sseq@ifintexpr@{needsint}#1\sseq@fexpsafenil% \@xp\egroup\next } @@ -113,7 +115,7 @@ \ifx\testtok\bgroup% \let\next\sseq@ifintexpr@false \else - \ifx\testtok\sseq@nil + \ifx\testtok\sseq@fexpsafenil \@xp\let\@xp\next\csname sseq@ifintexpr@@\sseq@ifintexpr@state @done\endcsname \else % We need to check here for a space because \string<space> produces NO OUTPUT regardless of the catcode of the space. @@ -155,8 +157,8 @@ % so then "\csname hello\testtok\endcsname" is an error. This indexes into our state machine, % cases: a digits, + or -, * or /, (, ), or something else (anything else always leads to false \def\sseq@ifintexpr@@@@#1{% - \ifx#1\sseq@nil - \def\next{\csname sseq@ifintexpr@@\sseq@ifintexpr@state @done\endcsname\sseq@nil}% + \ifx#1\sseq@fexpsafenil + \def\next{\csname sseq@ifintexpr@@\sseq@ifintexpr@state @done\endcsname\sseq@fexpsafenil}% \else \sseq@ifdigit{#1}% {\sseq@ifintexpr@next{digit}}% @@ -187,8 +189,8 @@ \next } -\def\sseq@ifintexpr@true#1\sseq@nil{\ifnum\sseq@tempcount=\z@ \let\next\@firstoftwo\else\let\next\@secondoftwo\fi} -\def\sseq@ifintexpr@false#1\sseq@nil{\let\next\@secondoftwo} +\def\sseq@ifintexpr@true#1\sseq@fexpsafenil{\ifnum\sseq@tempcount=\z@ \let\next\@firstoftwo\else\let\next\@secondoftwo\fi} +\def\sseq@ifintexpr@false#1\sseq@fexpsafenil{\let\next\@secondoftwo} \def\sseq@makeifint#1#2#3{\@xp\def\csname sseq@ifintexpr@@#1@#2\endcsname{#3}} \def\sseq@ifintexpr@next#1{\@xp\let\@xp\next\csname sseq@ifintexpr@@\sseq@ifintexpr@state @#1\endcsname} @@ -234,6 +236,8 @@ %% %% This parser defines the syntax for the page argument of \d. %% +%% #1 -- callback. Will pass control to this function when done. +%% stores output in \sseq@dpage \def\sseq@d@grabpage#1{ \let\sseq@grabdpage@return#1 \futurelet\testtok\sseq@grabdpage@ @@ -497,33 +501,47 @@ \ifpgfutil@in@ \sseq@parsecoord@maincoord@@#1,\sseq@nil \else - \sseq@obj@ifdef{class.namedclass.\detokenize{#1}}{ - \def\sourcename{#1} - \@xpthree\sseq@parsecoord@maincoord@named\sseq@obj{class.namedclass.#1}\sseq@nil + \pgfutil@in@{lastclass}{#1} + \ifpgfutil@in@ + \def\handledname{#1} + \else + \sseq@protectedeval{\@nx\sseq@classname@handler{\sseq@classnameprefix#1\sseq@classnamepostfix}} + \let\handledname\result + \fi + \sseq@obj@ifdef{class.namedclass.\detokenize\@xp{\handledname}}{ + \let\sourcename\handledname + \@xpthree\sseq@parsecoord@maincoord@named\sseq@obj{class.namedclass.\detokenize\@xp{\sourcename}}\sseq@nil }{ - \sseq@error{invalid-coordinate}\sseq@breakfifi + \sseq@error{invalid-coordinate}\sseq@breakfifi } \fi \fi } \def\sseq@parsecoord@maincoord@@#1,#2,#3\sseq@nil{% - \sseq@obj@ifdef{class.namedclass.\detokenize{#1}}{ - \def\sourcename{#1} - \@xpthree\sseq@parsecoord@maincoord@named\sseq@obj{class.namedclass.#1}\sseq@nil - \edef\sseq@restcoord{\sseq@removecomma#2,#3\sseq@nil} - }{ - \sseq@ifintexpr{#1}{ - \sseq@ifintexpr{#2}{}{\sseq@error@n{invalid-coordinate}{y~}\sseq@breakfifi} % breakfifi to get out of ifs from maincoord@ - \edef\sseq@xcoord{\the\numexpr\sseq@x+(#1)\relax}% - \edef\sseq@ycoord{\the\numexpr\sseq@y+(#2)\relax}% - \edef\sseq@xycoord{\sseq@xcoord,\sseq@ycoord}% - \sseq@ifempty{#3}{\let\sseq@restcoord\pgfutil@empty}{% - \edef\sseq@restcoord{\sseq@removecomma#3\sseq@nil}% - }% - }{ + \sseq@ifintexpr{#1}{% + \sseq@ifintexpr{#2}{}{\sseq@error@n{invalid-coordinate}{y~}\sseq@breakfifi} % breakfifi to get out of ifs from maincoord@ + \edef\sseq@xcoord{\the\numexpr\sseq@x+(#1)\relax}% + \edef\sseq@ycoord{\the\numexpr\sseq@y+(#2)\relax}% + \edef\sseq@xycoord{\sseq@xcoord,\sseq@ycoord}% + \sseq@ifempty{#3}{\let\sseq@restcoord\pgfutil@empty}{% + \edef\sseq@restcoord{\sseq@removecomma#3\sseq@nil}% + }% + }{% + \pgfutil@in@{lastclass}{#1}% + \ifpgfutil@in@ + \def\handledname{#1}% + \else + \sseq@protectedeval{\@nx\sseq@classname@handler{\sseq@classnameprefix#1\sseq@classnamepostfix}}% + \let\handledname\result + \fi + \sseq@obj@ifdef{class.namedclass.\detokenize\@xp{\handledname}}{% + \def\sourcename{#1} + \@xpthree\sseq@parsecoord@maincoord@named\sseq@obj{class.namedclass.\detokenize{#1}}\sseq@nil + \edef\sseq@restcoord{\sseq@removecomma#2,#3\sseq@nil}% + }{% \sseq@error@n{invalid-coordinate}{x~}\sseq@breakfifi % breakfifi to get out of ifs from maincoord@ - } + }% }% }% @@ -587,14 +605,19 @@ % #1 -- name to define % #2 -- coordinate % #3 -- the error message +\def\sseq@eatparens(#1){#1} \def\sseq@parsecoord#1#2#3{% - \def\sseq@index{} - \def\sseq@errortype{#3} + \def\sseq@index{}% + \def\sseq@errortype{#3}% \sseq@parsecoord@maincoord{#2}% \let\sseq@rawindex\sseq@restcoord \ifx\sseq@index\pgfutil@empty \@xp\sseq@parsecoord@index \fi + \sseq@parsecoord@setupvariables{#1}{#2} +} + +\def\sseq@parsecoord@setupvariables#1#2{ % TODO: clean this up a bit? it's pretty ad-hoc. % Whenever you update this, make sure to update sseq@paredcoords@swap below too. \@xp\let\csname x\sseq@macroname#1\endcsname\sseq@xcoord @@ -603,29 +626,55 @@ \@xp\let\csname \sseq@macroname#1@partial\endcsname\sseq@xycoord \edef#1{(\sseq@xycoord,\sseq@index)}% \@xp\edef\csname\sseq@macroname#1nopar\endcsname{\sseq@xycoord,\sseq@index} - \@xp\def\csname\sseq@macroname#1name\endcsname{(#2)}% - \@xp\def\csname\sseq@macroname#1nameunbraced\endcsname{#2}% + \@xp\edef\csname\sseq@macroname#1name\endcsname{(#2)}% + \@xp\edef\csname\sseq@macroname#1nameunbraced\endcsname{\@xptwo\sseq@eatparens\csname\sseq@macroname#1name\endcsname}% edef? \@xp\edef\csname\sseq@macroname#1@internalname\endcsname{sseq{\sseq@xycoord,\sseq@index}}% } + +% This quiets parsecoord for the rest of the current scope. +% The reason we did it this way is because parsecoord makes too many local definitions... +\def\sseq@quiet@parsecoord{ + \msg_redirect_name:nnn {spectralsequences}{invalid-coordinate}{none} + \msg_redirect_name:nnn {spectralsequences}{no-classes}{none} + \msg_redirect_name:nnn {spectralsequences}{index-too-large}{none} + \msg_redirect_name:nnn {spectralsequences}{undefined-tag}{none} +} + + +% These are used for \replacesource and \replacetarget, though they might be useful for other things too. +\def\sseq@parsedcoord@save#1#2{ + \cs_gset_eq:cc { sseq@parsedcoord@save@x#1 } { x\sseq@macroname#2 } + \cs_gset_eq:cc { sseq@parsedcoord@save@y#1 } { y\sseq@macroname#2 } + \cs_gset_eq:cc { sseq@parsedcoord@save@n#1 } { n\sseq@macroname#2 } + \cs_gset_eq:cc { \sseq@macroname#1@partial } { \sseq@macroname#2@partial } + \cs_gset_eq:cN { sseq@parsedcoord@save@#1 } #2 + \cs_gset_eq:cc { sseq@parsedcoord@save@#1nopar } { \sseq@macroname#2nopar } + \cs_gset_eq:cc { sseq@parsedcoord@save@#1name } { \sseq@macroname#2name } + \cs_gset_eq:cc { sseq@parsedcoord@save@#1nameunbraced } { \sseq@macroname#2nameunbraced } + \cs_gset_eq:cc { sseq@parsedcoord@save@#1@internalname } { \sseq@macroname#2@internalname } +} + +\def\sseq@parsedcoord@restore#1#2{ + \cs_set_eq:cc { x\sseq@macroname#1 } { sseq@parsedcoord@save@x#2 } + \cs_set_eq:cc { y\sseq@macroname#1 } { sseq@parsedcoord@save@y#2 } + \cs_set_eq:cc { n\sseq@macroname#1 } { sseq@parsedcoord@save@n#2 } + \cs_set_eq:cc { \sseq@macroname#1@partial } { #2@partial } + \cs_set_eq:Nc #1 { sseq@parsedcoord@save@#2 } + \cs_set_eq:cc { \sseq@macroname#1nopar } { sseq@parsedcoord@save@#2nopar } + \cs_set_eq:cc { \sseq@macroname#1name } { sseq@parsedcoord@save@#2name } + \cs_set_eq:cc { \sseq@macroname#1nameunbraced } { sseq@parsedcoord@save@#2nameunbraced } + \cs_set_eq:cc { \sseq@macroname#1@internalname } { sseq@parsedcoord@save@#2@internalname } +} + % #1 & #2 -- the two base commands that were handed to \sseq@parsecoord to swap. % This is only used in \structline to normalize the name of structure lines, so that sseqpages knows what you are talking about % if you say \structline(coorda)(coordb) and then later \structline(coordb)(coorda) -\cs_new:Npn \sseq_swapmacros:NN #1#2 { - \let\sseq@temp#1 \let#1#2 \let#2\sseq@temp -} -\cs_generate_variant:Nn \sseq_swapmacros:NN { cc } - \def\sseq@parsedcoords@swap#1#2{ - \sseq_swapmacros:cc { x\sseq@macroname#1 } { x\sseq@macroname#2 } - \sseq_swapmacros:cc { y\sseq@macroname#1 } { y\sseq@macroname#2 } - \sseq_swapmacros:cc { n\sseq@macroname#1 } { n\sseq@macroname#2 } - \sseq_swapmacros:cc { \sseq@macroname#1@partial } { \sseq@macroname#2@partial } - \sseq_swapmacros:NN #1 #2 - \sseq_swapmacros:cc { \sseq@macroname#1nopar } { \sseq@macroname#2nopar } - \sseq_swapmacros:cc { \sseq@macroname#1name } { \sseq@macroname#2name } - \sseq_swapmacros:cc { \sseq@macroname#1nameunbraced } { \sseq@macroname#2nameunbraced } - \sseq_swapmacros:cc { \sseq@macroname#1@internalname } { \sseq@macroname#2@internalname } + \sseq@parsedcoord@save{swaptempa}{#1} + \sseq@parsedcoord@save{swaptempb}{#2} + \sseq@parsedcoord@restore{#1}{swaptempb} + \sseq@parsedcoord@restore{#2}{swaptempa} } % EXPOSE: a wrapper around \sseq@parsecoord. Use full name of coordinate to avoid name class with sseq@parsecoord. @@ -672,16 +721,8 @@ \sseq@error{d-named-coord-two-indexes} \fi \fi - \let\sourcecoord\sseq@xycoord -% - \let\xsource\sseq@xcoord - \let\ysource\sseq@ycoord - \let\nsource\sseq@index -% - \edef\source{(\sseq@xycoord,\sseq@index)}% - \ifx\sourcename\undefined - \edef\sourcename{(\sseq@xycoord\ifx\sseq@rawindex\pgfutil@empty\else,\sseq@rawindex\fi)} - \fi + \sseq@parsecoord@setupvariables{\source}{(\sseq@xycoord\ifx\sseq@rawindex\pgfutil@empty\else,\sseq@rawindex\fi)} + \let\sourcecoord\source@partial \IfNoValueTF{#3}{ \ifsseq@hasdegree\else\sseq@error{d-no-degree}\@xp\sseq@break\fi \sseq@eval{\edef\@nx\sseq@xycoord{\@nx\sseq@differential@gettarget{#1}{\sseq@xycoord}}} @@ -689,11 +730,7 @@ \def\sseq@errortype{target ~ of ~ differential} \sseq@parsecoord@index \let\targetcoord\sseq@xycoord - \edef\target{(\sseq@xycoord,\sseq@index)}% - \let\xtarget\sseq@xcoord - \let\ytarget\sseq@ycoord - \let\ntarget\sseq@index - \edef\targetname{(\sseq@xycoord\ifx\sseq@rawindex\pgfutil@empty\else,\sseq@rawindex\fi)} + \sseq@parsecoord@setupvariables{\target}{(\sseq@xycoord\ifx\sseq@rawindex\pgfutil@empty\else,\sseq@rawindex\fi)} }{ \ifx\sseq@rawtindex\pgfutil@empty\else \sseq@error{d-target-index-target-coord} @@ -709,6 +746,8 @@ \fi \fi } + \sseq@parsedcoord@save{lastsource}{\source} + \sseq@parsedcoord@save{lasttarget}{\target} } \def\sseq@differential@gettarget#1#2{\sseq@differential@gettarget@{#1}#2\sseq@nil} @@ -735,8 +774,12 @@ % EXPOSE: a wrapper around \sseq@dparsecoord. -\sseq@DeclareDocumentCommand \parsedifferential { m r() d() }{% - \sseq@dparsecoord{#1}{#2}{#3}% +\protected\def\sseq@parsedifferential{% + \sseq@d@grabpage\sseq@parsedifferential@ +} + +\DeclareDocumentCommand \sseq@parsedifferential@ { d() d() } {% + \sseq@eval{\@nx\sseq@dparsecoord{\sseq@dpage}{\IfNoValueTF{#1}{\lastclass0}{\unexpanded{#1}}}{\unexpanded{#2}}}% } % Expandable coordinate parsing for \isalive. @@ -913,21 +956,46 @@ \egroup } +\prg_new_conditional:Npnn \sseq_if_empty:n #1 {T,F,TF} { + \sseq@ifempty{\prg_return_true:}{\prg_return_false:} +} + +\let\SseqIfEmptyTF\sseq_if_empty:nTF +\let\SseqIfEmptyT\sseq_if_empty:nT +\let\SseqIfEmptyF\sseq_if_empty:nF + +% Test if a class exists. +\prg_new_conditional:Npnn \sseq_if_exists:n #1 { T , F , TF } { + \bgroup + \sseq@tempiftrue + \sseq@quiet@parsecoord + \sseq@parsecoord\coord{#1}{} + \@gobbletwo\sseq@breakpoint\sseq@tempiffalse % this executes \sseq@tempiffalse if we broke, otherwise it gets gobbled + \ifsseq@tempif + \egroup + \prg_return_true: + \else + \egroup + \prg_return_false: + \fi +} + +% Test if a class is out of bounds. Return false if the class doesn't exist. \prg_new_conditional:Npnn \sseq_if_out_of_bounds:n #1 { T , F , TF } { \bgroup \sseq@tempiftrue + \sseq@quiet@parsecoord \sseq@parsecoord\coord{#1}{} \@gobbletwo\sseq@breakpoint\sseq@tempiffalse % this executes \sseq@tempiffalse if we broke, otherwise it gets gobbled \ifsseq@tempif \sseq_if_out_of_bounds_noparse:nnTF { \xcoord } { \ycoord }{\egroup\prg_return_true:}{\egroup\prg_return_false:} \else \egroup - \prg_return_false + \prg_return_false: \fi } % For internal use b/c it's faster not to call \sseq@parsecoord -% There's no noticeable performance boost though... =( \prg_new_conditional:Npnn \sseq_if_out_of_bounds_noparse:nn #1#2 {TF} { \sseq@tempiftrue \ifnum#1<\sseq@xmaxpp\relax\ifnum#1>\sseq@xminmm\relax\ifnum#2<\sseq@ymaxpp\relax\ifnum#2>\sseq@yminmm\relax @@ -940,6 +1008,115 @@ \fi } +\prg_new_conditional:Npnn \sseq_if_alive:nn #1 #2 { T, F, TF } { + \bgroup + \sseq@tempiftrue + \sseq@quiet@parsecoord + \sseq@parsecoord\coord{#2}{} + \@gobbletwo\sseq@breakpoint\sseq@tempiffalse + \ifsseq@tempif + \sseq@obj@pagetogen{class.\coord}{#1} + \ifnum\sseq@gen>-1\relax + \egroup + \prg_return_true: + \else + \egroup + \prg_return_false: + \fi + \else + \egroup + \prg_return_false: + \fi +} + + +\protected\def\sseq@DrawIfValidDifferential{\sseq@DrawIfValidDifferential@{}{}} +\protected\def\sseq@DrawIfValidDifferentialT{\sseq@DrawIfValidDifferential@{T}{}} +\protected\def\sseq@DrawIfValidDifferentialF{\sseq@DrawIfValidDifferential@{}{F}} +\protected\def\sseq@DrawIfValidDifferentialTF{\sseq@DrawIfValidDifferential@{T}{F}} + +\DeclareDocumentCommand\sseq@DrawIfValidDifferential@{mmO{}}{% + \begingroup + \sseq@loadinputline + \def\sseq@dtype{d} + \def\sseq@trueclause{#1} + \def\sseq@falseclause{#2} + \def\sseq@doptions{#3} + \sseq@d@grabpage\sseq@DrawIfValidDifferential@@ +} + + +% #4 -- first coord +% #5 -- possible second coord +\DeclareDocumentCommand \sseq@DrawIfValidDifferential@@ { d() d() } {% + \ifx\sseq@trueclause\pgfutil@empty + \@xp\@firstoftwo + \else + \@xp\@secondoftwo + \fi{\sseq@DrawIfValidDifferential@@@{#1}{#2}{}} + {\sseq@DrawIfValidDifferential@@@{#1}{#2}} +} + +% #1 -- first coord +% #2 -- possible second coord +% #3 -- rest of true clause +\def \sseq@DrawIfValidDifferential@@@#1#2#3{ + \sseq@eval{\endgroup%\@nx\tracingall + \exp_not:c{sseq_if_valid_differential:nnT\sseq@falseclause}{\sseq@dpage}{\IfNoValueTF{#1}{\lastclass0}{\unexpanded{#1}}}{\unexpanded{#2}}{% + \@nx\d[\exp_not:o{\sseq@doptions}]\sseq@dpage\IfNoValueF{#1}{(\unexpanded{#1})}\IfNoValueF{#2}{(\unexpanded{#2})}% + \unexpanded{#3}% + }% + }% +} + +\protected\def\sseq@IfValidDifferentialTF{\sseq@IfValidDifferential{TF}} +\protected\def\sseq@IfValidDifferentialT{\sseq@IfValidDifferential{T}} +\protected\def\sseq@IfValidDifferentialF{\sseq@IfValidDifferential{F}} + +\protected\def\sseq@IfValidDifferential#1{% + \bgroup + \def\sseq@truefalseclauses{#1} + \sseq@d@grabpage{\sseq@IfValidDifferential@} +} + +\DeclareDocumentCommand \sseq@IfValidDifferential@ { d() d() } {% + \sseq@eval{\egroup\exp_not:c{sseq_if_valid_differential:nn\sseq@truefalseclauses}{\sseq@dpage}{\IfNoValueTF{#1}{\lastclass0}{\unexpanded{#1}}}{\unexpanded{#2}}}% +} + +\prg_new_conditional:Npnn \sseq_if_valid_differential:nn #1 #2 #3 { T, F, TF } { + \bgroup + \sseq@tempiftrue + \sseq@ifintexpr{#1}{% + \edef\sseq@pagenum{\the\numexpr#1\relax} + }{% + \sseq@break% return false + }% + \sseq@quiet@parsecoord + \msg_redirect_name:nnn {spectralsequences} {d-wrong-degree} {none} + \msg_redirect_name:nnn {spectralsequences} {d-target-index-target-coord} {none} + \msg_redirect_name:nnn {spectralsequences} {d-named-coord-two-indexes} {none} + \msg_redirect_name:nnn {spectralsequences} {d-hit-wrong-order} {none} + \msg_redirect_name:nnn {spectralsequences} {d-class-already-hit} {none} + \msg_redirect_name:nnn {spectralsequences} {d-hit-same-page-replaceclass}{none} + \sseq@dparsecoord{\sseq@pagenum}{#2}{#3} + \let\sseq@obj@xdef\@gobbletwo + \sseq@d@setpageclass{class.\source}{\sseq@pagenum}{source} + \sseq@d@setpageclass{class.\target}{\sseq@pagenum}{target} + \@gobbletwo\sseq@breakpoint\sseq@tempiffalse + \ifsseq@tempif + \egroup + \prg_return_true: + \else + \egroup + \prg_return_false: + \fi +} + + + +\sseq@DeclareDocumentCommand \IfExistsTF { r() } { \sseq_if_exists:nTF { #1 } } +\sseq@DeclareDocumentCommand \IfExistsT { r() } { \sseq_if_exists:nT { #1 } } +\sseq@DeclareDocumentCommand \IfExistsF { r() } { \sseq_if_exists:nF { #1 } } \sseq@DeclareDocumentCommand \IfOutOfBoundsTF { r() } { \sseq_if_out_of_bounds:nTF { #1 } } \sseq@DeclareDocumentCommand \IfOutOfBoundsT { r() } { \sseq_if_out_of_bounds:nT { #1 } } @@ -948,6 +1125,10 @@ \sseq@DeclareDocumentCommand \IfInBoundsT { r() } { \sseq_if_out_of_bounds:nF { #1 } } \sseq@DeclareDocumentCommand \IfInBoundsF { r() } { \sseq_if_out_of_bounds:nT { #1 } } +\sseq@DeclareDocumentCommand \IfAliveTF { mr() }{ \sseq_if_alive:nnTF{#1}{#2}} +\sseq@DeclareDocumentCommand \IfAliveT { mr() } { \sseq_if_alive:nnT{#1}{#2}} +\sseq@DeclareDocumentCommand \IfAliveF { mr() } { \sseq_if_alive:nnF{#1}{#2}} + %%%%%% %%% @@ -1201,13 +1382,15 @@ } } -\def\sseq@tikzprimitives@coords@maybenamedclass#1{ +\def\sseq@tikzprimitives@coords@maybenamedclass#1{% \sseq@tikzprimitive@getcoord@anchor#1.\sseq@nil % puts coord into \sseq@tempcoord, anchor if any into \sseq@tempanchor - \sseq@protectedeval{\@nx\sseq@obj@ifdef{class.namedclass.\@nx\detokenize{\sseq@tempcoord}}}{% need this detokenize here to prevent it from throwing errors when there's a command inside... - \sseq@x@addto@macro\sseq@thepathsofar{(sseq{\sseq@obj{class.namedclass.\sseq@tempcoord}\sseq@tempanchor})} - }{ - \sseq@tikzprimitives@coords@notaclass{#1} - } + \protected@edef\sseq@tempcoord{\sseq@tempcoord}% + % need this detokenize here to prevent it from throwing errors when there's a command inside... + \sseq@obj@ifdef{class.namedclass.\detokenize\@xp{\sseq@tempcoord}}{ + \sseq@x@addto@macro\sseq@thepathsofar{(sseq{\sseq@obj{class.namedclass.\detokenize\@xp{\sseq@tempcoord}}\sseq@tempanchor})}% + }{% + \sseq@tikzprimitives@coords@notaclass{#1}% + }% } \let\sseq@tikzprimitives@coords@maybeclass@save\sseq@tikzprimitives@coords@maybeclass @@ -1255,7 +1438,7 @@ \edef\sseq@index{,\unexpanded\@xp{\sseq@removecomma#3\sseq@nil}} \edef\sseq@indexnocomma{\unexpanded\@xp{\sseq@removecomma#3\sseq@nil}} } - \sseq@ifpgfmathexpr{#1}{ + \sseq@ifpgfmathexpr{#1}{% % Decide whether we can keep the result, which is stored in \sseq@mathresult \protected@edef\sseq@tempa{#1} \edef\sseq@tempb{#1} @@ -1388,25 +1571,46 @@ % We need to check for math subscript characters \char_set_catcode_math_subscript:N \_ -\protected\def\sseqnormalizemonomial#1{ +\def\sseq@support@std{} +\protected\def\SseqNormalizeMonomialSetVariables#1{% \bgroup - \def\sseq@support{} - \sseq@ifempty{#1}{1}{ + \gdef\sseq@support@std{}% + \def\sseqnormalizemonomial@add{% + \def\temp{1}% + \ifx\sseq@var\temp\else + \edef\sseq@var{\unexpanded\@xp{\sseq@var}\unexpanded\@xp{\sseq@subscript}}% + \@ifundefined{\sseqnormalizemonomial@varcs}{% + \@xp\xdef\csname\sseqnormalizemonomial@varcs\endcsname{0}% + \sseq@x@addto@macro\sseq@support@std{\@nx\\{\unexpanded\@xp{\sseq@var}}{\sseqnormalizemonomial@varcs}}% + }{}% + \fi + \sseqnormalizemonomial@testend + }% + \SseqNormalizeMonomial{#1}% + \egroup +} + + +\protected\def\SseqNormalizeMonomial#1{% + \bgroup + \def\sseq@ourinput{#1}% + \let\sseq@support\sseq@support@std + \sseq@ifempty{#1}{\egroup\def\result{1}}{% \sseqnormalizemonomial@#1\sseq@nil - } + }% } -\def\sseqnormalizemonomial@#1{ - \pgfkeys@spdef\sseq@var{#1} - \def\sseq@power{1} - \def\sseq@subscript{} +\def\sseqnormalizemonomial@#1{% + \pgfkeys@spdef\sseq@var{#1}% + \def\sseq@power{1}% + \def\sseq@subscript{}% \futurelet\testtok\sseqnormalizemonomial@@ } -\def\sseqnormalizemonomial@@{ - \ifx\testtok^ +\def\sseqnormalizemonomial@@{% + \ifx\testtok^% \let\next\sseqnormalizemonomial@sup \else - \ifx\testtok_ + \ifx\testtok_% \let\next\sseqnormalizemonomial@sub \else \let\next\sseqnormalizemonomial@add @@ -1415,40 +1619,46 @@ \next } -\def\sseqnormalizemonomial@sup^#1{ - \edef\sseq@power{\the\numexpr#1\relax} +\def\sseqnormalizemonomial@sup^#1{% + \sseq@ifintexpr{#1}{% + \edef\sseq@power{\the\numexpr#1\relax}% + }{% + \sseq@error@xxx{NormalizeMonomial-invalid-exponent}{\unexpanded{#1}}{\unexpanded\@xp{\sseq@var}}{\unexpanded\@xp{\sseq@ourinput}} + \let\result\sseq@ourinput + \sseq@gobble@to@nil + } \futurelet\testtok\sseqnormalizemonomial@@ } -\def\sseqnormalizemonomial@sub_#1{ - \def\sseq@subscript{_{#1}} +\def\sseqnormalizemonomial@sub_#1{% + \def\sseq@subscript{_{#1}}% \futurelet\testtok\sseqnormalizemonomial@@ } -\def\sseqnormalizemonomial@add{ - \def\temp{1} +\def\sseqnormalizemonomial@add{% + \def\temp{1}% \ifx\sseq@var\temp\else - \edef\sseq@var{\unexpanded\@xp{\sseq@var}\unexpanded\@xp{\sseq@subscript}} - \@ifundefined{\sseqnormalizemonomial@varcs}{ - \@xp\edef\csname\sseqnormalizemonomial@varcs\endcsname{\sseq@power} + \edef\sseq@var{\unexpanded\@xp{\sseq@var}\unexpanded\@xp{\sseq@subscript}}% + \@ifundefined{\sseqnormalizemonomial@varcs}{% + \@xp\edef\csname\sseqnormalizemonomial@varcs\endcsname{\sseq@power}% \sseq@e@addto@macro\sseq@support{\@nx\\{\unexpanded\@xp{\sseq@var}}{\sseqnormalizemonomial@varcs}}% - }{ - \@xp\edef\csname\sseqnormalizemonomial@varcs\endcsname{\the\numexpr\csname\sseqnormalizemonomial@varcs\endcsname + \sseq@power} - } + }{% + \@xp\edef\csname\sseqnormalizemonomial@varcs\endcsname{\the\numexpr\csname\sseqnormalizemonomial@varcs\endcsname + \sseq@power}% + }% \fi \sseqnormalizemonomial@testend } -\def\sseqnormalizemonomial@testend{ +\def\sseqnormalizemonomial@testend{% \ifx\testtok\sseq@nil \sseqnormalizemonomial@done - \sseq@smuggle@macro\processedlabel + \sseq@smuggle@macro\result \egroup \let\next\@gobble \else \@xp\ifx\space\testtok - \def\next{\@xp\futurelet\@xp\testtok\@xp\sseqnormalizemonomial@testend\romannumeral-`0} + \def\next{\@xp\futurelet\@xp\testtok\@xp\sseqnormalizemonomial@testend\romannumeral-`0}% \else \let\next\sseqnormalizemonomial@ \fi @@ -1458,22 +1668,22 @@ \def\sseqnormalizemonomial@varcs{sseqnormalizemonomial@var@\detokenize\@xp{\sseq@var}} -\def\sseqnormalizemonomial@done{ - \def\processedlabel{} - \def\\##1##2{ +\def\sseqnormalizemonomial@done{% + \def\result{}% + \def\\##1##2{% \sseq@tempcount=\csname ##2\endcsname\relax \ifnum\sseq@tempcount=\z@ \else \ifnum\sseq@tempcount=\@ne - \sseq@d@addto@macro\processedlabel{##1} + \sseq@d@addto@macro\result{##1}% \else - \sseq@e@addto@macro\processedlabel{\unexpanded{##1}^{\the\sseq@tempcount}} + \sseq@e@addto@macro\result{\unexpanded{##1}^{\the\sseq@tempcount}}% \fi \fi - } + }% \sseq@support - \ifx\processedlabel\pgfutil@empty % use 1 for empty monomial - \def\processedlabel{1} + \ifx\result\pgfutil@empty % use 1 for empty monomial + \def\result{1}% \fi } @@ -1481,6 +1691,44 @@ \catcode`\_ = 11\relax +\def\SseqAHSSNameHandler#1{ + \pgfutil@in@[{#1} + \ifpgfutil@in@ + \@xp\@firstofone + \else + \sseq@error{AHSSNameHandler-missing-cell}{#1} + \def\result{#1} + \@xp\@gobble + \fi{ + \SseqAHSSNameHandler@#1\sseq@nil + } +} + + +\def\SseqAHSSNameHandler@#1[#2\sseq@nil{ + \pgfutil@in@]{#2} + \ifpgfutil@in@ + \@xp\@firstofone + \else + \sseq@error{AHSSNameHandler-missing-cell}{#1[#2} + \def\result{#1[#2} + \@xp\@gobble + \fi{ + \SseqAHSSNameHandler@@{#1}#2\sseq@nil + } +} + +\def\SseqAHSSNameHandler@@#1#2]#3\sseq@nil{ + \SseqNormalizeMonomial{#1#3} + \sseq@ifintexpr{#2}{ + \edef\result{\unexpanded\@xp{\result}[\the\numexpr#2+\sseq@y]} + }{ + \sseq@error{AHSSNameHandler-invalid-integer}{#2}{#1[#2]#3} + \edef\result{\unexpanded\@xp{\result[#2]}} + } +} + + -\ExplSyntaxOff
\ No newline at end of file +\ExplSyntaxOff |