%% %% Package: spectralsequences v1.3.3 2023-01-28 %% Author: Hood Chatham %% Email: hood@mit.edu %% Date: 2023-01-28 %% License: Latex Project Public License %% %% File: sseqmain.code.tex %% %% Defines the main environments and commands %% %%%%%%% %%% %%% Environment definitions %%% %%%%%%% \def\sseq@usesavedpaths{% \sseq@savedpaths \sseq@clearchangestyles \sseq@tempsavedpaths \gdef\sseq@tempsavedpaths{}% } \sseq@addtostorelist\sseq@savedbackgroundpaths{} \sseq@addtostorelist\sseq@restorestyles{} \def\sseq@page{\protect\sseq@thepage} \def\sseqdata{\@ifnextchar[{\sseqdata@}{\sseqdata@[]}}%} \def\sseqdata@[#1]{% \edef\sseq@restorefont{\font@name}% \selectfont\nullfont % Avoid space hazards! \def\par{}% % \ifx\pgfpictureid\@undefined\else %Uh-oh, we're inside tikz. \sseq@error@n{env-inside-tikz}{sseqdata}\@xp\sseq@breakdataenv \fi \ifsseq@inprogress % Uh-oh, we're already in a sseq environment. \sseq@error@n{env-inside-sseq}{sseqdata}\@xp\sseq@breakdataenv \fi \sseq@inprogresstrue \def\sseq@sseqsetdirectory{/sseqpages} \sseq@keepchangestrue \sseq@storelist@setdefaults \let\sseq@xtickfn\@firstofone\let\sseq@ytickfn\@firstofone % These are default functions, which addtostorelist can't handle. % \ifx\sseq@xmin@default\sseq@infinity \let\sseq@xminmax\sseq@xminmax@active \fi \ifx\sseq@ymin@default\sseq@infinity \let\sseq@yminmax\sseq@yminmax@active \fi \ifsseq@mathnodes \let\sseq@maybemathswitch=$\@gobble$ \fi % % copy commands into the user namespace. \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} % \sseq@modtikzcommands % Defer evaluation of tikz primitives \sseq@patchfor % patch \foreach to work with deferred macros \pgfkeys{/handlers/first char syntax/the character "/.initial=\sseq@handlequote} % install quotes parsing % % \pgfqkeys{/sseqpages/global/name only}{#1} \@ifundefined{sseq@thename}{\sseq@error{env-data-no-name}\sseq@breakdataenv}{} \sseq@obj@ifundef{exists}{ \sseq@obj@gdef{exists}{} \pgfqkeys{/sseqpages/global}{{\sseq@thename} options/.code={}} }{ \ifsseq@updateexisting\else \sseq@error@x{env-data-already-exist}{\sseq@thename}% this could be a warning \fi \sseq@restorestyles \sseq@getcmds } \sseq@setsavedpaths{standard} % % the default option handler for /sseqpages/global adds to \sseq@currentoptionpath options \let\sseq@currentoptionpath\sseq@thename \pgfqkeys{/sseqpages/global}{#1} \ifx\sseq@targetx\pgfutil@empty\else \sseq@hasdegreetrue \fi \sseq@eval{ \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{\@nx\sseq@style@object{\sseq@stylelist}} \sseq@savedpaths@add{\begingroup\sseq@startcontentmarker} % prevent some of the two-pass user macros horrors \let\sseq@error@setup\sseq@error@setup@withinfo } \let\sseq@startcontentmarker\relax % Just store all the settings \def\endsseqdata{% \let\sseq@error@setup\sseq@error@setup@noinfo \sseq@checkend{sseqdata}% \sseq@savedpaths@add{\endgroup} % prevent some of the two-pass user macros horrors \xdef\sseq@restorestyles{\sseq@stylelist}% \sseq@storecmds \ignorespacesafterend \sseq@breakpoint } \def\sseqpage{\@ifnextchar[{\sseqpage@}{\sseqpage@[]}} %] \def\sseqpage@[#1]{% \edef\sseq@restorefont{\font@name}% \selectfont\nullfont % Avoid space hazards! \def\par{}% % \ifx\pgfpictureid\@undefined\else %Uh-oh, we're inside tikz. \sseq@error@n{env-inside-tikz}{sseqpage}\@xp\sseq@breakpageenv \fi \ifsseq@inprogress % Uh-oh, we're already in a sseq environment. This is not good. \sseq@error@n{env-inside-sseq}{sseqpage}\@xp\sseq@breakpageenv \fi \sseq@inprogresstrue \sseq@ispageenvtrue \def\sseq@sseqsetdirectory{/sseqpages} % % \ifsseq@mathnodes % \let\sseq@maybemathswitch=$\@gobble$ % \fi % % Copy commands into user namespace \sseq@installmacros \sseq@installmsghooks \sseq@install@xparse@Uarggrabber \def\xmin{\protect\sseq@xmin}\def\xmax{\protect\sseq@xmax} \def\ymin{\protect\sseq@ymin}\def\ymax{\protect\sseq@ymax} \sseq@modtikzcommands % Redefine tikz primitives to store themselves in the appropriate place \sseq@patchfor % Change foreach to record it's variable values in the appropriate places \pgfkeys{/handlers/first char syntax/the character "/.initial=\sseq@handlequote}% install quotes parsing % \gdef\sseq@pagecleanup{}% For undoing local option settings % \def\sseq@thepage{0}% page defaults to 0 \def\thepage{\sseq@printpageas} \def\page{\sseq@printnum@inftytosymbol{\sseq@thepage}} \sseq@thepagecount=\z@ \pgfqkeys{/sseqpages/global/name only}{#1}% Get the name \sseq@tempiftrue \ifsseq@hasname \sseq@obj@ifundef{exists}{ \sseq@error@x{env-page-not-exist}{\sseq@thename} % This could be a warning \sseq@obj@gdef{exists}{} \let\sseq@currentoptionpath\sseq@thename \pgfqkeys{/sseqpages/global}{{\sseq@thename} options/.code={}} \sseq@keepchangestrue \sseq@keepglobaloptionstrue \sseq@setsavedpaths{standard} }{ \sseq@restorestyles \sseq@getcmds \ifsseq@keepchanges \sseq@setsavedpaths{standard} \else \sseq@setsavedpaths{temporary} \fi \sseq@tempiffalse \def\sseq@currentoptionpath{this page} \pgfqkeys{/sseqpages/global}{{this page} options/.code={},#1} } \else \edef\sseq@thename{temp@sseq@number@\the\sseq@anonsseqcount} \global\advance\sseq@anonsseqcount1 \sseq@setsavedpaths{temporary} \fi \ifsseq@tempif % Either the spectral sequence has no name, or it has a name but no such existed. \sseq@storelist@setdefaults \sseq@savedpaths@xadd{\sseq@stylelist} \let\sseq@currentoptionpath\sseq@thename \pgfqkeys{/sseqpages/global}{{\sseq@thename} options/.code={},{this page} options/.code={},#1} \sseq@eval{ \global\let\@xp\@nx\csname pgfk@/sseqpages/global/{\sseq@currentoptionpath} options/.@cmd\endcsname \@xp\@nx\csname pgfk@/sseqpages/global/{\sseq@currentoptionpath} options/.@cmd\endcsname } \fi % \ifsseq@specifiedxrange \let\sseq@xminmax\@gobbletwo \else \let\sseq@xminmax\sseq@xminmax@active \fi \ifsseq@specifiedyrange \let\sseq@yminmax\@gobbletwo \else \let\sseq@yminmax\sseq@yminmax@active \fi % \sseq@savedpaths@xadd{\sseq@stylelist} \sseq@savedpaths@add{\begingroup} % prevent some of the two-pass user macros horrors \ifx\sseq@targetx\pgfutil@empty\else \sseq@hasdegreetrue \fi \let\sseq@error@setup\sseq@error@setup@withinfo } % Here we do all of the work to actually print the page \def\endsseqpage{ \let\sseq@error@setup\sseq@error@setup@noinfo \sseq@checkend{sseqpage} \sseq@savedpaths@add{\endgroup} % prevent some of the two-pass user macros horrors % \sseq@xscalecm=\sseq@xscale cm \sseq@yscalecm=\sseq@yscale cm % % check that range is okay % \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} {from \sseq@xmin\space to \sseq@xmax\space (xmax - xmin = \the\numexpr\sseq@xmax-\sseq@xmin)} \@xp\sseq@break \fi \ifnum\numexpr\sseq@ymax-\sseq@ymin\relax>\numexpr\maxdimen/\dimexpr1pt\relax-1\relax \sseq@error@xx{range-super-overflow}{y} {from \sseq@ymin\space to \sseq@ymax\space (ymax - ymin = \the\numexpr\sseq@ymax-\sseq@ymin)} \@xp\sseq@break \fi % \sseq@setlayoutparameters \ifsseq@rangecheck % Calculate available space % We might need to know the dimensions of the tick marks in order to calculate "margin" size. \bgroup \@xp\tikzset\@xp{\sseq@xtickstyle} \pgfmathparse{height("\sseq@xmin") + depth("\sseq@xmin")} \edef\sseq@xlabelheight{\pgfmathresult pt} \sseq@smuggle@macro\sseq@xlabelheight \egroup \bgroup \@xp\tikzset\@xp{\sseq@ytickstyle} \pgfmathparse{max(width("\sseq@ymax"), width("\sseq@ymin"))} \edef\sseq@maxylabelwidth{\pgfmathresult pt} \sseq@smuggle@macro\sseq@maxylabelwidth \egroup % "totaldirmargin" isn't really quite margin: it's the distance between % the bounding box (xmin, ymin) -- (xmax, ymax) and the bounding box of % the resulting figure. % % By subtracting the "margin" distance from the page width / height, we % get the amount of space available for the content. \sseq@tempxdimen = \dimexpr \linewidth - \sseq@totalhorizontalmargin@yborder - 0.1pt \sseq@tempydimen = \dimexpr \textheight - \sseq@totalverticalmargin@xborder - 0.1pt % \ifsseq@insidewaysenv % Swap availability measurements \sseq@tempdimen=\sseq@tempxdimen \sseq@tempxdimen=\sseq@tempydimen \sseq@tempydimen=\sseq@tempdimen \fi % % \showthe\dimexpr\dimexpr \sseq@tempxdimen - \sseq@xscale cm * (\sseq@xmax-\sseq@xmin)\relax % Compare space available to range * scale. \ifdim \sseq@tempxdimen < \dimexpr \sseq@xscale cm * (\sseq@xmax-\sseq@xmin)\relax % this will divide by zero if somehow we overflow the space on page % while the range is 0. Hopefully no one will ever manage that. \pgfmathparse{\sseq@tempxdimen/1cm/(\sseq@xmax-\sseq@xmin)} % max x range \sseq@tempx = \numexpr \sseq@tempxdimen /\sseq@xscalecm \relax % max xscale \sseq@error@xxxx{range-overflow}{x} {from \sseq@xmin\space to \sseq@xmax\space (xmax - xmin = \the\numexpr\sseq@xmax-\sseq@xmin)} {\the\sseq@tempx}% max x range {\pgfmathresult}% max xscale %\@xp\sseq@break \fi % \relax % Not sure why we need this... % % \showthe\dimexpr\dimexpr \sseq@tempydimen - \sseq@yscale cm * (\sseq@ymax-\sseq@ymin)\relax \ifdim \sseq@tempydimen < \dimexpr \sseq@yscale cm * (\sseq@ymax-\sseq@ymin)\relax \sseq@tempy = \numexpr \sseq@tempydimen /\sseq@yscalecm \relax % max y range \pgfmathparse{\sseq@tempydimen/1cm/(\sseq@ymax-\sseq@ymin)} % max yscale \sseq@error@xxxx{range-overflow}{y} {from \sseq@ymin\space to \sseq@ymax\space (ymax - ymin = \the\numexpr\sseq@ymax-\sseq@ymin)} {\the\sseq@tempy}% max y range {\pgfmathresult} % max yscale %\@xp\sseq@break \fi \fi % % Really this could be anything between -\sseq@xmin and -\sseq@xmax and it wouldn't matter. We'll split the difference. \sseq@xoffset=\numexpr\sseq@intdivceiling{\numexpr-\sseq@xmin-\sseq@xmax\relax}{\numexpr4*\sseq@xgridstep\relax}*(2*\sseq@xgridstep)\relax \sseq@yoffset=\numexpr\sseq@intdivceiling{\numexpr-\sseq@ymin-\sseq@ymax\relax}{\numexpr4*\sseq@ygridstep\relax}*(2*\sseq@ygridstep)\relax % % \def\sseq@temp{\sseq@novalue} \ifx\sseq@printpageas\sseq@temp \def\sseq@printpageas{Page $2$ (all differentials)}% \fi % % \tikzset{ z=0pt, every path/.style={}, every node/.style={} } \let\errmessage\sseq@errmessage@std \begin{tikzpicture}[/sseqpages/global/{default} options,\ifsseq@hasname/sseqpages/global/{\sseq@thename} options\fi,/sseqpages/global/{this page} options]% \sseq@sseqstyle@globalpart \sseq@globaldetonetransform \sseq@globalscaletransform % \let\sseq@transform\sseq@error@illegaltransform % Disallow most coordinate transforms \let\sseq@shifttransform\sseq@checkshifttransform % Allow shifts as long as they are by integers and have no units. % \sseq@setupclip % \sseq@patchtikzcoords % \pgfonlayer{background}% % Axes labels only occur once per page, so the cost of typesetting them with tikz doesn't matter ... THANK GOD \ifx\sseq@title\pgfutil@empty\else \ifsseq@drawtitle \sseq@eval{\@nx\node[ /sseqpages/global/every title, above=\sseq@topclippadding+5pt ] {\unexpanded\expandafter{\sseq@title}}; } \fi \fi % Don't touch the shifts -- they are very persnickety. \ifx\sseq@xaxislabel\pgfutil@empty\else\ifsseq@drawxaxislabel \sseq@eval{\noexpand\node[ align=center, /sseqpages/global/every x axis label, below, shift={\sseq@xlabelposition}, ] {\unexpanded\expandafter{\sseq@xaxislabel}};} \fi\fi \ifx\sseq@yaxislabel\pgfutil@empty\else\ifsseq@drawyaxislabel \sseq@eval{\noexpand\node[ align=center, /sseqpages/global/every y axis label, above, rotate=90, shift={\sseq@ylabelposition}, ] {\unexpanded\expandafter{\sseq@yaxislabel}};} \fi\fi % \sseq@grid \sseq@handlexaxis % Draw the axis with pgf primitives. These are defined in sseqdrawing.code.tex \sseq@handleyaxis \endpgfonlayer % \ifsseq@mathnodes \tikzset{execute at begin node=$,execute at end node=$}% \fi % \begingroup \sseq@savedbackgroundpaths \endgroup % \sseq@useclip % \ifsseq@drawdifferentials\else \let\sseq@differential@object\@gobble \fi \ifsseq@drawstructlines\else \let\sseq@structline@object\@gobble \fi % \sseq@usesavedpaths % \ifsseq@keepchanges \xdef\sseq@restorestyles{\sseq@stylelist} \fi \end{tikzpicture}% \ifsseq@keepchanges \sseq@storecmds % store changes \else \sseq@pagecleanup % undo any changes specific to this page \fi \sseq@breakpoint \ignorespacesafterend } % Shorthand for sseqpage with empty body \def\printpage[#1]{% \begin{sseqpage}[#1]% \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@extension@draw\sseq@copypage@addextension \let\sseq@tikzpath@object\@gobble \let\sseq@pgfkeysdocommand\@gobbletwo \sseq@savedpaths \sseq@g@addto@macro#1{\endgroup} \endgroup \@xp\let\csname\sseq@macroname#1 copiedcode\endcsname\sseq@copymacro \DeclareSseqGroup #1 {} { \csname\sseq@macroname#1 copiedcode\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}} } \def\sseq@copypage@addextension#1{ \sseq@x@addto@macro\sseq@copymacro{\@nx\sseq@extension@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{\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. % Anyways, to avoid this excessive storage demand, we don't put the shifts into the scope toks and apply them tons of times, we just do them once. \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{\@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{\sseq@endscope@object} %\sseq@restorestack@name{scope@save\the\sseq@scope@savestackid } \protected\def\sseq@xcoord{}\protected\def\sseq@ycoord{} %%% "Quick" commands for "compiled" code. \def\sseq@qclass(#1,#2){ \sseq@obj@inccheckdef{partcoord.(#1,#2).numnodes} \edef\tempn{\sseq@obj{partcoord.(#1,#2).numnodes}} \edef\classname{class.(#1,#2,\tempn)} \sseq@obj@xdef{\classname.n}{\tempn} \sseq@obj@xdef{\classname.num}{0} \sseq@obj@xdef{\classname[0].page}{\sseq@infinity} \sseq@savedpaths@addclass{class.(#1,#2,\tempn)} } \def\sseq@qclassnamed(#1,#2)#3{ \sseq@qclass(#1,#2) \def\sseq@class@name{#3} \sseq@obj@xdef{\classname[0].name}{\sseq@class@name} \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{#1,#2,\tempn} } \def\sseq@qdnamed#1(#2)(#3){\sseq@eval{\@nx\sseq@qd#1(\sseq@obj{class.namedclass.\detokenize{#2}})(\sseq@obj{class.namedclass.\detokenize{#3}})}} \def\sseq@qd#1(#2,#3,#4)(#5,#6,#7){ \bgroup \def\sseq@dname{d.#1(#2,#3,#4)(#5,#6,#7)} \def\source{(#2,#3,#4)} \def\target{(#5,#6,#7)} \sseq@obj@gdef{\sseq@dname.page}{#1} \sseq@obj@gdef{\sseq@dname.source}{(#2,#3,#4)} \sseq@obj@gdef{\sseq@dname.target}{(#5,#6,#7)} \sseq@d@setpageminrec{class.\source}{#1}{source}% automatically handles \sseq@cleanup@obj \sseq@d@setpageminrec{class.\target}{#1}{target} \sseq@savedpaths@adddifferential{\sseq@dname} \egroup } \def\sseq@qstructlinenamed(#1)(#2){\sseq@eval{\@nx\sseq@qstructline(\sseq@obj{class.namedclass.\detokenize{#1}})(\sseq@obj{class.namedclass.\detokenize{#2}})}} \def\sseq@qstructline(#1,#2,#3)(#4,#5,#6){ \def\source{(#1,#2,#3)} \def\target{(#4,#5,#6)} \sseq@obj@xdef{structline.\source\target.num}{0} \def\sseq@pagemin{0} \edef\sseq@structlinename{structline.\source\target[\sseq@obj{structline.\source\target.num}]} \sseq@cleanup@obj{\sseq@structlinename.page} \sseq@obj@xdef{\sseq@structlinename.page}{\sseq@infinity} \sseq@obj@xdef{\sseq@structlinename.pagemin}{\sseq@pagemin} \sseq@obj@xdef{\sseq@structlinename.source}{\source} \sseq@obj@xdef{\sseq@structlinename.target}{\target} \sseq@class@adddependence{class.\source}{\sseq@structlinename}% If the source or target is already dead, this will set structlinename.page \sseq@class@adddependence{class.\target}{\sseq@structlinename} \sseq@savedpaths@addstructline{structline.\source\target} %\sseq@cleanup@obj{\sseq@structlinename.options} %\sseq@obj@xdef{\sseq@structlinename.options}{\ifsseq@needstikz\@nx\sseq@needstikztrue\fi\unexpanded\@xp{\sseq@savedoptioncode}} } %%%%% %% %% The main commands %% %%%%% %%% \class, \classoptions, \replaceclass \sseq@DeclareDocumentCommand\class{or()}{% \begingroup \sseq@loadinputline \IfNoValueT{#2}{\sseq@break} \sseq@xsetthiscall{\string\class\IfNoValueF{#1}{[\unexpanded{#1}]}\unexpanded{(#2)}}% \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@classstyle \the\sseq@scope@toks \sseq@options@normalmode \IfNoValueF{#1}{% \sseq@processoptions{class}{#1}% Outputs result into \sseq@savedoptioncode }% % \@ifundefined{sseq@class@page}{}{\sseq@error@xxx{cmdoptions-only}{page} {\string\class}{\string\classoptions}}% could be warnings \@ifundefined{sseq@gen} {}{\sseq@error@xxx{cmdoptions-only}{generation}{\string\class}{\string\classoptions}} % \sseq@cparsecoord{#2}{}% \ifnum\csname sseq@\sseq@classpattern @maxclasses\endcsname<\nodenum\relax \sseq@error@xxxx{classpattern-too-many-classes}{(\partialcoord)}{\nodenum}{\sseq@classpattern}{\@xp\the\csname sseq@\sseq@classpattern @maxclasses\endcsname} \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} \else \ifnum\sseq@classinsert<\z@ % negative 1 is where we would normally insert things \edef\sseq@classinsert{\the\numexpr\nodenum+\sseq@classinsert+1} \fi \ifnum\sseq@classinsert<\@ne \def\sseq@classinsert{1} \fi \ifnum\sseq@classinsert>\nodenum\relax \edef\sseq@classinsert{\nodenum} \fi \ifnum\nodenum>\@ne \@xp\sseq@class@adjustclasses\@xp{\partialcoord} % Adjust all of the indices of the classes to the right of the one we're inserting \fi \fi % % \sseq@xminmax{\xcoord}{\ycoord}% \sseq@yminmax{\xcoord}{\ycoord}% \sseq@cleanup@obj{partcoord.(\partialcoord).numnodes}% \sseq@obj@xdef{partcoord.(\partialcoord).numnodes}{\nodenum}% \edef\classname{class.\coord[0]}% \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{ \sseq@error@xx{class-tag-already-defined}{\sseq@class@tagprefix\sseq@class@tag}{(\partialcoord)}% could be warning }{} \sseq@cleanup@obj{class.\coord.tag} \sseq@obj@xdef{class.\coord.tag}{\sseq@class@tagprefix\sseq@class@tag} \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{\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 % % \sseq@obj@gdef{class.\coord.num}{0}% For \replaceclass \sseq@obj@xdef{\classname.page}{\sseq@infinity}% \sseq@obj@xdef{class.\coord.n}{\sseq@classinsert} \ifx\sseq@familylist\pgfutil@empty\else \sseq@obj@xodef{\classname.familylist}{\sseq@familylist} \fi \ifx\sseq@savedoptioncode\pgfutil@empty\else \sseq@obj@xodef{\classname.options}{\sseq@savedoptioncode}% \fi \ifx\sseq@classnodetext\pgfutil@empty\else \sseq@obj@xodef{\classname.nodetext}{\sseq@classnodetext} \fi \ifx\sseq@classnodetextoptions\pgfutil@empty\else \sseq@obj@xodef{\classname.nodetext.options}{\sseq@classnodetextoptions} \fi \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 \@ifundefined{sseq@tempoffset}{}{% \@xp\tikz@scan@one@point\@xp\sseq@setoffset\sseq@tempoffset }% \ifx\sseq@tooltip\pgfutil@empty\else \sseq@obj@protectedxdef{\classname.tooltip}{\sseq@tooltip} \fi % \sseq@savedpaths@addclass{class.\coord}% } \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{ \sseq@tempcount=\z@ \sseq@tempcountb=\sseq@obj{partcoord.(#1).numnodes} \loop \advance\sseq@tempcount\@ne \ifnum\sseq@obj{class.(#1,\the\sseq@tempcount).n}<\sseq@classinsert\relax\else \sseq@cleanup@obj{class.(#1,\the\sseq@tempcount).n} \sseq@eval{\@nx\sseq@obj@inc{class.(#1,\the\sseq@tempcount).n}} % unfortunately, \sseq@obj@inc uses \sseq@tempcount so we need this eval \fi \ifnum\sseq@tempcount<\sseq@tempcountb\repeat } \sseq@DeclareDocumentCommand\classoptions{od()}{% \begingroup \sseq@loadinputline \sseq@xsetthiscall{\string\classoptions\IfNoValueF{#1}{[\unexpanded{#1}]}\unexpanded{(#2)}}% \IfNoValueT{#1}{\sseq@error@x{cmdoptions-without-options}{\string\classoptions}\sseq@break}% could be warning \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@classstyle \the\sseq@scope@toks \sseq@options@normalmode \let\sseq@processlabels\sseq@processlabels@default % Don't double dip on labels from the scope or classstyle \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 % \let\partialcoord\coord@partial \edef\sseq@classnum{\sseq@obj@ifdef{class.\coord.num}{\sseq@obj{class.\coord.num}}{0}} \@ifundefined{sseq@class@page}{% \@ifundefined{sseq@gen}{ \@ifundefined{sseq@thepage}{ \let\sseq@gen\sseq@classnum }{ \sseq@obj@pagetogen{class.\coord}{\sseq@thepage} % stores in \sseq@gen } \let\sseq@genmax\sseq@gen }{ \ifnum\sseq@gen<\z@ \edef\sseq@gen{\the\numexpr\sseq@classnum+\sseq@gen+1} \fi \@ifundefined{sseq@genmax}{\let\sseq@genmax\sseq@gen}{ \edef\sseq@genmax{\the\numexpr\sseq@classnum+\sseq@genmax+1} } } }{ \@ifundefined{sseq@gen}{}{\sseq@error{classoptions-page-gen}}% This could be a warning \sseq@class@getgen{\sseq@class@page} \@ifundefined{sseq@class@pagemax}{ % If no max is present, apply options to all pages starting at specified minimum \let\sseq@genmax\sseq@classnum% \let\sseq@class@pagemax\sseq@infinity % ensure if "page" is defined, "pagemax" is defined too }{ \let\sseq@genmin\sseq@gen \sseq@class@getgen{\sseq@class@pagemax} \let\sseq@genmax\sseq@gen \let\sseq@gen\sseq@genmin } \edef\sseq@class@page{\the\numexpr\sseq@class@page-\@ne} \edef\sseq@class@pagemax{\the\numexpr\sseq@class@pagemax+\@ne} } \ifnum\sseq@gen=\m@ne \let\sseq@gen\sseq@classnum \fi \edef\classname{class.\coord[\sseq@gen]} \ifsseq@keepchanges\else \ifnum\sseq@thepagecount>\sseq@obj{\classname.page}\relax \sseq@error@xxx{classoptions-already-dead}{\sseq@gen}{\coordname}{\sseq@obj{\classname.page}} \sseq@breakfifi \fi \ifnum\sseq@gen>\z@ \ifnum\sseq@thepagecount>\sseq@obj{class.\coord[\the\numexpr\sseq@gen-\@ne].page}\relax\else \sseq@error@xx{classoptions-not-yet-born}{\sseq@gen}{\coord}{\sseq@class@page}% \sseq@breakfififi \fi \fi \fi{} \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{% \sseq@error@nn{class-tag-already-defined}{\sseq@class@tagprefix\sseq@class@tag}{\sseq@partialcoord}% could be warning }% \sseq@cleanup@obj{class.\coord.tag}% \sseq@obj@xdef{class.\coord.tag}{\sseq@class@tagprefix\sseq@class@tag}% \sseq@cleanup@obj{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}% \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{\classname.name}{ \sseq@error@nn{classoptions-class-already-named}{\coord}{\sseq@obj{\classname.name}}%could be warning }{} \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 \loop \advance\sseq@tempcount\@ne \edef\classname{class.\coord[\the\sseq@tempcount]} \sseq@cleanup@obj{\classname.options} \sseq@classoptions@setup@pagerange \sseq@classoptions@obj@addto@withpagerange{\classname.options}{\sseq@savedoptioncode} % \ifx\sseq@classnodetext\pgfutil@empty\else \sseq@cleanup@obj{\classname.nodetext} \@ifundefined{sseq@class@page}{}{ \sseq@obj@xdef{\classname.nodetext}{ \@nx\ifnum\@nx\sseq@thepagecount<\the\numexpr\sseq@class@page+1\relax\relax \unexpanded\@xptwo{\csname \sseq@obj@fullname{\classname.nodetext}\endcsname\fi} } } \sseq@classoptions@obj@addto@withpagerange{\classname.nodetext}{\sseq@classnodetext} \fi \ifx\sseq@classnodetextoptions\pgfutil@empty\else \sseq@cleanup@obj{\classname.nodetext.options} \sseq@classoptions@obj@addto@withpagerange{\classname.nodetext.options}{\sseq@classnodetextoptions} \fi \ifx\sseq@classlabelnodes\pgfutil@empty\else \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} \fi \@ifundefined{sseq@tempoffset}{}{ \sseq@cleanup@obj{\classname.offset} \@xp\tikz@scan@one@point\@xp\sseq@setoffset\sseq@tempoffset } \ifnum\sseq@tempcount<\sseq@genmax\repeat \sseq@breakpoint \endgroup } \def\sseq@classoptions@setup@pagerange{% \@ifundefined{sseq@class@page}{ \def\sseq@classoptions@obj@addto@withpagerange@{\sseq@obj@gaddto{\sseq@tempobj}} }{ \def\sseq@temp##1{##1} \ifnum\sseq@tempcount=\sseq@gen\relax \sseq@eval{\@nx\pretocmd\@nx\sseq@temp{\@nx\ifnum\sseq@thepagecount>\sseq@class@page\relax}{}{% \@nx\sseq@error@x{this-shouldnt-happen}{file main, function \string\sseq@classoptions@setup@pagerange} }}% \apptocmd\sseq@temp{\fi}{}{\sseq@error@x{this-shouldnt-happen}{file main, function \string\sseq@classoptions@setup@pagerange}} \fi \ifnum\sseq@tempcount=\sseq@genmax\relax \sseq@eval{\@nx\pretocmd\@nx\sseq@temp{\@nx\ifnum\sseq@thepagecount<\sseq@class@pagemax\relax}{}{\@nx\sseq@error@internal{}}} \apptocmd\sseq@temp{\fi}{}{\sseq@error@internal{this-shouldnt-happen}{file main, function \string\sseq@classoptions@setup@pagerange}} \fi \@xp\def\@xp\sseq@temp\@xp##\@xp1\@xp{\@xp{\sseq@temp{##1}}} \pretocmd\sseq@temp{\sseq@obj@gaddto{\sseq@tempobj}}{}{\sseq@error@internal{this-shouldnt-happen}{file main, function \string\sseq@classoptions@setup@pagerange}} \let\sseq@classoptions@obj@addto@withpagerange@\sseq@temp } } \def\sseq@classoptions@obj@addto@withpagerange#1#2{% \def\sseq@tempobj{#1}% \@xp\sseq@classoptions@obj@addto@withpagerange@\@xp{#2}% } \def\sseq@class@getgen#1{ \bgroup \ifnum\sseq@classnum>\z@ \sseq@eval{\unexpanded{\sseq@obj@pagetogen{class.\coord}}{#1}} % stores in \sseq@gen \else \def\sseq@gen{0} \fi \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@pushstack@\coord \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@classstyle \the\sseq@scope@toks \sseq@options@normalmode \IfNoValueF{#1}{% \sseq@processoptions{class}{#1}% Outputs result into \sseq@savedoptioncode }% \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}]} % \ifsseq@keepchanges\else % \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 % \sseq@cleanup@obj{class.\coord.num} \sseq@obj@inc{class.\coord.num} \edef\classname{class.\coord[\sseq@obj{class.\coord.num}]} %\show\classname % \let\partialcoord\coord@partial \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{% \sseq@error@nn{class-tag-already-defined}{\sseq@class@tagprefix\sseq@class@tag}{\sseq@partialcoord}% could be warning }{}% \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 \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 \let\partialcoord\coord@partial \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partialcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{% \sseq@error@nn{class-tag-already-defined}{\sseq@class@tagprefix\sseq@class@tag}{\sseq@partialcoord}% could be warning }{}% \sseq@obj@xdef{partialcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\nodenum}% \fi % \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} \ifx\sseq@classnodetext\pgfutil@empty\else \sseq@obj@xodef{\classname.nodetext}{\sseq@classnodetext} \fi \ifx\sseq@classnodetextoptions\pgfutil@empty\else \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} \fi \@ifundefined{sseq@tempoffset}{}{\@xp\tikz@scan@one@point\@xp\sseq@setoffset\sseq@tempoffset} % \sseq@breakpoint \endgroup } \sseq@DeclareDocumentCommand\replacestructlines{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}% % % TODO: error handling here... % \edef\sseq@classnum{\sseq@obj{class.\coord.num}}% \ifnum\sseq@classnum=0\relax \sseq@error@x{replacestructlines-class-not-replaced}{\coordname}\sseq@breakfi \fi \edef\classname{class.\coord[\sseq@classnum]}% %\show\classname \edef\oldclassname{class.\coord[\the\numexpr\sseq@obj{class.\coord.num}-1]}% \sseq@cleanup@obj{\classname.dependencies}% \sseq@obj@gletobj{\classname.dependencies}{\oldclassname.dependencies}% %\sseq@obj@show{\classname.dependencies} \sseq@obj@map{\classname.dependencies}{ \sseq@cleanup@obj{##1.page}% \sseq@obj@gletobj{##1.page}{##1.page.old}% } \sseq@breakpoint \endgroup } \def\sseq@class@draw@ifpage#1{ \bgroup \sseq@obj@pagetogen{#1}{\sseq@thepage} % sets \sseq@gen \ifnum\sseq@gen>\m@ne % -1 means no class to print \ifnum\sseq@obj{#1[\sseq@gen].page}=\sseq@thepagecount \sseq@thispagetrue \fi \sseq@drawtrue \sseq@obj{#1[\sseq@gen].familylist} \ifsseq@draw \sseq@gsetthiscall{class #1} \sseq@class@drawnode{#1[\sseq@gen]} \fi \fi \egroup } % #1 -- object % #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. \def\sseq@obj@pagetogen#1#2{ \bgroup \def\sseq@gen{-1} \sseq@tempcount=\m@ne \sseq@tempcountb=\sseq@obj{#1.num}\relax \loop \advance\sseq@tempcount\@ne \ifnum\sseq@obj{#1[\the\sseq@tempcount].page}<#2\relax\else \edef\sseq@gen{\the\sseq@tempcount} \sseq@tempcount=\sseq@tempcountb\relax \fi \ifnum\sseq@tempcount<\sseq@tempcountb\repeat \sseq@smuggle@macro\sseq@gen \egroup } %%% %%% \kill, \d and \doptions %%% % Because \kill doesn't take options, there's no need to use \sseq@DeclareDocumentCommand for the outer command. % Rather than use \sseq@DeclareDocumentCommand with no arguments, we just do the normal stuff that \sseq@DeclareDocumentCommand would do, % Then call \sseq@d@grabpage, the command that is responsible for handling the strange syntax of the page argument for \d. \protected\def\sseq@kill{% \begingroup \sseq@setinputline % These two lines normally would happen inside of \sseq@DeclareDocumentCommand. \sseq@loadinputline \sseq@d@grabpage\sseq@kill@ } % Now we need to parse a potential coordinate. \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 }{% \sseq@error@x{d-invalid-page}{\unexpanded\@xp{\sseq@dpage}}\sseq@break% }% \sseq@eval{\@nx\sseq@d@setpageminrec{class.\coordinate}{\the\sseq@tempcount}{coordinate}}% automatically handles \sseq@cleanup@obj \sseq@breakpoint \endgroup } % \sseq@d@grabpage is defined in sseqparsers. \sseq@DeclareDocumentCommand\d{o}{% \begingroup \sseq@loadinputline \def\sseq@dtype{d} \def\sseq@d@theoptions{#1} \sseq@d@grabpage\sseq@d@ } \sseq@DeclareDocumentCommand\doptions{o}{% \begingroup \sseq@loadinputline \def\sseq@dtype{doptions} \def\sseq@d@theoptions{#1} \sseq@d@grabpage\sseq@d@ } \def\sseq@d@{ \ifsseq@tempif \csname sseq@\sseq@dtype @grabcoord\@xp\endcsname \else \sseq@eval{\@nx\sseq@d@main{\sseq@dtype}{\unexpanded\@xp{\sseq@d@theoptions}}{\sseq@dpage}{\sseq@NoValue}{\sseq@NoValue}} \sseq@breakpoint \endgroup \fi } \sseq@DeclareDocumentCommandAs\sseq@d@grabcoord\d{d()d()}{ \sseq@eval{\@nx\sseq@d@main{\sseq@dtype}{\unexpanded\@xp{\sseq@d@theoptions}}{\sseq@dpage}}{#1}{#2} \sseq@breakpoint \endgroup } \sseq@DeclareDocumentCommandAs\sseq@doptions@grabcoord\doptions{d()d()}{ \sseq@eval{\@nx\sseq@d@main{\sseq@dtype}{\unexpanded\@xp{\sseq@d@theoptions}}{\sseq@dpage}}{#1}{#2} \sseq@breakpoint \endgroup } \def\sseq@d@main#1#2#3#4#5{% \sseq@options@firstpassmode \def\sseq@edgetype{differential}% \the\sseq@sseqstyle \the\sseq@edgestyle \the\sseq@differentialstyle \the\sseq@scope@toks \sseq@options@normalmode \IfNoValueF{#2}{% \sseq@processoptions{differential}{#2}% Outputs result into \sseq@savedoptioncode }% \sseq@xsetthiscall{\@xp\string\csname#1\endcsname\IfNoValueF{#2}{\unexpanded{[#2]}}\unexpanded{#3}\IfNoValueF{#4}{\unexpanded{(#4)}}\IfNoValueF{#5}{\unexpanded{(#5)}}}% \sseq@ifintexpr{#3}{% \sseq@tempcount=\numexpr#3\relax % this is a convenient way to get rid of spaces because #3 has to be a number }{% \sseq@error@n{d-invalid-page}{#3}\sseq@break }% \sseq@eval{\@nx\sseq@dparsecoord{\the\sseq@tempcount}{\IfNoValueTF{#4}{\lastclass0}{\unexpanded{#4}}}{\unexpanded{#5}}} \sseq@eval{\unexpanded{\csname sseq@d@#1\endcsname{#2}}{\the\sseq@tempcount}}% \sseq@breakpoint } % #1 -- options % #2 -- page % #3 -- source coordinate \def\sseq@d@d#1#2{%% \sseq@obj@ifdef{class.\source.hasextension}{ \sseq@error@xxx{d-class-has-extension}{source}{\sourcename}{#2} \sseq@break }{} \sseq@obj@ifdef{class.\target.hasextension}{ \sseq@error@xxx{d-class-has-extension}{target}{\targetname}{#2} \sseq@break }{} \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} \sseq@obj@gdef{d.#2\source\target.page}{#2} \sseq@obj@xdef{d.#2\source\target.source}{\source} \sseq@obj@xdef{d.#2\source\target.target}{\target} \sseq@obj@xdef{d.#2\source\target.options}{\ifsseq@needstikz\@nx\sseq@needstikztrue\fi\unexpanded\@xp{\sseq@savedoptioncode}} % \sseq@savedpaths@adddifferential{d.#2\source\target}% \else \sseq@obj@gdef{d.#2\source\target.invisible}{} \fi } \def\sseq@d@doptions#1#2{% \sseq@obj@ifundef{d.#2\source\target.options}{\sseq@error@n{cmdoptions-feature-doesn't-exist}{differential}\sseq@break}{}% \sseq@obj@ifdef{d.#2\source\target.invisible}{\sseq@error{doptions-invisible}\sseq@break} \ifsseq@keepchanges\else \@ifundefined{sseq@thepage}{}{ \ifnum#2=\sseq@thepagecount\else\ifnum\sseq@thepagecount=\z@\else \sseq@error@n{doptions-no-effect-on-this-page}{#2}\sseq@breakfififi \fi\fi }% \fi % \sseq@cleanup@obj{d.#2\source\target.familylist} \sseq@obj@xoaddto{d.#2\source\target.familylist}{\sseq@familylist} \sseq@cleanup@obj{d.#2\source\target.options} \sseq@obj@xaddto{d.#2\source\target.options}{\ifsseq@needstikz\@nx\sseq@needstikztrue\fi\unexpanded\@xp{\sseq@savedoptioncode}} } % Some helper macros: % #1 -- class name for \sseq@obj % #2 -- page % #3 -- source or target for error handling purposes. \def\sseq@d@setpageminrec#1#2#3{% not really recursive. \sseq@cleanup@obj{#1[\sseq@obj{#1.num}].page} \sseq@cleanup@obj{#1[\sseq@obj{#1.num}].deathinfo} \sseq@cleanup@obj{#1[\sseq@obj{#1.num}].deathline} \sseq@d@setpageclass{#1}{#2}{#3} \sseq@obj@map{#1[\sseq@obj{#1.num}].dependencies}{ %\def\temp{##1}\show\temp %\sseq@obj@show{#1[\sseq@obj{#1.num}].dependencies} \sseq@d@setpagemin{##1}{#2} % automatically handles cleanup } } % #1 -- class name for \sseq@obj % #2 -- page % #3 -- source or target for error handling purposes. \def\sseq@d@setpageclass#1#2#3{ \edef\sseq@classgenname{#1[\sseq@obj{#1.num}]} % If the class is dead, then it's only not an error if it died on the current page \ifnum\sseq@obj{\sseq@classgenname.page}<\sseq@infinitycount % If the page it died on is greater than this one, hit-wrong-order error \ifnum\sseq@obj{\sseq@classgenname.page}>#2\relax \let\sseq@deadclass@genname\sseq@classgenname \sseq@preparestacktrace \sseq@error@xxxx{d-hit-wrong-order}{#3}{\csname #3name\endcsname}{#2}{\the\sseq@temptoks} \sseq@breakfifi \fi % If the page it died on is less than this one, class-already-hit error \ifnum\sseq@obj{\sseq@classgenname.page}<#2\relax \let\sseq@deadclass@genname\sseq@classgenname \sseq@preparestacktrace \sseq@error@xxxx{d-class-already-hit}{#3}{\csname #3name\endcsname}{#2}{\the\sseq@temptoks} \sseq@breakfifi \fi \fi % If the class has been replaced before, that's only okay if it was replaced on a previous page. \ifnum\sseq@obj{#1.num}>\z@ \sseq@tempcount=\sseq@obj{#1.num}\relax \advance\sseq@tempcount\m@ne \ifnum\sseq@obj{#1[\the\sseq@tempcount].page}<#2\relax\else \ifnum#2=\sseq@obj{#1[\the\sseq@tempcount].page} \sseq@error@xxxx{d-hit-same-page-replaceclass}{#3}{\csname #3name\endcsname}{#2}{\sseq@obj{#1[\the\sseq@tempcount].deathinfo}} \sseq@breakfififi \else \edef\sseq@deadclass@genname{#1[\the\numexpr\sseq@obj{#1.num}-\@ne]} \sseq@preparestacktrace \sseq@error@xxxx{d-hit-wrong-order}{#3}{\csname #3name\endcsname}{#2}{\the\sseq@temptoks} \sseq@breakfififi \fi \fi \fi \sseq@obj@xdef{\sseq@classgenname.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\\{} \let\sseq@possibleperiod\empty \let\sseq@possibleperiodb\empty \sseq@obj@xdef{\sseq@classgenname.deathlocation}{% on input line \sseq@inputline\sseq@error@inforeachloop } \sseq@obj@xdef{\sseq@classgenname.deathline}{\sseq@inputline} \sseq@tempiffalse \edef\sseq@temp{\the\sseq@foreachcall} \ifx\sseq@temp\pgfutil@empty\else\sseq@tempiftrue\fi \ifx\sseq@restofstacktrace\pgfutil@empty\else\sseq@tempiftrue\fi \sseq@obj@xdef{\sseq@classgenname.deathstacktrace}{% \ifsseq@tempif \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 } \egroup } \def\sseq@preparestacktrace{ \def\foreach{\@nx\foreach} \edef\sseq@temp@i{\unexpanded\@xpthree{\sseq@obj{\sseq@deadclass@genname.deathline}}} \edef\sseq@temp@ii{\sseq@inputline} \ifx\sseq@temp@i\sseq@temp@ii \sseq@temptoks\@xpthree{\sseq@obj{\sseq@deadclass@genname.deathinfo} (in the same \foreach loop)} \else \protected\def\\{} \sseq@eval{\sseq@temptoks{\unexpanded\@xpthree{\sseq@obj{\sseq@deadclass@genname.deathinfo}}\space(\sseq@obj{\sseq@classgenname.deathlocation})}} \sseq@e@addto@macro\sseq@errorinfo{\unexpanded\@xpthree{\sseq@obj{\sseq@deadclass@genname.deathstacktrace}}} \fi } \def\sseq@d@setpagemin#1#2{ \ifnum\sseq@obj{#1.page}>#2\relax \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@cleanup@obj{#1.page.old} \sseq@obj@gletobj{#1.page.old}{#1.page} \sseq@obj@xdef{#1.page}{#2} \fi \fi } \def\sseq@differential@draw@ifpage#1{ \sseq@drawtrue \sseq@obj{#1.familylist} \ifsseq@draw \ifnum\sseq@thepagecount=\z@ \sseq@drawdifferential{#1} \else \ifnum\sseq@obj{#1.page}>\sseq@thepagemm\relax \ifnum\sseq@obj{#1.page}<\sseq@thepagemaxpp\relax \sseq@drawdifferential{#1} \fi \fi \fi \fi } \def\sseq@drawdifferential#1{ \bgroup \sseq@eval{ \@nx\sseq@drawedge\sseq@obj{#1.source}\sseq@obj{#1.target}{differential}{% \@nx\sseq@obj{#1.options} } } \egroup } %%% %%% \structline and \structlineoptions %%% \sseq@DeclareDocumentCommand\structline{od()}{% \begingroup \sseq@loadinputline \IfNoValueTF{#2}{ \sseq@structline@main{structline}{#1}{#2}{#2} }{ \def\next{\sseq@structline@@{structline}{#1}{#2}}% \@xptwo\next\sseq@trimleadingspaces } } \sseq@DeclareDocumentCommand\structlineoptions{od()}{% \begingroup \sseq@loadinputline \IfNoValueTF{#2}{ \sseq@structline@main{structlineoptions}{#1}{#2}{#2} }{ \def\next{\sseq@structlineoptions@@{structlineoptions}{#1}{#2}}% \@xptwo\next\sseq@trimleadingspaces } } \sseq@DeclareDocumentCommandAs\sseq@structline@@\structline{mmmd()}{% \sseq@structline@main{#1}{#2}{#3}{#4} } \sseq@DeclareDocumentCommandAs\sseq@structlineoptions@@\structlineoptions{mmmd()}{% \sseq@structline@main{#1}{#2}{#3}{#4} } \def\sseq@structline@main#1#2#3#4{ \sseq@xsetthiscall{\string\structline\IfNoValueF{#2}{\unexpanded{[#2]}}\IfNoValueF{#3}{\unexpanded{(#3)}\IfNoValueF{#4}{\unexpanded{(#4)}}}}% \def\sseq@edgetype{structline} \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@edgestyle \the\sseq@structlinestyle \the\sseq@scope@toks \sseq@options@normalmode \IfNoValueF{#2}{% \sseq@processoptions{struct line}{#2}% Outputs result into \sseq@savedoptioncode }% \def\sourcename{#3}% \def\targetname{#4}% \IfNoValueTF{#3}{% \def\sourcename{\lastclass1}% \def\targetname{\lastclass}% }{% \IfNoValueT{#4}{% \def\targetname{\lastclass}% }% }% \sseq@parsecoord\source{\sourcename}{source of structure line}% \sseq@parsecoord\target{\targetname}{target of structure line}% % Sort \xsource and \xtarget. This is to ensure that if a person adds \ifnum\xsource>\xtarget\relax \sseq@parsedcoords@swap\source\target \else \ifnum\xsource=\xtarget\relax \ifnum\ysource>\ytarget\relax \sseq@parsedcoords@swap\source\target \else \ifnum\ysource=\ytarget\relax \ifnum\nsource>\ntarget\relax \sseq@parsedcoords@swap\source\target \else \ifnum\nsource=\ntarget\relax \sseq@error@n{edge-source-target-equal}{\structline}% \sseq@fbreak \fi \fi \fi \fi \fi \fi \relax % stop fbreak \@ifundefined{sseq@structline@page}{%this is repeated in circleclasses \def\sseq@pagemin{0} \ifnum\sseq@obj{class.\source.num}>\z@ \edef\sseq@pagemin{\sseq@obj{class.\source[\the\numexpr\sseq@obj{class.\source.num}-1].page}} \fi \ifnum\sseq@obj{class.\target.num}>\z@ \edef\sseq@test{\sseq@obj{class.\target[\the\numexpr\sseq@obj{class.\target.num}-1].page}} \ifnum\sseq@test>\sseq@pagemin\relax \let\sseq@pagemin\sseq@test \fi \fi }{\edef\sseq@pagemin{\the\numexpr\sseq@structline@page-\@ne}} \csname sseq@structline@#1\endcsname \sseq@breakpoint \endgroup } \def\sseq@structline@structline{ \@ifundefined{sseq@structline@pagemax}{}{\ifnum\sseq@structline@pagemax=\sseq@infinity\else \sseq@error{structline-no-page-max}\fi}% could be warning \ifnum\sseq@pagemin<\sseq@obj{class.\source[\sseq@obj{class.\source.num}].page}\relax\else \sseq@error{structline-stillborn} \sseq@breakfi \fi \ifnum\sseq@pagemin<\sseq@obj{class.\target[\sseq@obj{class.\target.num}].page}\relax\else % If the \structline is dead before it is born, throw an error \sseq@error{structline-stillborn} \sseq@breakfi \fi \sseq@obj@ifdef{structline.\source\target.num}{% \ifnum\sseq@obj{structline.\source\target[\sseq@obj{structline.\source\target.num}].page}=\sseq@infinitycount \sseq@error@xx{structline-already-exists}{\sourcename}{\targetname} \sseq@breakfi \fi \sseq@cleanup@obj{structline.\source\target.num} \sseq@obj@inc{structline.\source\target.num} }{ \sseq@cleanup@obj{structline.\source\target.num} \sseq@obj@gdef{structline.\source\target.num}{0} \sseq@savedpaths@addstructline{structline.\source\target} } \edef\sseq@structlinename{structline.\source\target[\sseq@obj{structline.\source\target.num}]} % The following cleanup call is needed to prevent a glitch where if a \structline is made inside of a temporary sseqpage environment, then later attempts % to put a structline throw a "structline already exists" error \sseq@cleanup@obj{\sseq@structlinename.page} \sseq@obj@xdef{\sseq@structlinename.page}{\sseq@infinity} \sseq@obj@xdef{\sseq@structlinename.pagemin}{\sseq@pagemin} \sseq@obj@xdef{\sseq@structlinename.source}{\source} \sseq@obj@xdef{\sseq@structlinename.target}{\target} \sseq@class@adddependence{class.\source}{\sseq@structlinename}% If the source or target is already dead, this will set structlinename.page \sseq@class@adddependence{class.\target}{\sseq@structlinename} \sseq@obj@xodef{\sseq@structlinename.familylist}{\sseq@familylist} \sseq@cleanup@obj{\sseq@structlinename.options} \sseq@obj@xdef{\sseq@structlinename.options}{\ifsseq@needstikz\@nx\sseq@needstikztrue\fi\unexpanded\@xp{\sseq@savedoptioncode}} } \def\sseq@structline@structlineoptions{ \sseq@obj@ifundef{structline.\source\target.num}{ \sseq@error@n{cmdoptions-feature-doesn't-exist}{\structline} \sseq@break }{} \@ifundefined{sseq@structline@page}{ \edef\sseq@gen{\sseq@obj{structline.\source\target.num}} \let\sseq@genmax\sseq@gen }{ \sseq@structline@getgen{\sseq@structline@page} \@ifundefined{sseq@structline@pagemax}{% % If no max is present, apply options to all pages starting at specified minimum \edef\sseq@genmax{\sseq@obj{structline.\source\target.num}}% \let\sseq@structline@pagemax\sseq@infinity }{ \let\sseq@genmin\sseq@gen \sseq@structline@getgen{\sseq@structline@pagemax} \let\sseq@genmax\sseq@gen \let\sseq@gen\sseq@genmin } \edef\sseq@structline@page{\the\numexpr\sseq@structline@page-1} \edef\sseq@structline@pagemax{\the\numexpr\sseq@structline@pagemax+1} } \sseq@tempcount=\sseq@gen\relax \advance\sseq@tempcount\m@ne \loop \advance\sseq@tempcount\@ne \edef\sseq@structlinename{structline.\source\target[\the\sseq@tempcount]} \sseq@cleanup@obj{\sseq@structlinename.options} \sseq@cleanup@obj{\sseq@structlinename.familylist} \ifsseq@needstikz \sseq@obj@gaddto{\sseq@structlinename.options}{\sseq@needstikztrue} \fi \ifnum\sseq@tempcount=\sseq@gen\relax \@ifundefined{sseq@structline@page}{}{ \edef\sseq@savedoptioncode{\@nx\ifnum\sseq@thepagecount>\sseq@structline@page\relax\unexpanded\@xp{\sseq@savedoptioncode}\@nx\fi} \edef\sseq@familylist{\@nx\ifnum\sseq@thepagecount>\sseq@structline@page\relax\unexpanded\@xp{\sseq@familylist}\@nx\fi} } \fi \ifnum\sseq@tempcount=\sseq@genmax\relax \@ifundefined{sseq@structline@pagemax}{}{ \edef\sseq@savedoptioncode{\@nx\ifnum\sseq@thepagecount<\sseq@structline@pagemax\relax\unexpanded\@xp{\sseq@savedoptioncode}\@nx\fi} \edef\sseq@familylist{\@nx\ifnum\sseq@thepagecount<\sseq@structline@pagemax\relax\unexpanded\@xp{\sseq@familylist}\@nx\fi} } \fi \sseq@obj@xoaddto{\sseq@structlinename.options}{\sseq@savedoptioncode} \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 \ifnum\sseq@tempcount>\z@ \ifnum#1<\z@\relax \@ifundefined{sseq@thepage}{ \ifnum\sseq@obj{structline.\source\target[\the\sseq@tempcount].page}<\sseq@infinitycount \sseq@tempcount=\sseq@obj{structline.\source\target[\the\sseq@tempcount].page}\relax \else \advance\sseq@tempcount\m@ne \sseq@tempcount=\sseq@obj{structline.\source\target[\the\sseq@tempcount].page}\relax \advance\sseq@tempcount\@ne \fi }{ \sseq@tempcount=\sseq@thepagecount } \advance\sseq@tempcount\@ne \advance\sseq@tempcount#1\relax \fi \sseq@eval{\unexpanded{\sseq@obj@pagetogen{structline.\source\target}}{\the\sseq@tempcount}} % stores in \sseq@gen \else \def\sseq@gen{0} \fi \sseq@smuggle@macro\sseq@gen \egroup } \def\sseq@class@adddependence#1#2{ \edef\sseq@temp{\sseq@obj{#1.num}} \sseq@d@setpagemin{#2}{\sseq@obj{#1[\sseq@temp].page}}% automatically handles cleanup \sseq@cleanup@obj{#1[\sseq@temp].dependencies} \sseq@obj@xaddto{#1[\sseq@temp].dependencies}{\@nx\\{#2}} } \def\sseq@structline@draw@ifpage#1{ \bgroup \ifnum\sseq@thepagecount=\z@ \ifnum\sseq@obj{#1[0].pagemin}=\z@ \sseq@drawtrue \sseq@obj{#1[0].familylist} \ifsseq@draw \sseq@structline@draw{#1[0]} \fi \fi \else \sseq@obj@pagetogen{#1}{\sseq@thepage} % sets \sseq@gen \ifnum\sseq@gen<\z@\else % negative sseq@gen means don't draw it \ifnum\sseq@obj{#1[\sseq@gen].page}=\sseq@thepagecount \sseq@thispagetrue \fi \ifnum\sseq@obj{#1[\sseq@gen].pagemin}<\sseq@thepagecount \sseq@drawtrue \sseq@obj{#1[\sseq@gen].familylist} \ifsseq@draw \sseq@structline@draw{#1[\sseq@gen]} \fi \fi \fi \fi \egroup } \def\sseq@structline@draw#1{\sseq@eval{\@nx\sseq@drawedge\sseq@obj{#1.source}\sseq@obj{#1.target}{structline}{\@nx\sseq@obj{#1.options}}}} \sseq@DeclareDocumentCommand\extension{od()}{% \begingroup \sseq@loadinputline \IfNoValueTF{#2}{ \sseq@extension@main{extension}{#1}{#2}{#2} }{ \def\next{\sseq@extension@@{extension}{#1}{#2}}% \@xptwo\next\sseq@trimleadingspaces } } \sseq@DeclareDocumentCommand\extensionoptions{od()}{% \begingroup \sseq@loadinputline \IfNoValueTF{#2}{ \sseq@structline@main{extensionoptions}{#1}{#2}{#2} }{ \def\next{\sseq@extensionoptions@@{extensionoptions}{#1}{#2}}% \@xptwo\next\sseq@trimleadingspaces } } \sseq@DeclareDocumentCommandAs\sseq@extension@@\extension{mmmd()}{% \sseq@extension@main{#1}{#2}{#3}{#4} } \sseq@DeclareDocumentCommandAs\sseq@extensionoptions@@\extensionoptions{mmmd()}{% \sseq@extension@main{#1}{#2}{#3}{#4} } \def\sseq@extension@main#1#2#3#4{ \sseq@xsetthiscall{\string\extension\IfNoValueF{#2}{\unexpanded{[#2]}}\IfNoValueF{#3}{\unexpanded{(#3)}\IfNoValueF{#4}{\unexpanded{(#4)}}}}% \def\sseq@edgetype{extension} \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@edgestyle \the\sseq@structlinestyle \the\sseq@scope@toks \sseq@options@normalmode \IfNoValueF{#2}{% \sseq@processoptions{extension}{#2}% Outputs result into \sseq@savedoptioncode }% \def\sourcename{#3}% \def\targetname{#4}% \IfNoValueTF{#3}{% \def\sourcename{\lastclass1}% \def\targetname{\lastclass}% }{% \IfNoValueT{#4}{% \def\targetname{\lastclass}% }% }% \sseq@parsecoord\source{\sourcename}{source of extension}% \sseq@parsecoord\target{\targetname}{target of extension}% \ifnum\xsource>\xtarget\relax \sseq@parsedcoords@swap\source\target \else \ifnum\xsource=\xtarget\relax \ifnum\ysource>\ytarget\relax \sseq@parsedcoords@swap\source\target \else \ifnum\ysource=\ytarget\relax \ifnum\nsource>\ntarget\relax \sseq@parsedcoords@swap\source\target \else \ifnum\nsource=\ntarget\relax \sseq@error@n{edge-source-target-equal}{\extension}% \sseq@fbreak \fi \fi \fi \fi \fi \fi \relax % stop fbreak \csname sseq@extension@#1\endcsname \sseq@breakpoint \endgroup } \def\sseq@extension@extension{ \ifnum\sseq@obj{class.\source[\sseq@obj{class.\source.num}].page}<\sseq@infinity\relax \sseq@error{extension-stillborn} \sseq@breakfi \fi \ifnum\sseq@obj{class.\target[\sseq@obj{class.\target.num}].page}<\sseq@infinity\relax \sseq@error{extension-stillborn} \sseq@breakfi \fi \edef\sseq@extensionname{extension.\source\target} \sseq@obj@ifdef{\sseq@extensionname.source}{% \sseq@error@xx{extension-already-exists}{\sourcename}{\targetname} \sseq@breakfi }{ \sseq@savedpaths@addextension{extension.\source\target} } \sseq@cleanup@obj{class.\source.hasextension} \sseq@obj@gdef{class.\source.hasextension}{} \sseq@cleanup@obj{class.\target.hasextension} \sseq@obj@gdef{class.\target.hasextension}{} \sseq@cleanup@obj{\sseq@extensionname.source} \sseq@obj@xdef{\sseq@extensionname.source}{\source} \sseq@obj@xdef{\sseq@extensionname.target}{\target} \sseq@obj@xodef{\sseq@extensionname.familylist}{\sseq@familylist} \sseq@cleanup@obj{\sseq@extensionname.options} \sseq@obj@xdef{\sseq@extensionname.options}{\ifsseq@needstikz\@nx\sseq@needstikztrue\fi\unexpanded\@xp{\sseq@savedoptioncode}} } \def\sseq@extension@extensionoptions{ \edef\sseq@extensionname{extension.\source\target} \sseq@obj@ifundef{\sseq@extensionname.source}{ \sseq@error@n{cmdoptions-feature-doesn't-exist}{\extension} \sseq@break }{} \sseq@cleanup@obj{\sseq@extensionname.options} \sseq@cleanup@obj{\sseq@extensionname.familylist} \ifsseq@needstikz \sseq@obj@gaddto{\sseq@extensionname.options}{\sseq@needstikztrue} \fi \sseq@obj@xoaddto{\sseq@extensionname.options}{\sseq@savedoptioncode} \sseq@obj@xoaddto{\sseq@extensionname.familylist}{\sseq@familylist} } \def\sseq@extension@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@extension@extension \endgroup } \def\sseq@extension@draw@ifpage#1{ \bgroup \ifnum\sseq@thepage=\sseq@infinity\relax \sseq@extension@draw{#1} \fi \egroup } \def\sseq@extension@draw#1{\sseq@eval{\@nx\sseq@drawedge\sseq@obj{#1.source}\sseq@obj{#1.target}{extension}{\@nx\sseq@obj{#1.options}}}} %% This is a dumb place to put this. It has to be after the differential commands are defined. \ifsseq@draftmode % Okay, have to dummy out all the main commands. % Only add tikz background paths to the savedpaths. We need to draw background paths because they might change the bounding box! \sseq@setsavedpaths@draftmode \let\sseq@handlequote\@gobble % % All we want to do here is record the range. Have to process options in order to figure out where it is. \sseq@DeclareDocumentCommand\class{or()}{% \begingroup \sseq@loadinputline \IfNoValueT{#2}{\sseq@break}% \sseq@xsetthiscall{\string\class\IfNoValueF{#1}{[\unexpanded{#1}]}\unexpanded{(#2)}}% \sseq@options@firstpassmode \the\sseq@sseqstyle \the\sseq@classstyle \sseq@options@normalmode \IfNoValueF{#1}{% \sseq@processoptions{class}{#1}% Outputs result into \sseq@savedoptioncode }% \sseq@cparsecoord{#2}{}% \sseq@xminmax{\xcoord}{\ycoord}% \sseq@yminmax{\xcoord}{\ycoord}% \sseq@pushstack@\coord % also need the class stack to calculate other \class commands. \sseq@cleanup@obj{partcoord.(\partialcoord).numnodes}% \ifnum\nodenum=\@ne \sseq@obj@gdef{partcoord.(\partialcoord).numnodes}{0}% \fi \sseq@obj@xdef{partcoord.(\partialcoord).numnodes}{\nodenum}% \edef\classname{class.\coord[0]}% \ifx\sseq@class@tag\pgfutil@empty\else \sseq@obj@ifdef{partcoord.(\partialcoord).tag.\sseq@class@tagprefix\sseq@class@tag}{% \sseq@error@xx{class-tag-already-defined}{\sseq@class@tagprefix\sseq@class@tag}{(\partialcoord)}% could be warning }{}% \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{\classname.name} \sseq@cleanup@obj{class.namedclass.\detokenize\@xp{\sseq@class@name}} \sseq@namehandler \sseq@obj@xdef{\classname.name}{\sseq@class@name} \sseq@obj@xdef{class.namedclass.\detokenize\@xp{\sseq@class@name}}{\coordnopar} \fi \sseq@breakpoint \endgroup } % Now the rest of these can be no-ops \sseq@DeclareDocumentCommand\classoptions{od()}{} \sseq@DeclareDocumentCommand\replaceclass{od()}{} \sseq@DeclareDocumentCommand\replacesource{o}{} \sseq@DeclareDocumentCommand\replacetarget{o}{} \def\sseq@d@main#1#2#3#4#5{} \DeclareDocumentCommand \sseq@DrawIfValidDifferential@ { mmO{} } { \sseq@loadinputline \def\sseq@dtype{d} \def\sseq@trueclause{#1} \def\sseq@falseclause{#2} \sseq@d@grabpage\sseq@DrawIfValidDifferential@@ } \DeclareDocumentCommand \sseq@DrawIfValidDifferential@@ { d() d() } { \csname sseq@DrawIfValidDifferential@@handle@truefalse% @@\sseq@trueclause\sseq@falseclause \endcsname } % Have to do something in case it branches. We somewhat arbitrarily always % pretend it branched yes. \def\sseq@DrawIfValidDifferential@@handle@truefalse@@{} \def\sseq@DrawIfValidDifferential@@handle@truefalse@@T{\@firstofone} \def\sseq@DrawIfValidDifferential@@handle@truefalse@@F{\@gobble} \def\sseq@DrawIfValidDifferential@@handle@truefalse@@TF{\@firstoftwo} \sseq@DeclareDocumentCommand\structline{od()d()}{} \sseq@DeclareDocumentCommand\structlineoptions{od()d()}{} \sseq@DeclareDocumentCommand\circleclasses{or()r()}{} \sseq@DeclareDocumentCommand\gettag{mr()}{} \expandafter\endinput \fi \newcount\sseq@circleclassuid \sseq@DeclareDocumentCommand\circleclasses{or()r()}{ \begingroup \sseq@loadinputline \def\sseq@keysfortikzprim{} \IfNoValueF{#1}{ \sseq@processoptions{fit}{#1} } \sseq@parsecoord\coorda{#2}{first \@nx\circleclass class} \sseq@parsecoord\coordb{#3}{second \@nx\circleclass class} % % \ifsseq@keepchanges \@ifundefined{sseq@fit@page}{% also in structline@main. TODO: refactor these chunks together? \def\sseq@pagemin{0} \ifnum\sseq@obj{class.\coorda.num}>\z@ \edef\sseq@pagemin{\sseq@obj{class.\coorda[\the\numexpr\sseq@obj{class.\coorda.num}-\@ne].page}} \fi \ifnum\sseq@obj{class.\coordb.num}>\z@ \edef\sseq@test{\sseq@obj{class.\coordb[\the\numexpr\sseq@obj{class.\coordb.num}-\@ne].page}} \ifnum\sseq@test>\sseq@pagemin\relax \let\sseq@pagemin\sseq@test \fi \fi }{\edef\sseq@pagemin{\the\numexpr\sseq@fit@page-\@ne}} \@ifundefined{sseq@fit@pagemax}{\let\sseq@pagemax\sseq@infinity}{\let\sseq@pagemax\sseq@fit@pagemax} \else % Put it on the current page no matter what inside sseqpage \let\sseq@pagemax\sseq@infinity\def\sseq@pagemin{-1} \fi % % \global\advance\sseq@circleclassuid\@ne \edef\circleclassobjname{circleclass(\coordanopar)(\coordbnopar)\the\sseq@circleclassuid} % % \sseq@obj@xodef{\circleclassobjname.options}{\sseq@savedoptioncode} \sseq@obj@xodef{\circleclassobjname.familylist}{\sseq@familylist} \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@object{\circleclassobjname}{\coordanopar}{\coordbnopar}} \sseq@obj@xdef{\circleclassobjname.page}{\sseq@pagemax} \sseq@obj@xdef{\circleclassobjname.pagemin}{\sseq@pagemin} \@ifundefined{sseq@fit@pagemax}{ \ifsseq@keepchanges \sseq@class@adddependence{class.\coorda}{\circleclassobjname}% If the source or target is already dead, this will set structlinename.page \sseq@class@adddependence{class.\coordb}{\circleclassobjname} \fi }{} \sseq@breakpoint \endgroup } \ifsseq@patchfit\else \sseq@DeclareDocumentCommand\circleclasses{or()r()}{% \sseq@warning{circleclasses-not-provided} } \fi \def\sseq@circleclass@draw@ifpage#1#2#3{ \sseq@drawtrue \sseq@obj{#1.familylist} \ifsseq@draw \ifnum\sseq@thepagecount<\numexpr\sseq@obj{#1.page}+\@ne \ifnum\sseq@obj{#1.page}=\sseq@thepagecount \sseq@thispagetrue \fi \ifnum\sseq@obj{#1.pagemin}<\sseq@thepagecount \sseq@circleclass@draw{#1}{#2}{#3} \fi \fi \fi } %% %% Labels %% %% This code is called from the key value handler, but it has more to do with the code in this file so I am putting it here. Search in sseqkeys.code.tex for "Labels" %% \def\sseq@processlabels@default{% \global\let\sseq@classnodetext\pgfutil@empty \global\let\sseq@classnodetextoptions\pgfutil@empty \global\let\sseq@classlabelnodes\pgfutil@empty } \let\sseq@processlabels\sseq@processlabels@default \let\sseqlastlabel\empty % I can't remember why we need to defer this. If at some point I figure this out, I should explain why here and in the definition of \class... \def\sseq@handleclassquotes@inner#1#2{% \begingroup\pgfscope \def\sseq@classquotes@smugglehook{} \def\sseq@classquotes@smugglehook@inner{} \sseq@options@firstpassmode \sseq@thesseqstyle \sseq@thelabelstyle \sseq@theclasslabelstyle \the\sseq@scope@toks \sseq@options@normalmode \gdef\sseqlastlabel{#2} \sseq@processoptions{class/label}{#2}% \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{\result}\sseq@maybemathswitch}% {% This is set up 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 \the\sseq@classlabelstyle\@nx\the\sseq@classlabelstyle@page \sseq@theouterclasslabelstyle \@nx\sseq@collections@labels@hook \@nx\sseq@collections@classlabels@hook \@nx\sseq@collections@outerclasslabels@hook \unexpanded\@xp{\sseq@savedoptioncode}% }% }% \else \let\sseq@classquotes@smugglehook\sseq@classquotes@smugglehook@inner \sseq@options@firstpassmode \the\sseq@innerclasslabelstyle \sseq@options@normalmode \sseq@protectedeval{\@nx\pgfqkeys{/sseqpages/class/label}{#2}}% \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 \@nx\sseq@collections@labels@hook \@nx\sseq@collections@classlabels@hook \@nx\sseq@collections@innerclasslabels@hook \unexpanded\@xp{\sseq@savedoptioncode}% }% \fi \@xp\endpgfscope\@xp\endgroup \sseq@classquotes@smugglehook } \def\sseq@handleedgequotes#1#2{% We use this via \let\tikz@quotes@as\sseq@handleedgequotes /utils/exec={% so it's called inside \pgfkeysalso{stuff}. Need to surround with /utils/exec={} to get out. \let\sseq@savedoptioncode@save\sseq@savedoptioncode \sseq@processoptions{label}{#2} \sseq@needstikztrue \let\sseq@temp\sseq@savedoptioncode \let\sseq@savedoptioncode\sseq@savedoptioncode@save \sseq@e@addto@options{ \@nx\tikzset{ every to/.append style={ edge node={ node [/sseqpages/label, /utils/exec={ \let\@nx\sseq@tikz@transform@save\@nx\tikz@transform \let\@nx\tikz@transform\relax \@nx\sseq@thelabelstyle \@nx\sseq@collections@labels@hook \@nx\sseq@theedgelabelstyle \@nx\sseq@collections@edgelabels@hook \@xp\@nx\csname sseq@the\sseq@edgetype labelstyle\endcsname \@xp\@nx\csname sseq@collections@\sseq@edgetype labels@hook\endcsname \unexpanded\@xp{\sseq@temp} \ifsseq@rotatelabels\iftikz@fullytransformed\else\@nx\tikz@fullytransformedtrue\@nx\tikz@addtransform{\@nx\pgftransformresetnontranslations\@nx\sseq@globalrotatetransform}\fi\fi \unexpanded\@xp{\sseq@edgeoptionhook} % this is just to make description work \let\@nx\tikz@transform\@nx\sseq@tikz@transform@save } ]{\sseq@labeltextfn{#1}} } } } } } }