From 6fde3f8617ebf837a452f38c9d715f70d93e71e2 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 11 Dec 2017 22:22:32 +0000 Subject: spectralsequences (11dec17) git-svn-id: svn://tug.org/texlive/trunk@46038 c570f23f-e606-0410-a88d-b1316a301751 --- .../latex/spectralsequences/spectralsequences.sty | 47 ++- .../sseqcheckdefinitions.code.tex | 4 +- .../latex/spectralsequences/sseqdrawing.code.tex | 32 +- .../latex/spectralsequences/sseqforeach.code.tex | 12 +- .../tex/latex/spectralsequences/sseqkeys.code.tex | 166 +++++--- .../latex/spectralsequences/sseqloadstore.code.tex | 14 +- .../spectralsequences/sseqmacromakers.code.tex | 4 +- .../tex/latex/spectralsequences/sseqmain.code.tex | 262 +++++++++--- .../latex/spectralsequences/sseqmessages.code.tex | 24 +- .../latex/spectralsequences/sseqparsers.code.tex | 460 ++++++++++++++++----- 10 files changed, 769 insertions(+), 256 deletions(-) (limited to 'Master/texmf-dist/tex/latex/spectralsequences') diff --git a/Master/texmf-dist/tex/latex/spectralsequences/spectralsequences.sty b/Master/texmf-dist/tex/latex/spectralsequences/spectralsequences.sty index 7faf6d6c39e..94b16a24f47 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/spectralsequences.sty +++ b/Master/texmf-dist/tex/latex/spectralsequences/spectralsequences.sty @@ -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 %% %% A package for drawing spectral sequences @@ -10,8 +10,10 @@ % TODO: -% +% Try catch blocks % Make an argument type for the \d page argument. +% deal with xmin, xmax, etc (was there actually a problem we were trying to fix?) +% Make xmirror not mirror axes labels % % Redo sseqerrortest and set up regression test script as part of build (damn I didn't realize we'd lost anything imporant with that find -d disaster) % Maybe we should add some other regression tests too @@ -25,13 +27,12 @@ \NeedsTeXFormat{LaTeX2e} -\ProvidesPackage{spectralsequences}[2017/09/16 v1.1.1] +\ProvidesPackage{spectralsequences}[2017/12/10 v1.2.0] \RequirePackage{tikz} \RequirePackage{etoolbox} \RequirePackage{xparse} \RequirePackage{verbatim} -\RequirePackage{pdfcomment} \usetikzlibrary{quotes} \usetikzlibrary{fit} @@ -44,9 +45,15 @@ %\usetikzlibrary{profiler} \newif\ifsseq@draftmode +\newif\ifsseq@tooltip \DeclareOption{draft}{\sseq@draftmodetrue} +\DeclareOption{tooltips}{\sseq@tooltiptrue} \ProcessOptions\relax +\ifsseq@tooltip + \RequirePackage{pdfcomment} +\fi + \def\sseq@authorname{Hood Chatham} \def\sseq@authoremail{hood@mit.edu} @@ -54,12 +61,18 @@ % Commands we are going to expose just inside of environments \def\sseq@macrolist{% \xcoord\ycoord\page %\xmin\xmax\ymin\ymax % these just get protected + % Defined in sseqmessages: + \quiet\endquiet % These are defined in sseqmain: - \class\classoptions\replaceclass\d\doptions\kill\structline\structlineoptions\circleclasses + \class\classoptions\replaceclass\replacesource\replacetarget + \d\doptions\kill\structline\structlineoptions\circleclasses % The following are defined in sseqparsers: \pgfmathparse\isalive\lastx\lasty\lastclass\savestack\restorestack\pushstack\nameclass\tagclass \parsecoordinate\parsedifferential\getdtarget\gettag \IfOutOfBoundsTF\IfOutOfBoundsT\IfOutOfBoundsF\IfInBoundsTF\IfInBoundsT\IfInBoundsF + \IfExistsTF\IfExistsT\IfExistsF\IfAliveTF\IfAliveT\IfAliveF + \IfValidDifferentialTF\IfValidDifferentialT\IfValidDifferentialF + \DrawIfValidDifferentialTF\DrawIfValidDifferentialT\DrawIfValidDifferentialF\DrawIfValidDifferential % sseqforeach \Do\DoUntilOutOfBounds\DoUntilOutOfBoundsThenNMore } @@ -121,7 +134,7 @@ \newcount\sseq@tempy \newcount\sseq@tempxb \newcount\sseq@tempyb -\newcount\sseq@xoffset % We add these to everything to avoid overflow errors as much as we possible +\newcount\sseq@xoffset % We add these to everything to avoid overflow errors as much as possible \newcount\sseq@yoffset \newcount\sseq@stackdepth @@ -279,6 +292,7 @@ \input sseqparsers.code.tex % Responsible for making tikz modifications, exposes directly \sseqnormalizemonomial, \sseqparseint + \ifsseq@patchforeach \input sseqforeach.code.tex \else @@ -286,9 +300,20 @@ \fi \input sseqkeys.code.tex % Exposes directly: \sseqset, \sseqnewfamily -\input sseqmain.code.tex % Defines all the main commands. Exposes directly: the environments, \xmin, \xmax, etc. +\input sseqmain.code.tex % Defines all the main commands. Exposes directly: the environments, \xmin, \xmax, etc, \SseqCopyPage \input sseqdrawing.code.tex +% Give standard definitions for savedpaths wrappers +\def\sseq@beginscope@object{\begin{scope}} +\def\sseq@endscope@object{\end{scope}} +\let\sseq@scope@object\@firstofone +\let\sseq@style@object\@firstofone +\let\sseq@class@object\sseq@class@draw@ifpage +\let\sseq@differential@object\sseq@differential@draw@ifpage +\let\sseq@structline@object\sseq@structline@draw@ifpage +\let\sseq@circleclass@object\sseq@circleclass@draw@ifpage +\let\sseq@tikzpath@object\@firstofone + %%% Some default key settings \sseqset{ @@ -301,8 +326,14 @@ pins=help lines } +\ifsseq@tooltip + \let\sseqtooltip\sseq@tooltip@wrapper +\fi + % Extra commands to expose: \let\sseqifempty\sseq@ifempty +\let\SseqParseInt\sseqparseint +\let\SseqNewFamily\sseqnewfamily \def\sseqpower#1#2{\@xp\sseqtypesetpower@\@xp{\the\numexpr#2}{#1}{1}} \def\sseqpowerempty#1#2{\@xp\sseqtypesetpower@\@xp{\the\numexpr#2}{#1}{}} diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqcheckdefinitions.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqcheckdefinitions.code.tex index e9162a02d15..aba45169816 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqcheckdefinitions.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqcheckdefinitions.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: sseqcheckdefinitions.code.tex diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex index 2574da643a9..9ea6d4397fc 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqdrawing.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: sseqdrawing.code.tex @@ -245,7 +245,7 @@ \sseq@tickloop@generic{\sseq@xmin}{\sseq@xmax}{\sseq@xtickstep}{\sseq@xtickstepoffset}{\sseq@yaxisorigin}{-\sseq@xaxisgap}{ \sseq@xtickstyle \tikz@options - \pgftransformshift{\pgfqpoint{0pt}{-\sseq@ylabelgap}} + \pgftransformshift{\pgfqpoint{0pt}{-\sseq@xlabelgap}} \pgftext{\hbox{$\sseq@xtickfn{\the\sseq@tempx}$}}% } \ifnum\sseq@xmajortickstep>\z@ @@ -565,7 +565,7 @@ \sseq@tempy=#3\relax } -\def\sseqtooltip#1#2{% +\def\sseq@tooltip@wrapper#1#2{% \edef\temp{\detokenize\@xpthree{#2}}% \edef\temp{\@xp\sseqtooltip@replaceslashes\@xp{\temp}}% \sseq@eval{\@nx\pdftooltip{\unexpanded{#1}}{\temp}}% @@ -627,7 +627,7 @@ \fi \def\sseq@collections@featuretype{class} \the\sseq@scope@toks - \sseq@obj{#1.options}% + \sseq@obj{#1.options} \pgftransformshift{\pgfqpointxy{\numexpr\sseq@tempx +\sseq@xoffset-\sseq@x\relax}{\numexpr\sseq@tempy + \sseq@yoffset-\sseq@y\relax}} \iftikz@fullytransformed\pgfgettransform{\savetransform}\fi \pgftransformresetnontranslations @@ -638,25 +638,35 @@ }% \iftikz@fullytransformed\pgfsettransform{\savetransform}\else\pgftransformresetnontranslations\ifsseq@rotatelabels\sseq@globalrotatetransform\fi\fi \tikz@options + % the value of \sseq@class@showname comes from styles. If there was a local option with showname, it's stored in #1.showname. + % local value takes priority. + \let\sseq@classlabelnodes\pgfutil@empty + \edef\sseq@classnodetextoptions{\sseq@obj@ifdef{#1.nodetext.options}{\@xptwo\@nx\sseq@obj{#1.nodetext.options}}{}} + \edef\sseq@classnodetext{\sseq@obj@ifdef{#1.nodetext}{\@xptwo\@nx\sseq@obj{#1.nodetext}}{}} + \sseq@obj@ifdef{#1.showname}{\sseq@lettoobj\sseq@class@showname{#1.showname}}{} + \ifcsname sseq@class@showname\endcsname + \sseq@obj@ifdef{#1.name}{ + \sseq@eval{\@nx\sseq@handleclassquotes@inner{\sseq@obj{#1.name}}{\sseq@class@showname}} + }{} + \fi \ifsseq@needstikz \let\sseq@mode\tikz@mode - \tikzset{every text node part/.code/.expand once={\sseq@globalrotatetransform\sseq@obj@ifdef{#1.nodetext.options}{\sseq@obj{#1.nodetext.options}}{}}}% + \tikzset{every text node part/.code/.expand once={\sseq@globalrotatetransform\sseq@classnodetextoptions{}}}% \sseq@eval{% \@nx\node[/utils/exec={\let\@nx\tikz@mode\@nx\sseq@mode}, /handlers/first char syntax/the character "/.initial=\@nx\sseq@handlequote - ] (\sseq@thisnodename) {\sseq@obj@ifdef{#1.nodetext}{\unexpanded\@xpthree{\sseq@obj{#1.nodetext}}}{}} + ] (\sseq@thisnodename) {\unexpanded\@xp{\sseq@classnodetext}} [every text node part/.code={}]; }% \else \tikz@node@textfont - \edef\sseq@classnodetextoptions{\sseq@obj@ifdef{#1.nodetext.options}{\@xptwo\@nx\sseq@obj{#1.nodetext.options}}{}} - \edef\sseq@classnodetext{\sseq@obj@ifdef{#1.nodetext}{\@xptwo\@nx\sseq@obj{#1.nodetext}}{}} \sseq@setnodetext{\sseq@classnodetext}{\sseq@classnodetextoptions} \let\tikz@fig@name\sseq@thisnodename \pgfmultipartnode{\tikz@shape}{\tikz@anchor}{\tikz@fig@name}{\sseq@drawnode}% \tikz@alias \fi \sseq@obj{#1.labelnodes} + \sseq@classlabelnodes % classlabelnodes comes from show name \sseq@obj@ifdef{#1.tooltip}{ \pgfpointanchor{\sseq@thisnodename}{west} \pgf@xa=\pgf@x @@ -880,10 +890,10 @@ % If either class is part of a family we aren't drawing, don't draw the edge either. \expandafter\ifx\csname pgf@sh@pi@sseq{#1}\endcsname\pgfpictureid\else \@xp\sseq@break - \fi + \fi \expandafter\ifx\csname pgf@sh@pi@sseq{#2}\endcsname\pgfpictureid\else \@xp\sseq@break - \fi + \fi \def\sseq@edgetype{#3} \let\sseq@collections@featuretype\sseq@edgetype \let\sseq@edgesourceanchor\pgfutil@empty diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqforeach.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqforeach.code.tex index 71bd11cf52c..851f65ab3ac 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqforeach.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqforeach.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: sseqforeach.code.tex @@ -68,7 +68,7 @@ \def\sseq@DoUntilOutOfBounds@ #1 { \sseq@esetthiscall{\string\DoUntilOutOfBoundsThenNMore} \sseq@opushstacktrace{\string\DoUntilOutOfBounds} - \ifx\xmin\sseq@xmin\else\ifx\ymin\sseq@ymin\else + \ifx\sseq@xminmax\@gobbletwo\else\ifx\sseq@yminmax\@gobbletwo\else \sseq@error@x{DoUntil-no-bound}{\string\DoUntilOutOfBounds} \sseq@breakfifi \fi\fi @@ -90,7 +90,7 @@ \def\sseq@DoUntilOutOfBoundsThenNMore@ #1#2 { \sseq@esetthiscall{\string\DoUntilOutOfBoundsThenNMore\unexpanded{#1}} \sseq@opushstacktrace{\string\DoUntilOutOfBoundsThenNMore{#1}} - \ifx\xmin\sseq@xmin\else\ifx\ymin\sseq@ymin\else + \ifx\sseq@xminmax\@gobbletwo\else\ifx\sseq@yminmax\@gobbletwo\else \sseq@error@n{DoUntil-no-bound}{\DoUntilOutOfBoundsThenNMore} \sseq@breakfifi \fi\fi @@ -131,7 +131,7 @@ \sseq@tempy=\lasty{0}\relax \bool_set_false:N \l_tmpb_bool % This is to record whether there is a defined x range or y range. If neither, we'll throw an error. % \def\sseq@checkbound{\bool_set_false:N \l_tmpb_bool} - \ifx\xmin\sseq@xmin + \ifx\sseq@xminmax\@gobbletwo \ifnum\sseq@tempx>\sseq@tempxb \bool_set_true:N \l_tmpb_bool % We have a descent condition % \sseq@d@addto@macro\sseq@checkbound{ @@ -150,7 +150,7 @@ \fi \fi \fi - \ifx\ymin\sseq@ymin + \ifx\sseq@yminmax\@gobbletwo \ifnum\sseq@tempy>\sseq@tempyb \bool_set_true:N \l_tmpb_bool % \sseq@d@addto@macro\sseq@checkbound{ diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex index 8c08ffa3a64..fcb843904d2 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.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: sseqkeys.code.tex @@ -203,6 +203,7 @@ }% } + \def\sseq@keys@unknown@handlecolor{% \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\@nx\tikz@addoption{\@nx\tikz@compat@color@set{\tikz@key}}}}% \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\def\@nx\tikz@textcolor{\tikz@key}}}% @@ -294,6 +295,7 @@ \fi } + % This has to be expandable, so \sseq@tempa and \sseq@tempb are set to "/tikz/" and "/pgf/" ahead of time % Defer the command if it is in directories /pgf or /tikz, otherwise run it now. TODO: explain here why we need this. \def\sseq@options@secondpass@iftikz{% @@ -386,17 +388,19 @@ \@ifnextchar[{\sseq@setlabeldirectionkeys@{#1}}{\sseq@setlabeldirectionkeys@{#1}[/.code]}%] } \def\sseq@setlabeldirectionkeys@#1[#2]#3{ + \bgroup \def\sseq@temp##1{#3} \sseq@temptoks{} \def\\##1{ \sseq@eval{\sseq@temptoks{\the\sseq@temptoks##1#2={\unexpanded\@xp{\sseq@temp{##1}}},}} } \sseq@labeldirectionlist - \sseq@eval{\@nx\pgfqkeys{#1}{\the\sseq@temptoks}} + \sseq@eval{\egroup\@nx\pgfqkeys{#1}{\the\sseq@temptoks}} } - +\begingroup \def\\#1{\@xp\sseq@addtostorelist\csname sseq@default@#1@distance\endcsname{1ex}} \sseq@labeldirectionlist +\endgroup \def\sseq@defaultlabeldistance#1{\@xp\csname sseq@default@#1@distance\endcsname} \def\sseq@setdefaultlabeldistance#1#2{\sseq@savedpaths@add{\@xp\gdef\csname sseq@default@#1@distance\endcsname{#2}}} \def\sseq@setdefaultlabeldistances#1{\def\\##1{\sseq@setdefaultlabeldistance{##1}{#1}}\sseq@labeldirectionlist} @@ -419,8 +423,11 @@ -\sseq@addtostorelist\sseq@classlabeltextfn{} % \sseq@classlabeltextfn is public via "class label handler" -\def\sseq@classlabeltextfn@default#1{\def\processedlabel{#1}} +\sseq@addtostorelist\sseq@classlabel@handler{} % \sseq@classlabel@handler is public via "class label handler" +\def\sseq@classlabel@handler@default#1{\def\result{#1}} +\sseq@addtostorelist\sseq@classname@handler{} % \sseq@classname@handler is public via "class name handler" +\def\sseq@classname@handler@default#1{\def\result{#1}} + \def\sseq@labeltextfn#1{#1} % labeltextfn is private \def\sseq@labeltextfn@rotatescale#1{% \@nx\ifmmode @@ -488,13 +495,13 @@ } } - +% We just do the parsing in sseqkeys, \sseq@handleclassquotes@inner which does the main work is defined sseqmain. \def\sseq@handlescopequotes#1#2{% We use this via \let\tikz@quotes@as\sseq@handleclassquotes /utils/exec={% so it's called inside \pgfkeysalso{stuff}. Need to surround with /utils/exec={} to get out. \global\let\sseq@classnodetext\pgfutil@empty% \global\let\sseq@classnodetextoptions\pgfutil@empty% \global\let\sseq@classlabelnodes\pgfutil@empty% - \sseq@handleclassquotes@inner{#1}{#2}% + \sseq@handleclassquotes@inner{#1}{#2} } } @@ -535,7 +542,6 @@ \let\structline\sseq@structline } - \sseq@pgfqkeysdirlist{/sseqpages,/sseqpages/tikz primitives}{% standard parse/.code={ \let\sseq@firstpass@shifttransform\@gobbletwo @@ -556,6 +562,7 @@ /tikz/handle quote/.code={\sseq@error{tikz-edge-quotes}} } + \sseq@pgfqkeysdirlist{/sseqpages/class,/sseqpages/differential}{ standard parse/.sseq @ first pass code={\sseq@error@n{option-tikz-prims-only}{standard parse}}, background/.sseq @ first pass code={\sseq@error@n{option-tikz-prims-only}{background}} @@ -575,14 +582,25 @@ } \def\sseq@classinsert{} +\def\sseq@classnameprefix{} +\def\sseq@classnamepostfix{} +\pgfqkeys{/sseqpages}{ + class name prefix/.store in=\sseq@classnameprefix, + class name postfix/.store in=\sseq@classnamepostfix +} + \pgfqkeys{/sseqpages/class}{ - name/.code={\def\sseq@class@name{#1}\pgfkeysalso{/sseqpages/alias=#1}}, + name/.code={% + \sseq@protectedeval{\@nx\sseq@classname@handler{\sseq@classnameprefix#1\sseq@classnamepostfix}}% + \edef\sseq@class@name{\unexpanded\@xp{\result}}% + \pgfkeysalso{/sseqpages/alias/.expand once=\detokenize\@xp{\sseq@class@name}}% + }, show name/.store in=\sseq@class@showname, page/.code={\sseq@getnumrange\sseq@class@page{#1}},% page & gen are only for \classoptions. generation/.code={\sseq@getnumrange\sseq@gen{#1}}, % \class tests if \sseq@class@page is set and throw an error if so. tag/.code={\sseq@d@addto@macro\sseq@class@tag{#1}}, offset/.store in=\sseq@tempoffset, - tooltip/.sseq @ first pass code={\def\sseq@tooltip{#1}}, + tooltip/.sseq @ first pass code={\ifx\sseqtooltip\undefined \sseq@error{no-tooltip}\else \def\sseq@tooltip{#1}\fi}, insert/.store in=\sseq@classinsert } @@ -792,7 +810,7 @@ #1s/.ecode={% \@nx\sseq@addstylecodetotoks{\sseq@tempcmd}{\sseq@temppath}{##1} \@nx\ifsseq@inprogress - \@nx\sseq@savedpaths@xadd{\sseq@tempcmd{\@nx\the\sseq@tempcmd}}% + \@nx\sseq@savedpaths@xadd{\@nx\sseq@style@object{\sseq@tempcmd{\@nx\the\sseq@tempcmd}}}% \@nx\fi },% change #1s/.ecode={% @@ -826,7 +844,7 @@ }% \sseq@addstylecodetomacro\sseq@sseqstyle@globalpart{/sseqpages/global}{#1}% \ifsseq@inprogress - \sseq@savedpaths@xadd{\sseq@sseqstyle{\the\sseq@sseqstyle}}% + \sseq@savedpaths@xadd{\@nx\sseq@style@object{\sseq@sseqstyle{\the\sseq@sseqstyle}}}% \fi % Restore hook \let\sseq@addstylecodetooptions@unknown\sseq@keys@unknown @@ -892,8 +910,8 @@ %% Families (also called collections in code) %% %% These are supposed to make it easy to display / hide and change appearance of logically connected families of classes. -%% In order to allow a set of options to be given that applies uniformly to all features, we separately apply the options in each of these bins. -%% +%% In order to allow a set of options to be given that applies uniformly to all features, we separately apply the options in each of these bins. +%% \def\sseq@featurelist{\\{class}\\{differential}\\{structline}\\{circleclass}\\{tikzprimitive}} @@ -1311,9 +1329,11 @@ } \def\sseq@keys@removehandler#1{\sseq@keys@removehandler@#1=\sseq@nil} \def\sseq@keys@removehandler@#1/.#2=#3\sseq@nil{% + \bgroup \def\sseq@temp{#2}% - \def\\##1{\def\sseq@tempii{##1}\ifx\sseq@tempii\sseq@temp \sseq@tempiffalse\let\\\@gobble\fi}% + \def\\##1{\def\sseq@tempii{##1}\ifx\sseq@tempii\sseq@temp \global\sseq@tempiffalse\let\\\@gobble\fi}% \sseq@keys@ignorehandlers + \egroup \def\sseq@temp{#1}% } @@ -1477,6 +1497,7 @@ \sseq@addiftostorelist{specifiedxrange} \sseq@addiftostorelist{specifiedyrange} +% We used to \let\xmin\sseq@xmin in here, but that's a bad idea. Hopefully things work now... \def\sseq@xrange#1#2{% \global\let\sseq@xminmax\@gobbletwo % Don't need to calculate range of nodes if user specifies it \global\sseq@specifiedxrangetrue @@ -1484,22 +1505,19 @@ \sseq@sanitize@intexpr{#2}{x range={#1}{#2}} \xdef\sseq@xmin{\the\numexpr#1}% \xdef\sseq@xmax{\the\numexpr#2}% - \let\xmin\sseq@xmin - \let\xmax\sseq@xmax % Need to know decremented \xmin and incremented \xmax to decide which nodes to print \sseq@tempcount=#1 \advance\sseq@tempcount-1\xdef\sseq@xminmm{\the\sseq@tempcount}% \sseq@tempcount=#2 \advance\sseq@tempcount1\xdef\sseq@xmaxpp{\the\sseq@tempcount}% \sseq@breakpoint } + \def\sseq@yrange#1#2{% \global\let\sseq@yminmax\@gobbletwo % - \sseq@sanitize@intexpr{#1}{x range={#1}{#2}} - \sseq@sanitize@intexpr{#2}{x range={#1}{#2}} + \sseq@sanitize@intexpr{#1}{y range={#1}{#2}} + \sseq@sanitize@intexpr{#2}{y range={#1}{#2}} \global\sseq@specifiedyrangetrue - \gdef\sseq@ymin{#1}% - \gdef\sseq@ymax{#2}% - \let\ymin\sseq@ymin - \let\ymax\sseq@ymax + \xdef\sseq@ymin{\the\numexpr#1}% + \xdef\sseq@ymax{\the\numexpr#2}% \sseq@tempcount=#1 \advance\sseq@tempcount-1\xdef\sseq@yminmm{\the\sseq@tempcount}% \sseq@tempcount=#2 \advance\sseq@tempcount1\xdef\sseq@ymaxpp{\the\sseq@tempcount}% } @@ -1625,27 +1643,51 @@ x tick handler/.sseq default code={\def\sseq@xtickfn@default##1{#1}}, y tick handler/.code={\def\sseq@ytickfn##1{#1}}, y tick handler/.sseq default code={\def\sseq@ytickfn@default##1{#1}}, - class label handler/.code = { % \long so that \ifx\classlabeltextfn\@gobble compares true if this is empty (\@gobble is long...) - \long\def\sseq@classlabeltextfn##1{#1} - \ifx\sseq@classlabeltextfn\@gobble - \def\sseq@classlabeltextfn##1{\def\processedlabel{##1}} + class label handler/.code = { % \long so that \ifx\sseq@classname@handler\@gobble compares true if this is empty (\@gobble is long...) + \long\def\sseq@classlabel@handler##1{#1} + \ifx\sseq@classlabel@handler\@gobble + \def\sseq@classlabel@handler##1{\def\result{##1}} \else - \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabeltextfn{}}} - \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabeltextfn{blah}}} + \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabel@handler{}}} + \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabel@handler{blah}}} \ifx\sseq@tempa\sseq@tempb - \long\def\sseq@classlabeltextfn##1{#1{##1}} + \long\def\sseq@classlabel@handler##1{#1{##1}} \fi \fi }, class label handler/.sseq default code={ - \long\def\sseq@classlabeltextfn@default##1{#1} - \ifx\sseq@classlabeltextfn@default\@gobble - \def\sseq@classlabeltextfn@default##1{\def\processedlabel{##1}} + \long\def\sseq@classlabel@handler@default##1{#1} + \ifx\sseq@classlabel@handler@default\@gobble + \def\sseq@classlabel@handler@default##1{\def\result{##1}} \else - \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabeltextfn@default{}}} - \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabeltextfn@default{blah}}} + \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabel@handler@default{}}} + \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabel@handler@default{blah}}} \ifx\sseq@tempa\sseq@tempb - \long\def\sseq@classlabeltextfn@default##1{#1{##1}} + \long\def\sseq@classlabel@handler@default##1{#1{##1}} + \fi + \fi + }, + class name handler/.code = { % \long so that \ifx\sseq@classname@handler\@gobble compares true if this is empty (\@gobble is long...) + \long\def\sseq@classname@handler##1{#1} + \ifx\sseq@classname@handler\@gobble + \def\sseq@classname@handler##1{\def\result{##1}} + \else + \edef\sseq@tempa{\unexpanded\@xp{\sseq@classname@handler{}}} + \edef\sseq@tempb{\unexpanded\@xp{\sseq@classname@handler{blah}}} + \ifx\sseq@tempa\sseq@tempb + \long\def\sseq@classname@handler##1{#1{##1}} + \fi + \fi + }, + class name handler/.sseq default code={ + \long\def\sseq@classname@handler@default##1{#1} + \ifx\sseq@classname@handler@default\@gobble + \def\sseq@classname@handler@default##1{\def\result{##1}} + \else + \edef\sseq@tempa{\unexpanded\@xp{\sseq@classname@handler@default{}}} + \edef\sseq@tempb{\unexpanded\@xp{\sseq@classname@handler@default{blah}}} + \ifx\sseq@tempa\sseq@tempb + \long\def\sseq@classname@handler@default##1{#1{##1}} \fi \fi }, @@ -1700,15 +1742,27 @@ \let\sseq@axistypesanitizer\sseq@axistypesanitizera \pgfqkeys{/sseqpages}{% - class label handler/.code = { % \long so that \ifx\classlabeltextfn\@gobble compares true if this is empty (\@gobble is long...) - \long\def\sseq@classlabeltextfn##1{#1} - \ifx\sseq@classlabeltextfn\@gobble - \def\sseq@classlabeltextfn##1{\def\processedlabel{##1}} + class label handler/.code = { % \long so that \ifx\sseq@classlabel@handler\@gobble compares true if this is empty (\@gobble is long...) + \long\def\sseq@classlabel@handler##1{#1} + \ifx\sseq@classlabel@handler\@gobble + \def\sseq@classlabel@handler##1{\def\result{##1}} + \else + \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabel@handler{}}} + \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabel@handler{blah}}} + \ifx\sseq@tempa\sseq@tempb + \long\def\sseq@classlabel@handler##1{#1{##1}} + \fi + \fi + }, + class name handler/.code = { % \long so that \ifx\sseq@classname@handler\@gobble compares true if this is empty (\@gobble is long...) + \long\def\sseq@classname@handler##1{#1} + \ifx\sseq@classname@handler\@gobble + \def\sseq@classname@handler##1{\def\result{##1}} \else - \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabeltextfn{}}} - \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabeltextfn{blah}}} + \edef\sseq@tempa{\unexpanded\@xp{\sseq@classname@handler{}}} + \edef\sseq@tempb{\unexpanded\@xp{\sseq@classname@handler{blah}}} \ifx\sseq@tempa\sseq@tempb - \long\def\sseq@classlabeltextfn##1{#1{##1}} + \long\def\sseq@classname@handler##1{#1{##1}} \fi \fi } @@ -1762,7 +1816,11 @@ } \def\sseq@globalscaleoption#1{% \sseq@globaldetonefalse - \@xp\gdef\@xp\sseq@globalscaletransform\@xp{\sseq@globalscaletransform#1}% + \@ifundefined{sseq@globalscaletransform}{ + \@xp\gdef\@xp\sseq@globalscaletransform@default\@xp{\sseq@globalscaletransform@default#1}% + }{ + \@xp\gdef\@xp\sseq@globalscaletransform\@xp{\sseq@globalscaletransform#1}% + } } \pgfqkeys{/sseqpages/global}{% x/.sseq @ illegal, @@ -1802,8 +1860,13 @@ \sseq@break \fi \sseq@globalscaleoption{\pgfsetxvec{\pgfpointxy{#1}{0}}} - \pgfmathparse{\sseq@xscale*#1} - \edef\sseq@xscale{\pgfmathresult} + \@ifundefined{sseq@xscale}{ + \pgfmathparse{\sseq@xscale@default*#1} + \edef\sseq@xscale@default{\pgfmathresult} + }{ + \pgfmathparse{\sseq@xscale*#1} + \edef\sseq@xscale{\pgfmathresult} + } \sseq@breakpoint }, xscale/.value required, @@ -1821,8 +1884,13 @@ \sseq@break \fi \sseq@globalscaleoption{\pgfsetyvec{\pgfpointxy{0}{#1}}} - \pgfmathparse{\sseq@yscale*#1} - \edef\sseq@yscale{\pgfmathresult} + \@ifundefined{sseq@yscale}{ + \pgfmathparse{\sseq@yscale@default*#1} + \edef\sseq@yscale@default{\pgfmathresult} + }{ + \pgfmathparse{\sseq@yscale*#1} + \edef\sseq@yscale{\pgfmathresult} + } \sseq@breakpoint }, yscale/.value required, diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqloadstore.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqloadstore.code.tex index c40d0d974c6..066685a57af 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqloadstore.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqloadstore.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: sseqloadstore.code.tex @@ -97,6 +97,8 @@ \def\sseq@obj@xoaddto#1{\sseq@obj@ifundef{#1}{\sseq@obj@xodef{#1}}{\@xp\sseq@g@addto@macro\csname \sseq@obj@fullname{#1}\@xp\endcsname\@xp}} \def\sseq@obj@map#1#2{\def\\##1{#2}\sseq@obj{#1}} +\def\sseq@lettoobj#1#2{\sseq@obj@ifdef{#2}{\@xp\let\@xp#1\csname\sseq@obj@fullname{#2}\endcsname}{\let#1\empty}} + \def\sseq@obj@ifchanged#1#2#3{\sseq@obj@ifundef{#1.changed}{#3}{#2}} \def\sseq@obj@changedtrue#1{\sseq@obj@gdef{#1.changed}{}} @@ -124,10 +126,10 @@ % This simplifies the code a lot because I don't have to check again where I should put things. \sseq@addtostorelist\sseq@savedpaths{} \def\sseq@tempsavedpaths{} -\def\sseq@savedpaths@addclass@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@class@draw@ifpage{#1}}} -\def\sseq@savedpaths@adddifferential@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@differential@draw@ifpage{#1}}} -\def\sseq@savedpaths@addstructline@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@structline@draw@ifpage{#1}}} -\def\sseq@savedpaths@xaddtikzpath@standard#1{\sseq@x@addto@macro\sseq@savedpaths{#1}} +\def\sseq@savedpaths@addclass@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@class@object{#1}}} +\def\sseq@savedpaths@adddifferential@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@differential@object{#1}}} +\def\sseq@savedpaths@addstructline@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@structline@object{#1}}} +\def\sseq@savedpaths@xaddtikzpath@standard#1{\sseq@x@addto@macro\sseq@savedpaths{\@nx\sseq@tikzpath@object{#1}}} \def\sseq@savedpaths@add@standard{\sseq@g@addto@macro\sseq@savedpaths} \def\sseq@savedpaths@xadd@standard{\sseq@x@addto@macro\sseq@savedpaths} \def\sseq@savedpaths@show@standard{\show\sseq@savedpaths} diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqmacromakers.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqmacromakers.code.tex index 3ac70b363b3..ae914721e25 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqmacromakers.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqmacromakers.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: sseqmacromakers.code.tex diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqmain.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqmain.code.tex index d33fcf15c67..d69b28d2041 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqmain.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqmain.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: sseqmain.code.tex @@ -63,6 +63,12 @@ \sseq@installmacros \sseq@installmsghooks \sseq@install@xparse@Uarggrabber + % The behavior of xmax and xmin is very particular, so it's best not to mess with them. + % In particular, they shouldn't be expanded until printing no matter what, but we don't want + % \pgfmathparse to barf on them. \pgfmathparse really doesn't like engine protected macros, + % so in no case should this be engine protected. (Wish we could test an argument for the presence + % of engine protected macros). If we try to do that, \sseq@ifpgfmathexpr will break in + % \sseq@tikzprimitives@coords@notaclass@handle@. \def\xmin{\protect\sseq@xmin}\def\xmax{\protect\sseq@xmax} \def\ymin{\protect\sseq@ymin}\def\ymax{\protect\sseq@ymax} % @@ -96,7 +102,7 @@ \global\let\@xp\@nx\csname pgfk@/sseqpages/global/{\sseq@currentoptionpath} options/.@cmd\endcsname \@xp\@nx\csname pgfk@/sseqpages/global/{\sseq@currentoptionpath} options/.@cmd\endcsname } - \sseq@savedpaths@xadd{\sseq@stylelist} + \sseq@savedpaths@xadd{\@nx\sseq@style@object{\sseq@stylelist}} \sseq@savedpaths@add{\begingroup} % prevent some of the two-pass user macros horrors \let\sseq@error@setup\sseq@error@setup@withinfo } @@ -218,6 +224,10 @@ % \ifx\sseq@xmin\sseq@infinity\sseq@error{no-range}\def\sseq@xmin{0}\def\sseq@xmax{0}\@xp\sseq@break\fi % could be warning \ifx\sseq@ymin\sseq@infinity\sseq@error{no-range}\def\sseq@ymin{0}\def\sseq@ymax{0}\@xp\sseq@break\fi + \let\xmin\sseq@xmin + \let\xmax\sseq@xmax + \let\ymin\sseq@ymin + \let\ymax\sseq@ymax % \ifnum\numexpr\sseq@xmax-\sseq@xmin\relax>\numexpr\maxdimen/\dimexpr1pt\relax-1\relax \sseq@error@xx{range-super-overflow}{x} @@ -266,7 +276,6 @@ \sseq@setlayoutparameters \begin{tikzpicture}[/sseqpages/global/{default} options,\ifsseq@hasname/sseqpages/global/{\sseq@thename} options\fi,/sseqpages/global/{this page} options]% \sseq@sseqstyle@globalpart - %\pgftransformreset \sseq@globaldetonetransform \sseq@globalscaletransform % @@ -315,7 +324,6 @@ \ifsseq@mathnodes \tikzset{execute at begin node=$,execute at end node=$}% \fi - %\let\sseq@error@setup\sseq@error@setup@withinfo % \begingroup \sseq@savedbackgroundpaths @@ -324,10 +332,10 @@ \sseq@useclip % \ifsseq@drawdifferentials\else - \let\sseq@differential@draw@ifpage\@gobble + \let\sseq@differential@object\@gobble \fi \ifsseq@drawstructlines\else - \let\sseq@structline@draw@ifpage\@gobble + \let\sseq@structline@object\@gobble \fi % \sseq@usesavedpaths @@ -351,12 +359,48 @@ \end{sseqpage}% } + +\def\SseqCopyPage#1#2#3{ + \begingroup + \def#1{\begingroup} + \global\let\sseq@copymacro\empty + \def\sseq@thename{#2} + \global\let\sseq@savedpaths@save\sseq@savedpaths + \sseq@storelist@get\sseq@savedpaths + \def\sseq@thepage{#3} + \sseq@thepagecount=#3\relax + \def\sseq@beginscope@object{\sseq@g@addto@macro#1{\sseq@savedpaths@add{\sseq@beginscope@object}}} + \def\sseq@endscope@object{\sseq@g@addto@macro#1{\sseq@savedpaths@add{\sseq@endscope@object}}} + \def\sseq@scope@object##1{\sseq@g@addto@macro#1{\sseq@savedpaths@add{\sseq@scope@object{##1}}}} + \def\sseq@style@object##1{\sseq@g@addto@macro#1{\sseq@savedpaths@add{\sseq@style@object{##1}}}} + \let\sseq@class@drawnode\sseq@copypage@addclass + \let\sseq@differential@object\@gobble + \let\sseq@structline@draw\sseq@copypage@addstructline + \let\sseq@tikzpath@object\@gobble + \let\sseq@pgfkeysdocommand\@gobbletwo + \sseq@savedpaths + \sseq@g@addto@macro#1{\endgroup} + \endgroup + \@xp\let\csname\sseq@macroname#1 code\endcsname\sseq@copymacro + \DeclareSseqGroup #1 {} { \csname\sseq@macroname#1 code\endcsname } + \let\sseq@savedpaths\sseq@savedpaths@save +} + +\def\sseq@copypage@addclass#1{ + \sseq@x@addto@macro\sseq@copymacro{\@nx\sseq@class@copy{\sseq@thename}{#1}} +} + +\def\sseq@copypage@addstructline#1{ + \sseq@x@addto@macro\sseq@copymacro{\@nx\sseq@structline@copy{\sseq@thename}{#1}} +} + + %%% Scope \newcount\sseq@scope@savestackid \def\sseq@scope@secondpasstoks{} \def\sseq@scope{\@ifnextchar[{\sseq@scope@}{\sseq@scope@[]}}%] \def\sseq@scope@[#1]{% - \sseq@scope@savedpaths@add{\begin{scope}}% + \sseq@scope@savedpaths@add{\sseq@beginscope@object}% % This is a funky hack to fix a problem with shifts. On tmfass, if we don't handle shifts specially, we actually put so much stuff into % this \sseq@scope@secondpasstoks macro that we exceed TeX's upper bound for the maximum total macro memory. Or something like that -- I don't understand the error, % but it definitely only depends on how much stuff there is overall and on there being lots of scopes, not on any particular part of the diagram. @@ -364,12 +408,12 @@ \let\sseq@options@scopeshiftsecondpass\sseq@scope@savedpaths@add \sseq@processoptions{scope}{#1}% outputs into \sseq@savedoptioncode \edef\sseq@scope@secondpasstoks{\unexpanded\@xp{\sseq@scope@secondpasstoks}\unexpanded\@xp{\sseq@savedoptioncode}} - \sseq@eval{\@nx\sseq@scope@savedpaths@add{\sseq@scope@toks{\unexpanded\@xp{\sseq@scope@secondpasstoks}}}}% + \sseq@eval{\@nx\sseq@scope@savedpaths@add{\@nx\sseq@scope@object{\sseq@scope@toks{\unexpanded\@xp{\sseq@scope@secondpasstoks}}}}}% %\advance\sseq@scope@savestackid\@ne %\sseq@savestack@name{scope@save\the\sseq@scope@savestackid} } \def\sseq@endscope{% - \sseq@scope@savedpaths@add{\end{scope}} + \sseq@scope@savedpaths@add{\sseq@endscope@object} %\sseq@restorestack@name{scope@save\the\sseq@scope@savestackid } @@ -411,11 +455,11 @@ \sseq@obj@xdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\nodenum}% \fi \ifx\sseq@class@name\pgfutil@empty\else - \sseq@cleanup@obj{class.\classname.name} - \sseq@cleanup@obj{class.namedclass.\sseq@class@name} + \sseq@cleanup@obj{\classname.name} + \sseq@cleanup@obj{class.namedclass.\detokenize\@xp{\sseq@class@name}} \sseq@namehandler - \sseq@obj@xdef{class.\classname.name}{\sseq@class@name} - \sseq@obj@xdef{class.namedclass.\sseq@class@name}{\coordnopar} + \sseq@obj@xdef{\classname.name}{\sseq@class@name} + \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{\coordnopar} \fi \sseq@breakpoint \endgroup @@ -463,7 +507,14 @@ \sseq@breakfi \fi %%%% No more breaks after this point + + \sseq@processlabels % This sets up the label nodes, now that we know the position of the class (I think that's what we needed?) + \sseq@class@main % We segment off the main part of the class so that we can call it separately from the copy method + \sseq@breakpoint + \endgroup +} % +\def\sseq@class@main{ \ifx\sseq@classinsert\empty % by default, just insert to the right of previous classes \edef\sseq@classinsert{\nodenum} @@ -483,7 +534,6 @@ \fi \fi % - \sseq@processlabels % This sets up the label nodes, now that we know the position of the class (I think that's what we needed?) % \sseq@xminmax{\xcoord}{\ycoord}% \sseq@yminmax{\xcoord}{\ycoord}% @@ -500,14 +550,10 @@ \sseq@obj@xdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\nodenum}% \fi \ifx\sseq@class@name\pgfutil@empty\else - \sseq@cleanup@obj{class.\classname.name} - \sseq@cleanup@obj{class.namedclass.\sseq@class@name} - \sseq@namehandler - \sseq@obj@xdef{class.\classname.name}{\sseq@class@name} - \sseq@obj@xdef{class.namedclass.\sseq@class@name}{\coordnopar} - \fi - \ifcsname sseq@class@showname\endcsname - \sseq@eval{\@nx\sseq@handleclassquotes{\sseq@obj{class.\classname.name}}{\sseq@class@showname}} + \sseq@cleanup@obj{\classname.name} + \sseq@cleanup@obj{class.namedclass.\detokenize\@xp{\sseq@class@name}} + \sseq@obj@xdef{\classname.name}{\sseq@class@name} + \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{\coordnopar} \fi \sseq@pushstack@\coord % @@ -530,6 +576,9 @@ \ifx\sseq@classlabelnodes\pgfutil@empty\else \sseq@obj@xodef{\classname.labelnodes}{\sseq@classlabelnodes}% \fi + \ifcsname sseq@class@showname\endcsname + \sseq@obj@xodef{\classname.showname}{\sseq@class@showname} + \fi \ifsseq@needstikz \sseq@obj@xdef{\classname.needstikz}{\sseq@needstikztrue}% \fi @@ -541,11 +590,36 @@ \fi % \sseq@savedpaths@addclass{class.\coord}% - \sseq@breakpoint - \endgroup } \def\sseq@setoffset#1{\sseq@obj@gdef{\classname.offset}{\pgftransformshift{#1}}} +\def\sseq@copy@nameprefix{} + +\def\sseq@class@copy#1#2{ + \begingroup + \let\sseq@thename@saved\sseq@thename + \def\sseq@thename{#1} + \sseq@lettoobj\sseq@familylist{#2.familylist} + \sseq@lettoobj\sseq@savedoptioncode{#2.options} + \sseq@lettoobj\sseq@classnodetext{#2.nodetext} + \sseq@lettoobj\sseq@classnodetextoptions{#2.nodetext.options} + \sseq@lettoobj\sseq@classlabelnodes{#2.labelnodes} + \sseq@obj@ifdef{#2.showname}{\sseq@lettoobj\sseq@class@showname{#2.showname}}{} + \sseq@lettoobj\sseq@class@name{#2.name} + \edef\sseq@class@name{\unexpanded\@xp{\sseq@copy@nameprefix}\unexpanded\@xp{\sseq@class@name}} + \sseq@obj{#2.needstikz} + \sseq@lettoobj\sseq@tooltip{#2.tooltip} + \sseq@class@getparts#2. + \sseq@quieterror{class-tag-already-defined} + \edef\sseq@class@tag{copiedfrom\sseq@thisposnum} + \let\sseq@thename\sseq@thename@saved + \sseq@eval{\@nx\sseq@cparsecoord{\the\sseq@tempx,\the\sseq@tempy}} + \let\sseq@pushstack@\@gobble + \sseq@class@main + \endgroup +} + + % This is for use with "insert" key. Add one to offset index of each class later than the one currently being inserted % Takes the partial coordinate "x,y" in #1, and the position that the new class is being inserted into in \sseq@classinsert. \def\sseq@class@adjustclasses#1{ @@ -643,14 +717,13 @@ \sseq@obj@xdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\sseq@index}% \fi \ifx\sseq@class@name\pgfutil@empty\else - \sseq@obj@ifdef{class.\classname.name}{ - \sseq@error@nn{classoptions-class-already-named}{\coord}{\sseq@obj{class.\classname.name}}%could be warning + \sseq@obj@ifdef{\classname.name}{ + \sseq@error@nn{classoptions-class-already-named}{\coord}{\sseq@obj{\classname.name}}%could be warning }{} - \sseq@cleanup@obj{class.\classname.name} - \sseq@cleanup@obj{class.namedclass.\sseq@class@name} - \sseq@namehandler - \sseq@obj@xdef{class.\classname.name}{\sseq@class@name} - \sseq@obj@xdef{class.namedclass.\sseq@class@name}{\coordnopar} + \sseq@cleanup@obj{\classname.name} + \sseq@cleanup@obj{class.namedclass.\detokenize\@xp{\sseq@class@name}} + \sseq@obj@xdef{\classname.name}{\sseq@class@name} + \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{\coordnopar} \fi \sseq@tempcount=\sseq@gen\relax \advance\sseq@tempcount\m@ne @@ -679,6 +752,9 @@ \sseq@cleanup@obj{\classname.labelnodes} \sseq@classoptions@obj@addto@withpagerange{\classname.labelnodes}{\sseq@classlabelnodes} \fi + \ifcsname sseq@class@showname\endcsname + \sseq@obj@xodef{\classname.showname}{\sseq@class@showname} + \fi \ifx\sseq@familylist\pgfutil@empty\else \sseq@cleanup@obj{\classname.familylist} \sseq@classoptions@obj@addto@withpagerange{\classname.familylist}{\sseq@familylist} @@ -725,10 +801,38 @@ \sseq@smuggle@macro\sseq@gen \egroup } + \sseq@DeclareDocumentCommand\replaceclass{od()}{% \begingroup \sseq@loadinputline \sseq@xsetthiscall{\string\replaceclass\IfNoValueF{#1}{[\unexpanded{#1}]}\unexpanded{(#2)}} +% + \IfNoValueTF{#2}{ + \def\sseq@coord{\lastclass0} + }{ + \def\sseq@coord{#2} + } + \sseq@parsecoord\coord{\sseq@coord}{coordinate passed to \string\replaceclass}% + \sseq@replaceclassmain{#1} +} + +\sseq@DeclareDocumentCommand\replacesource{o}{ + \begingroup + \sseq@loadinputline + \sseq@xsetthiscall{\string\replacesource\IfNoValueF{#1}{[\unexpanded{#1}]}} + \sseq@parsedcoord@restore{\coord}{lastsource} + \sseq@replaceclassmain{#1} +} + +\sseq@DeclareDocumentCommand\replacetarget{o}{ + \begingroup + \sseq@loadinputline + \sseq@xsetthiscall{\string\replacetarget\IfNoValueF{#1}{[\unexpanded{#1}]}} + \sseq@parsedcoord@restore{\coord}{lasttarget} + \sseq@replaceclassmain{#1} +} + +\def\sseq@replaceclassmain#1{ \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@classstyle @@ -737,24 +841,23 @@ \IfNoValueF{#1}{% \sseq@processoptions{class}{#1}% Outputs result into \sseq@savedoptioncode }% -% - \IfNoValueTF{#2}{ - \def\sseq@coord{\lastclass0} - }{ - \def\sseq@coord{#2} - } - \sseq@parsecoord\coord{\sseq@coord}{\string\classoptions}% \sseq@processlabels -% \sseq@obj@ifundef{class.\coord.num}{\sseq@error@x{replaceclass-no-class}{\coordname}\sseq@break}{} \sseq@ifdead\coord{}{\sseq@error@x{replaceclass-not-dead-yet}{\coordname}\sseq@break} +% + \edef\oldclassname{class.\coord[\sseq@obj{class.\coord.num}]} + \sseq@cleanup@obj{class.\coord.num} + \sseq@obj@inc{class.\coord.num} + \edef\classname{class.\coord[\sseq@obj{class.\coord.num}]} +% \ifsseq@keepchanges\else - \ifnum\the\numexpr\sseq@obj{class.\coord[\sseq@obj{class.\coord.num}].page}<\sseq@thepagecount\else - \edef\sseq@temp{\sseq@obj{class.\coord[\sseq@obj{class.\coord.num}].page}} + \ifnum\the\numexpr\sseq@obj{\oldclassname.page}<\sseq@thepagecount\else + \edef\sseq@temp{\sseq@obj{\oldclassname.page}} \sseq@error@xxx{replaceclass-no-effect-on-this-page}{\coord}{\sseq@temp}{\the\numexpr\sseq@temp+\@ne}% warning \sseq@breakfifi \fi \fi +% \let\partialcoord\coord@partial \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{% @@ -763,18 +866,20 @@ \sseq@cleanup@obj{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}% \sseq@obj@xdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\nodenum}% \fi - \ifx\sseq@class@name\pgfutil@empty\else - \sseq@cleanup@obj{class.\classname.name} - \sseq@cleanup@obj{class.namedclass.\sseq@class@name} - \sseq@namehandler - \sseq@obj@xdef{class.\classname.name}{\sseq@class@name} - \sseq@obj@xdef{class.namedclass.\sseq@class@name}{\coordnopar} - \fi - \ifcsname sseq@class@showname\endcsname - \sseq@eval{\@nx\sseq@handleclassquotes{\sseq@obj{class.\classname.name}}{\sseq@class@showname}} + \ifx\sseq@class@name\pgfutil@empty + \sseq@obj@ifdef{\oldclassname.name}{ + \sseq@lettoobj\sseq@class@name{\oldclassname.name} + \sseq@cleanup@obj{\classname.name} + \sseq@cleanup@obj{class.namedclass.\detokenize\@xp{\sseq@class@name}} + \sseq@obj@xdef{\classname.name}{\sseq@class@name} + \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{\coordnopar} + }{} + \else + \sseq@cleanup@obj{\classname.name} + \sseq@cleanup@obj{class.namedclass.\detokenize\@xp{\sseq@class@name}} + \sseq@obj@xdef{\classname.name}{\sseq@class@name} + \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{\coordnopar} \fi - \sseq@cleanup@obj{class.\coord.num} - \sseq@obj@inc{class.\coord.num} \let\partialcoord\coord@partial \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partialcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{% @@ -782,8 +887,10 @@ }{}% \sseq@obj@xdef{partialcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\nodenum}% \fi - \edef\classname{class.\coord[\sseq@obj{class.\coord.num}]} % + \ifcsname sseq@class@showname\endcsname + \sseq@obj@xodef{\classname.showname}{\sseq@class@showname} + \fi \sseq@obj@xodef{\classname.familylist}{\sseq@familylist} \sseq@obj@xdef{\classname.page}{\sseq@infinity} \sseq@obj@xodef{\classname.options}{\sseq@savedoptioncode} @@ -794,6 +901,9 @@ \sseq@obj@xodef{\classname.nodetext.options}{\sseq@classnodetextoptions} \fi \sseq@obj@xodef{\classname.labelnodes}{\sseq@classlabelnodes} + \ifcsname sseq@class@showname\endcsname + \sseq@obj@xodef{\classname.showname}{\sseq@class@showname} + \fi \sseq@obj@gdef{\classname.dependencies}{} \ifsseq@needstikz \sseq@obj@xdef{\classname.needstikz}{\sseq@needstikztrue} @@ -819,6 +929,7 @@ \fi \egroup } + % #1 -- class % #2 -- page % If there is a class #1 drawn on page #2, set \sseq@gen to be the generation of that class, otherwise set \sseq@gen to be -1. @@ -856,6 +967,8 @@ \sseq@DeclareDocumentCommandAs\sseq@kill@\kill {d()} { \sseq@xsetthiscall{\string\kill\unexpanded\@xp{\sseq@dpage}\IfNoValueF{#1}{(#1)}}% \sseq@parsecoord\coordinate{\IfNoValueTF{#1}{\lastclass}{#1}}{}% + \sseq@parsedcoord@save{lastsource}{\coordinate} + \sseq@parsedcoord@save{lasttarget}{\coordinate} \sseq@ifintexpr{\sseq@dpage}{% \sseq@tempcount=\numexpr\sseq@dpage\relax % this is a convenient way to get rid of spaces because #3 has to be a number }{% @@ -934,6 +1047,8 @@ \def\sseq@d@d#1#2{%% \sseq@d@setpageminrec{class.\source}{#2}{source}% automatically handles \sseq@cleanup@obj \sseq@d@setpageminrec{class.\target}{#2}{target} + %%% This is the last point we might break, so now the differential is good. + %%% Note that we can break inside \sseq@d@setpageclass inside \sseq@d@setpageminrec % \ifsseq@drawdifferential % TODO: probably should get rid of invisible now that we have \kill... \sseq@obj@xodef{d.#2\source\target.familylist}{\sseq@familylist} @@ -1017,7 +1132,7 @@ \fi \fi \sseq@obj@xdef{\sseq@classgenname.page}{#2} - \sseq@obj@xdef{\sseq@classgenname.deathinfo}{#3 of differential \sseq@thiscall\space on page #2} + \sseq@obj@xdef{\sseq@classgenname.deathinfo}{#3 of differential \sseq@thiscall\ on page #2} \bgroup \def\foreach{\@nx\@nx\@nx\foreach} \protected\def\\{} @@ -1033,7 +1148,7 @@ \ifx\sseq@restofstacktrace\pgfutil@empty\else\sseq@tempiftrue\fi \sseq@obj@xdef{\sseq@classgenname.deathstacktrace}{% \ifsseq@tempif - \unexpanded{\\\\}Stack trace for differential \sseq@thiscall\ that killed #3:\unexpanded{\\}% + \unexpanded{\\\\}Stack trace for differential \@nx\unexpanded{\sseq@thiscall} that killed #3:\unexpanded{\\}% \ifx\sseq@temp\sseq@empty\else\unexpanded{\ \ \ }\@nx\sseq@stack@unexpanded{\unexpanded\@xp{\the\sseq@foreachcall}}\fi \unexpanded\@xp{\sseq@restofstacktrace}% \fi @@ -1056,8 +1171,10 @@ \def\sseq@d@setpagemin#1#2{ \ifnum\sseq@obj{#1.page}>#2\relax - \sseq@cleanup@obj{#1.page} - \sseq@obj@xdef{#1.page}{#2} + \ifnum\sseq@obj{#1.pagemin}>#2\relax\else % prevent a d1 from getting rid of a structline that was supposed to start on page 5 + \sseq@cleanup@obj{#1.page} + \sseq@obj@xdef{#1.page}{#2} + \fi \fi } \def\sseq@differential@draw@ifpage#1{ @@ -1262,6 +1379,27 @@ \sseq@obj@xoaddto{\sseq@structlinename.familylist}{\sseq@familylist} \ifnum\sseq@tempcount<\sseq@genmax\repeat } + +\def\sseq@structline@copy#1#2{ + \begingroup + \sseq@structline@copy@decomposename#2 + \let\sseq@thename@saved\sseq@thename + \def\sseq@pagemin{0} + \sseq@parsecoord\source{\sourcename}{source of structure line}% + \sseq@parsecoord\target{\targetname}{target of structure line} + \def\sseq@thename{#1} + \sseq@lettoobj\sseq@familylist{#2.familylist} + \sseq@lettoobj\sseq@savedoptioncode{#2.options} + \let\sseq@thename\sseq@thename@saved + \sseq@structline@structline + \endgroup +} + +\def\sseq@structline@copy@decomposename#1.(#2,#3,#4)(#5,#6,#7){ + \def\sourcename{#2,#3,copiedfrom#4} + \def\targetname{#5,#6,copiedfrom#7} +} + \def\sseq@structline@getgen#1{ \bgroup \sseq@tempcount=\sseq@obj{structline.\source\target.num}\relax @@ -1366,7 +1504,7 @@ \sseq@obj@xodef{\circleclassobjname.tikzprimoptions}{\sseq@keysfortikzprim} \sseq@obj@xdef{\circleclassobjname.fitnodes}{\@nx\tikz@lib@fit{(sseq{\coordanopar})(sseq{\coordbnopar})\sseq@fitalso}} %\edef\temp{\@nx\sseq@circleclass@draw{\coorda@internalname}{\coordb@internalname}{\unexpanded\@xp{\sseq@savedoptioncode}}} - \sseq@savedpaths@xadd{\@nx\sseq@circleclass@draw@ifpage{\circleclassobjname}{\coordanopar}{\coordbnopar}} + \sseq@savedpaths@xadd{\@nx\sseq@circleclass@object{\circleclassobjname}{\coordanopar}{\coordbnopar}} \sseq@obj@xdef{\circleclassobjname.page}{\sseq@pagemax} \sseq@obj@xdef{\circleclassobjname.pagemin}{\sseq@pagemin} \@ifundefined{sseq@fit@pagemax}{ @@ -1425,13 +1563,13 @@ \the\sseq@scope@toks \sseq@options@normalmode \sseq@processoptions{class/label}{#2}% - \sseq@classlabeltextfn{#1}% labeltextfn is a private handler, classlabeltextfn is exposed via "class label handler" + \sseq@classlabel@handler{#1}% labeltextfn is a private handler for transformations, sseq@classlabel@handler is exposed via "class label handler" \ifsseq@classlabel \sseq@options@firstpassmode \the\sseq@outerclasslabelstyle \sseq@x@addto@macro\sseq@classlabelnodes{% \@nx\sseq@drawlabel{% - \sseq@maybemathswitch\unexpanded\@xp{\processedlabel}\sseq@maybemathswitch}% + \sseq@maybemathswitch\unexpanded\@xp{\result}\sseq@maybemathswitch}% {% This is setup to prevent a bug where \classoptions and class label style don't work correctly together \the\sseq@sseqstyle\@nx\the\sseq@sseqstyle@page \the\sseq@labelstyle\@nx\the\sseq@labelstyle@page @@ -1449,7 +1587,7 @@ \the\sseq@innerclasslabelstyle \sseq@options@normalmode \sseq@protectedeval{\@nx\pgfqkeys{/sseqpages/class/label}{#2}}% - \sseq@protected@xdef\sseq@classnodetext{\sseq@maybemathswitch\processedlabel\sseq@maybemathswitch}% + \sseq@protected@xdef\sseq@classnodetext{\sseq@maybemathswitch\result\sseq@maybemathswitch}% \xdef\sseq@classnodetextoptions{% %\unexpanded{\def\pgfkeysdefaultpath{/sseqpages/class/node texts/}}% \sseq@thelabelstyle\sseq@theclasslabelstyle\sseq@theinnerclasslabelstyle diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqmessages.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqmessages.code.tex index 8bde90b1c24..bfa11df4e4b 100644 --- a/Master/texmf-dist/tex/latex/spectralsequences/sseqmessages.code.tex +++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqmessages.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: sseqmessages.code.tex @@ -260,7 +260,9 @@ \ExplSyntaxOn \char_set_catcode_space:N\ % Needed to make pretocmd work -- there are always spaces after every command, and they need to be retokenized as spaces -\def\sseqerrortowarning#1{ \msg_redirect_name:nnn { spectralsequences } { #1 } { warning } } +\def\SseqErrorToWarning#1{\msg_redirect_name:nnn{spectralsequences}{#1}{warning}} +\let\sseqerrortowarning\SseqErrorToWarning +\def\sseq@quieterror#1{\msg_redirect_name:nnn{spectralsequences}{#1}{none}} \def\sseq@error {\msg_error:nn {spectralsequences}} \def\sseq@error@n {\msg_error:nnn {spectralsequences}} @@ -416,6 +418,13 @@ \sseq@newerror{anchor-ignored} {The coordinate #1 is not a class, but it has an anchor '#3'. Ignoring the anchor and treating it as the literal position #2.} \sseq@newerror{invalid-tikz-coord}{The coordinate #1 does not refer to a tikz class but its #2 coordinate is not valid \string\pgfmathparse\ input.} +% handlers +\sseq@newerror{NormalizeMonomial-invalid-exponent}{The exponent #1 of the variable #2 in the monomial #3 is not a valid integer expression. Giving up on processing this monomial -- I will leave it alone and hope for the best.} +\sseq@newerror{AHSSNameHandler-missing-cell}{The name #1 has no cell (an integer expression surrounded by brackets). Giving up on processing it and returning my input in \string\result.} +\sseq@newerror{AHSSNameHandler-invalid-integer}{The cell degree #1 of #2 is not a valid integer expression. I am leaving it alone, but I processed the monomial.} + + + %% %% %% foreach @@ -491,10 +500,14 @@ \sseq@newerror{unknown-grid}{Undefined grid style '#1'.} \sseq@newerror{unknown-class-pattern}{Unknown class pattern '\sseq@classpattern'.} \sseq@newerror{class-placement-shift}{Shifts are illegal in the transformations applied in "class placement" key. If you want to shift your nodes, use \string\sseqnewclasspattern.} % #1 <- x shift, #2 <- shift amount -\sseq@newerror{do-command-failed}{\string\sseq@pgfkeysdocommand{#1}{#2} failed.} +\sseq@newerror@internal{do-command-failed}{\string\sseq@pgfkeysdocommand{#1}{#2} failed.} \sseq@newerror{standard-parse}{You cannot use \string#1 inside a scope that has either the background key or coordinate transformations other than integer shifts.} +\sseq@newerror{no-tooltip}{You cannot use the 'tooltip' option without either using the 'tooltips' package option or giving your own definition for '\string\sseqtooltip'. + Tooltips aren't enabled by default because they use the 'pdfcomment' package which creates two extra auxiliary files.% +} + %% %% %% main @@ -559,4 +572,7 @@ \sseq@newerror{structline-source-target-equal}{The source and target of a \@nx\structline cannot be equal.} +\protected\def\sseq@quiet{\msg_redirect_module:nnn{spectralsequences}{error}{info}} +\protected\def\sseq@endquiet{} + \ExplSyntaxOff 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 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 -- cgit v1.2.3