summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex')
-rw-r--r--Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex460
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