summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex')
-rw-r--r--Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex344
1 files changed, 253 insertions, 91 deletions
diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqparsers.code.tex
index cbce7c25492..f1804243fe5 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.sty version 1.0
+%% Package: spectralsequences v1.1.0
%% Author: Hood Chatham
%% Email: hood@mit.edu
-%% Date: 2017-06-18
+%% Date: 2017-08-02
%% License: Latex Project Public License
%%
%% File: sseqparsers.code.tex
@@ -11,11 +11,32 @@
%% ExplSyntaxOn for this whole file!
\ExplSyntaxOn
+\let\sseq@NoValue\c__xparse_no_value_tl
+\protected\def\sseqparseint#1#2{
+ \sseq@ifintexpr{#2+0}{ % +0 here to prevent \lastx from freaking out if it's at the end of #2.
+ \edef#1{\the\numexpr#2\relax}
+ }{
+ \sseq@error{invalid-int-expr}
+ }
+}
+
+% WARNING: doesn't work =(
+\def\sseq@ifint#1{
+ \ifcat$\romannumeral0#1$
+ \prg_return_true:
+ \else
+ \ifcat$\romannumeral-0#1$
+ \prg_return_true:
+ \else
+ \prg_return_false:
+ \fi
+ \fi
+}
% Prevent \protect from causing trouble for \pgfmathparse
\let\sseq@pgfmathparse@orig\pgfmathparse
-\def\sseq@pgfmathparse#1{\let\@@protect\protect\def\protect{}\sseq@pgfmathparse@orig{#1}\restore@protect}
+\protected\def\sseq@pgfmathparse#1{\let\@@protect\protect\def\protect{}\sseq@pgfmathparse@orig{#1}\restore@protect}
%%% ifpgfmathexpr
@@ -24,17 +45,20 @@
% #3 -- false case
% This tests true if \pgfmathparse{#1} throws an error or not. Luckily, \pgfmathparse pipes its errors through \pgfmath@error so this is easy.
\def\sseq@ifpgfmathexpr#1{
- \bgroup
+ \begingroup
\let\protect\pgfutil@empty
\global\sseq@gtempiftrue
- \def\pgfmath@error##1##2{\global\sseq@gtempiffalse}
+ \def\pgfmath@error##1##2{\global\sseq@gtempiffalse\sseq@closegroups\sseq@break}
+ \def\sseq@groupflag{}
\pgfmathparse{#1}
+ \global\let\ifpgfmathunitsdeclared\ifpgfmathunitsdeclared
\ifpgfmathunitsdeclared
\xdef\sseq@mathresult{\pgfmathresult pt}
\else
\xdef\sseq@mathresult{\pgfmathresult}
\fi
- \egroup
+ \endgroup
+ \sseq@breakpoint
\ifsseq@gtempif
\@xp\@firstoftwo
\else
@@ -42,6 +66,8 @@
\fi
}
+\def\sseq@closegroups{\ifx\sseq@groupflag\empty\endgroup\@xp\sseq@closegroups\fi}
+
% Test if single token input is a digit
\def\sseq@ifdigit#1{
@@ -75,21 +101,13 @@
% so we make spaces into catcode other and use \scantokens
\def\sseq@ifintexpr#1{%
\bgroup
- \char_set_catcode_other:N \ %
\sseq@tempcount\z@
- \makeatletter
- \scantokens{\sseq@ifintexpr@first{needsint}#1\sseq@nil}%
+ \sseq@ifintexpr@{needsint}#1\sseq@nil%
\@xp\egroup\next
}
-\@xp\let\@xp\sseq@otherspace\c_catcode_other_space_tl % This has to be a let, no idea why
-%\def\sseq@ifintexpr#1{\@firstoftwo}
-
-% Gobble the space of catcode other that scantokens inserts after \sseq@ifintexpr@first
-\def\sseq@ifintexpr@first#1#2{\sseq@ifintexpr@{#2}}
% We need to use \futurelet so that we can detect open braces even when they only surround one token like {1}
-% so we have to store the state in \sseq@ifintexpr@state
-
+% also we use it to detect spaces. Store the state in \sseq@ifintexpr@state first.
\def\sseq@ifintexpr@#1{\def\sseq@ifintexpr@state{#1}\futurelet\testtok\sseq@ifintexpr@@}
\def\sseq@ifintexpr@@{%
\ifx\testtok\bgroup%
@@ -98,12 +116,10 @@
\ifx\testtok\sseq@nil
\@xp\let\@xp\next\csname sseq@ifintexpr@@\sseq@ifintexpr@state @done\endcsname
\else
- % Even though I \let \sseq@otherspace to a space of catcode other up there,
- % I still need this freaking expandafter here. God only knows why. Figured this out by trial and error.
% We need to check here for a space because \string<space> produces NO OUTPUT regardless of the catcode of the space.
- % This fucks over \sseq@ifintexpr@@@ real hard because it doesn't expect \string#1 to produce no characters.
- \@xp\ifx\sseq@otherspace\testtok
- \def\next{\sseq@ifintexpr@next{~}\@xp\next\@gobble}
+ % This messes up \sseq@ifintexpr@@@ because it doesn't expect \string#1 to produce no characters.
+ \@xp\ifx\space\testtok
+ \def\next{\sseq@ifintexpr@next{\space}\@xp\next\romannumeral-`0}
\else
\let\next\sseq@ifintexpr@@@
\fi
@@ -116,28 +132,24 @@
\ifcat$\@xp\@gobble\string#1$%
\@xp\sseq@ifintexpr@@@@\@xp#1
\else
- % scantokens puts an extra space character after control sequences, so to give them the best shot at working, eat that space character
+ % This is a macro, so fexpand it
% Then use f expansion.
- \@xp\@xp\@xp\sseq@ifintexpr@@@fexpcs\@xp\@xp\@xp#1\@xp\@gobble
+ \@xp\sseq@ifintexpr@@@fexpcs\@xp#1
\fi
}
-% Unfortunately, if we have a macro that takes an argument inside another macro that takes an argument, this will fail (the inside macro will get a space) but such is life.
\def\sseq@ifintexpr@@@fexpcs{\exp_last_unbraced:Nf\sseq@ifintexpr@@@fexpcs@}
\def\sseq@ifintexpr@@@fexpcs@{\futurelet\testtok\sseq@ifintexpr@@@fexpcs@@}
\def\sseq@ifintexpr@@@fexpcs@@{
\ifx\testtok\bgroup
- \@xp\sseq@ifintexpr@false
+ \@xp\sseq@ifintexpr@false % We already tested for groups above, so we need to check if this expanded to a group
\else
- \@xp\sseq@ifintexpr@@@@
+ \@xp\sseq@ifintexpr@@@@ % If it's still a control sequence, then this will fail in the \pgfutil@ifundefined step
\fi
}
-%\exp_last_unbraced:Nf\sseq@ifintexpr@@
-
-
% We can't just use \futurelet because "\let\testtok(" makes \testtok unexpandable
% (I guess that makes sense, but why is it that I need \@xp\ifx\otherspace above if I've also \let\otherspace to a character? Mysterious...),
% so then "\csname hello\testtok\endcsname" is an error. This indexes into our state machine,
@@ -161,7 +173,9 @@
\ifx#1/%
\sseq@ifintexpr@next{*/}
\else
- \pgfutil@ifundefined{sseq@ifintexpr@@\sseq@ifintexpr@state @#1}%
+ % This extra \string here is so that if a control sequence fexpanded and still gave a control sequence,
+ % we don't get a missing \endcsname error here, it just returns false
+ \pgfutil@ifundefined{sseq@ifintexpr@@\sseq@ifintexpr@state @\string#1}%
{\let\next\sseq@ifintexpr@false}%
{\sseq@ifintexpr@next{#1}}%
\fi
@@ -173,11 +187,9 @@
\next
}
-% This has to eat the space
-%\bgroup\lccode`\*=`\ \lowercase{\egroup
- \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@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@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}
@@ -220,6 +232,95 @@
\sseq@makeifint{nointallowed}{\space}{\sseq@ifintexpr@{nointallowed}}
%%
+%% This parser defines the syntax for the page argument of \d.
+%%
+\def\sseq@d@grabpage#1{
+ \let\sseq@grabdpage@return#1
+ \futurelet\testtok\sseq@grabdpage@
+}
+
+\def\sseq@grabdpage@{
+ \sseq@tempiftrue
+ \ifx\testtok\bgroup
+ \let\next\sseq@grabdpage@group
+ \else
+ \def\sseq@dpage{}
+ \let\next\sseq@grabdpage@norm
+ \fi
+ \next
+}
+
+\def\sseq@grabdpage@group#1{\def\sseq@dpage{#1}\sseq@grabdpage@return}
+
+\def\sseq@grabdpage@norm{
+ \futurelet\testtok\sseq@grabdpage@norm@
+}
+
+\def\sseq@grabdpage@norm@{
+ \let\next\sseq@grabdpage@token
+ \ifx\testtok\bgroup
+ \sseq@tempiffalse
+ \let\next\sseq@grabdpage@return
+ \else
+ \ifx\testtok\par
+ \sseq@tempiffalse
+ \let\next\sseq@grabdpage@return
+ \else
+ \ifx\testtok(
+ \let\next\sseq@grabdpage@return
+ \else
+ \@xp\ifx\space\testtok
+ \let\next\sseq@grabdpage@space
+ \fi
+ \fi
+ \fi
+ \fi
+ \next
+}
+
+\def\sseq@grabdpage@space{\sseq@d@addto@macro\sseq@dpage{~}\@xp\sseq@grabdpage@norm\romannumeral-`0}
+
+\def\sseq@grabdpage@token#1{
+ \ifcat$\@xp\@gobble\string#1$%
+ \sseq@d@addto@macro\sseq@dpage{#1}
+ \@xp\sseq@grabdpage@norm
+ \else
+ \ifx#1\end
+ \sseq@tempiffalse
+ \@xp\sseq@grabdpage@return\@xp#1\romannumeral-`0
+ \else
+ \ifx#1\begin
+ \sseq@tempiffalse
+ \@xp\sseq@grabdpage@return\@xp#1\romannumeral-`0
+ \else
+ \@xp\sseq@grabdpage@token@fexpcs\@xp#1\romannumeral-`0
+ \fi
+ \fi
+ \fi
+}
+
+\def\sseq@grabdpage@token@fexpcs{\exp_last_unbraced:Nf\sseq@grabdpage@token@fexpcs@}
+\def\sseq@grabdpage@token@fexpcs@{\futurelet\testtok\sseq@grabdpage@token@fexpcs@@}
+\def\sseq@grabdpage@token@fexpcs@@{
+ \ifx\testtok\bgroup
+ \sseq@tempiffalse
+ \@xp\sseq@grabdpage@return
+ \else
+ \@xp\sseq@grabdpage@token@fexpcs@@@
+ \fi
+}
+\def\sseq@grabdpage@token@fexpcs@@@#1{
+ \ifcat$\@xp\@gobble\string#1$%
+ \sseq@d@addto@macro\sseq@dpage{#1}
+ \@xp\sseq@grabdpage@norm
+ \else
+ \sseq@tempiffalse
+ \@xp\sseq@grabdpage@return
+ \fi
+}
+
+
+%%
%%
%% New Class Pattern
%%
@@ -354,11 +455,6 @@
%% %%
%%%%%% %%%%%%
-% Only works for full coordinates. Used for error checking in \replaceclass and \d.
-\def\sseq@ifundefcoord{\@xp\sseq@ifundefcoord@}
-\def\sseq@ifundefcoord@(#1){%
- \sseq@obj@ifundef{class.(#1).num}%
-}
\def\sseq@ifdead#1{\ifnum\sseq@obj{class.#1[\sseq@obj{class.#1.num}].page}<\sseq@infinitycount\@xp\@firstoftwo\else\@xp\@secondoftwo\fi}
@@ -378,7 +474,8 @@
% inside of an hbox.
\def\sseq@errortype{}
-\def\sseq@printerrortype{\@xp\sseq@ifempty\@xp{\sseq@errortype}{}{~ for ~ \sseq@errortype}}
+\def\sseq@printerrortype#1{\@xp\sseq@ifempty\@xp{\sseq@errortype}{}{#1 \sseq@errortype}}
+\def\sseq@printforerrortype{\sseq@printerrortype{~for~}}
%% Pulls off x,y and evaluates them, puts n or empty into a separate variable.
% #1 -- a coordinate of the form {x,y} or {x,y,stuff}
@@ -390,7 +487,7 @@
\pgfutil@in@ \sseq@protecterror { #1 }
\ifpgfutil@in@
\bgroup
- \sseq@restorefont
+ \sseq@restorefont % This prevents "Missing character" stuff from being written to the log.
\let\sseq@protecterror\relax
\setbox0=\hbox{#1} % Trigger the error message
\egroup
@@ -498,8 +595,11 @@
\ifx\sseq@index\pgfutil@empty
\@xp\sseq@parsecoord@index
\fi
+ % 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
\@xp\let\csname y\sseq@macroname#1\endcsname\sseq@ycoord
+ \@xp\let\csname n\sseq@macroname#1\endcsname\sseq@index
\@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}
@@ -508,6 +608,26 @@
\@xp\edef\csname\sseq@macroname#1@internalname\endcsname{sseq{\sseq@xycoord,\sseq@index}}%
}
+% #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 }
+}
+
% EXPOSE: a wrapper around \sseq@parsecoord. Use full name of coordinate to avoid name class with sseq@parsecoord.
\sseq@DeclareDocumentCommand \parsecoordinate { m r() }{%
\sseq@parsecoord{#1}{#2}{call of \string\parsecoord}%
@@ -522,7 +642,7 @@
\let\partialcoord\sseq@xycoord
\let\xcoord\sseq@xcoord
\let\ycoord\sseq@ycoord
- \edef\nodenum{\sseq@obj@ifundef{partcoord.(\partialcoord).numnodespp}{1}{\sseq@obj{partcoord.(\partialcoord).numnodespp}}}%
+ \edef\nodenum{\sseq@obj@ifundef{partcoord.(\partialcoord).numnodes}{1}{\the\numexpr\sseq@obj{partcoord.(\partialcoord).numnodes}+1}}%
\edef\coordnopar{\xcoord,\ycoord,\nodenum}
\edef\coord{(\coordnopar)}%
}
@@ -540,7 +660,7 @@
\@xp\pgfkeys@spdef\@xp\sseq@rawsindex\@xp{\sseq@rawsindex}
\edef\sseq@rawtindex{\@xp\sseq@dparsecoord@getyindex\@xp{\sseq@restcoord}}%
\@xp\pgfkeys@spdef\@xp\sseq@rawtindex\@xp{\sseq@rawtindex}
- %
+%
\let\sseq@rawindex\sseq@rawsindex
\def\sseq@errortype{source ~ of ~ differential}
\@xp\sseq@parsecoord@index % the \@xp is needed so that \sseq@break inside of parsecoordindex works properly.
@@ -553,6 +673,11 @@
\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)}
@@ -565,6 +690,9 @@
\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)}
}{
\ifx\sseq@rawtindex\pgfutil@empty\else
@@ -587,7 +715,7 @@
\def\sseq@differential@gettarget@#1#2,#3\sseq@nil{\the\numexpr#2+\sseq@targetx{#1}\relax,\the\numexpr#3+\sseq@targety{#1}\relax}
\def\sseq@getfirsttwoelts#1,#2,#3\sseq@nil{#1,#2}
-\def\sseq@getdtarget#1#2#3{\sseq@eval{\edef\@nx#1{\@nx\sseq@differential@gettarget{#2}{\sseq@getfirsttwoelts#3,,\sseq@nil}}}}
+\protected\def\sseq@getdtarget#1#2#3{\sseq@eval{\edef\@nx#1{\@nx\sseq@differential@gettarget{#2}{\sseq@getfirsttwoelts#3,,\sseq@nil}}}}
% Takes a comma separated list that can be empty, have one element, or two elements, returns first element (or empty if list is empty).
\def\sseq@dparsecoord@getxindex#1{\sseq@dparsecoord@getxindex@#1,\sseq@nil}
@@ -600,14 +728,15 @@
}%
}
-\def\sseq@parsecoordinate#1#2{%
+% EXPOSE: a wrapper around \sseq@parsecoord.
+\sseq@DeclareDocumentCommand\parsecoordinate { m r() }{%
\sseq@parsecoord{#1}{#2}{call of \string\parsecoord}%
}
-% EXPOSE: a wrapper around \sseq@parsecoord. Use full name of coordinate to avoid name class with sseq@parsecoord.
-\sseq@DeclareDocumentCommand \parsedifferential { m r() }{%
- \sseq@dparsecoord{#1}{#2}{call of \string\parsecoord}%
+% EXPOSE: a wrapper around \sseq@dparsecoord.
+\sseq@DeclareDocumentCommand \parsedifferential { m r() d() }{%
+ \sseq@dparsecoord{#1}{#2}{#3}%
}
% Expandable coordinate parsing for \isalive.
@@ -659,29 +788,32 @@
%%% The Stack
%%%
-\sseq@addtostorelistlet\sseq@stacktop\relax
-\def\sseq@stackitem#1#2#3{\csname sseq.\sseq@thename.stack.#1.#3\endcsname} % gobble #2 which we added in for the error message
-\def\sseq@getstackentry#1{
- \exp_args:No\sseq@getstackentry@{\sseq@stacktop}{#1}{#1} % Second copy of #1 for error message
+% This maybe should be moved into sseqmain.code.tex...
+\sseq@addtostorelist\sseq@stacktop{}
+\def\sseq@stackitem#1#2{\csname sseq.\sseq@thename.stack.#1.#2\endcsname} % gobble #2 which we added in for the error message
+\def\sseq@getstackentry#1#2{
+ \ifnum#1<\sseq@stackdepth
+ \exp_args:No\sseq@getstackentry@{\sseq@stacktop}{#1}{#2}
+ \else
+ \sseq@protecterror{\sseq@error@xx{index-out-of-bounds}{#1}{\the\sseq@stackdepth}}
+ \fi
}
\def\sseq@getstackentry@#1#2{
\ifnum#2=\z@\@xp\@firstoftwo\else\@xp\@secondoftwo\fi
- {\sseq@stackitem{#1}}
- {\@ifundefined{sseq.\sseq@thename.stack.#1.next}{\sseq@getstackentry@indextoolarge}{
- \exp_args:Nf\sseq@getstackentry@{\csname sseq.\sseq@thename.stack.#1.next\@xp\endcsname\@xp}\@xp{\the\numexpr#2-1}
- }}
+ { \sseq@stackitem{#1} }
+ { \exp_args:Nco\sseq@getstackentry@ { sseq.\sseq@thename.stack.#1.next } { \the\numexpr#2-1 } }
}
-\def\sseq@getstackentry@indextoolarge#1{\sseq@protecterror{\sseq@error@xx{index-larger-than-stack}{#1}{\the\sseq@stackdepth}}}
-\def\sseq@pushstack(#1){
+\protected\def\sseq@pushstack(#1){
\bgroup
\sseq@parsecoord\temp{#1}{}
\sseq@pushstack@\temp
\egroup
}
+% Note that \class directly calls pushstack@ to avoid reparsing the coordinate
\def\sseq@pushstack@{\@xp\sseq@pushstack@@}
\def\sseq@pushstack@@(#1,#2,#3){
@@ -696,11 +828,11 @@
\newcount\sseq@userstacksavecount
-\def\sseq@savestack{
+\protected\def\sseq@savestack{
\global\advance\sseq@userstacksavecount\@ne
\sseq@savestack@name{usersave@\the\sseq@userstacksavecount}
}
-\def\sseq@restorestack{
+\protected\def\sseq@restorestack{
\sseq@restorestack@name{usersave@\the\sseq@userstacksavecount}
\global\advance\sseq@userstacksavecount\m@ne
}
@@ -714,17 +846,19 @@
% if #1 consists of a single nonnegative integer then -0#1 will be turned into some nonpositive integer
% and romannumeral produces no output when handed a nonpositive integer, so the result will be empty.
% If #1 has any nonnumerical tokens or is negative, there will be left over stuff.
+ %
+ % We also have to subtract off \sseq@x so that this behaves correctly inside of a scope (the \lastx value should be unshifted)
\@xp\sseq@ifempty\@xp{\romannumeral-0#1}{
- \sseq@getstackentry{#1}{lastx}
+ \the\numexpr\sseq@getstackentry{#1}{lastx}-\sseq@x\relax
}{
- \sseq@getstackentry{0}{lastx}#1 % #1 isn't a number so put it back
+ \the\numexpr\sseq@getstackentry{0}{lastx}-\sseq@x\relax#1 % #1 isn't a number so put it back
}
}
\def\sseq@lasty#1{
\@xp\sseq@ifempty\@xp{\romannumeral-0#1}{
- \sseq@getstackentry{#1}{lasty}
+ \the\numexpr\sseq@getstackentry{#1}{lasty}-\sseq@y\relax
}{
- \sseq@getstackentry{0}{lasty}#1 % #1 isn't a number so put it back
+ \the\numexpr\sseq@getstackentry{0}{lasty}-\sseq@y\relax#1 % #1 isn't a number so put it back
}
}
@@ -737,16 +871,22 @@
}
-\def\sseq@nameclass#1(#2){
+\sseq@DeclareDocumentCommand\nameclass {mr()} {
\bgroup
+ \sseq@setthiscall{\sseq@nameclass#1(#2)}
+ \let\sseq@possibleoninputlinepar\empty
\sseq@parsecoord\coord{#2}{}
\sseq@cleanup@obj{class.namedclass.#1}
\sseq@obj@xdef{class.namedclass.#1}{\coordnopar}
+ \sseq@breakpoint
\egroup
}
-\def\sseq@tagclass#1(#2){%
+\sseq@DeclareDocumentCommand\tagclass{mr()}{
\bgroup
+ \sseq@setthiscall{\tagclass#1(#2)}
+ \let\sseq@possibleoninputlinepar\empty
+ \def\sseq@class@tag{#1}
\sseq@parsecoord\coord{#2}{}%
\sseq@obj@ifdef{partcoord.(\sseq@xycoord).tag.\sseq@class@tagprefix\sseq@class@tag}{%
\sseq@error@nn{class-tag-already-defined}{\sseq@class@tagprefix\sseq@class@tag}{(\sseq@xycoord)}% could be warning
@@ -755,23 +895,59 @@
\sseq@obj@xdef{class.\coord.tag}{\sseq@class@tagprefix\sseq@class@tag}%
\sseq@cleanup@obj{partcoord.(\sseq@xycoord).tag.\sseq@class@tagprefix\sseq@class@tag}%
\sseq@obj@xdef{partcoord.(\sseq@xycoord).tag.\sseq@class@tagprefix\sseq@class@tag}{\sseq@index}%
+ \sseq@breakpoint
\egroup
}
-\def\sseq@gettag#1(#2){
+\sseq@DeclareDocumentCommand\gettag{mr()}{
\bgroup
+ \sseq@setthiscall{\gettag#1(#2)}
+ \let\sseq@possibleoninputlinepar\empty
\sseq@parsecoord\coord{#2}{}
\sseq@obj@ifdef{class.\coord.tag}{
\xdef#1{\sseq@obj{class.\coord.tag}}
}{
\sseq@error@n{class-no-tag}{(#2)}
}
+ \sseq@breakpoint
\egroup
}
+\prg_new_conditional:Npnn \sseq_if_out_of_bounds:n #1 { T , F , TF } {
+ \bgroup
+ \sseq@tempiftrue
+ \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
+ \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
+ \sseq@tempiffalse
+ \fi\fi\fi\fi
+ \ifsseq@tempif
+ \prg_return_true:
+ \else
+ \prg_return_false:
+ \fi
+}
+\sseq@DeclareDocumentCommand \IfOutOfBoundsTF { r() } { \sseq_if_out_of_bounds:nTF { #1 } }
+\sseq@DeclareDocumentCommand \IfOutOfBoundsT { r() } { \sseq_if_out_of_bounds:nT { #1 } }
+\sseq@DeclareDocumentCommand \IfOutOfBoundsF { r() } { \sseq_if_out_of_bounds:nF { #1 } }
+\sseq@DeclareDocumentCommand \IfInBoundsTF { r() mm } { \sseq_if_out_of_bounds:nTF { #1 } { #3 } { #2 } }
+\sseq@DeclareDocumentCommand \IfInBoundsT { r() } { \sseq_if_out_of_bounds:nF { #1 } }
+\sseq@DeclareDocumentCommand \IfInBoundsF { r() } { \sseq_if_out_of_bounds:nT { #1 } }
+
%%%%%%
%%%
@@ -788,7 +964,7 @@
}
\def\sseq@modtikzcommands@#1{%
\ifx#1\sseq@nil\else
- \edef#1{\@xp\@nx\csname\sseq@macroname#1\space\endcsname\@nx#1}%
+ \protected\edef#1{\@xp\@nx\csname\sseq@macroname#1\space\endcsname\@nx#1}%
\@xp\let\csname\sseq@macroname#1\space\endcsname\sseq@defer@tikzcommand % This is just for error reporting so that it will say "Paragraph ended before \draw was complete"
\@xp\sseq@modtikzcommands@
\fi
@@ -797,6 +973,8 @@
\def\sseq@defer@tikzcommand#1{%
\begingroup
\let\sseq@isaliveprotect\sseq@isaliveprotect@protect
+ \sseq@setinputline
+ \sseq@loadinputline
\sseq@callas{#1}%
\gdef\sseq@thepathsofar{#1[/utils/exec={\sseq@thesseqstyle\sseq@thetikzprimitivestyle\the\sseq@scope@toks\sseq@savedoptioncode}]}%
\xdef\sseq@whattheusersaid{\string#1}
@@ -836,7 +1014,7 @@
\def\sseq@defer@tikzcommand@option[#1]{%
\sseq@processoptions{tikz ~ primitives}{#1}%
\ifx\sseq@savedoptioncode\pgfutil@empty\else
- \sseq@x@addto@macro\sseq@thepathsofar{[/utils/exec={\unexpanded\@xp{\sseq@savedoptioncode}}]}%
+ \sseq@x@addto@macro\sseq@thepathsofar{[/utils/exec={\unexpanded\@xp{\@xp\sseq@options@bothpassmode\sseq@savedoptioncode}}]}%
\fi
\sseq@g@addto@macro\sseq@whattheusersaid{[#1]}
\sseq@defer@tikzcommand@
@@ -927,14 +1105,14 @@
\sseq@defer@tikzcommand@finish@
}
-% If the expression was incomplete, we'll jump here
+% If the expression was incomplete, we'll jump here to avoid adding the semicolon to the error printout
\def\sseq@defer@tikzcommand@finish@{
\sseq@g@addto@macro\sseq@thepathsofar{;}
\global\sseq@thiscalltoks\@xp{\sseq@whattheusersaid}
\ifx\sseq@pageconstraint\sseq@pageconstraint@true
- \sseq@savedpaths@xadd{\unexpanded\@xp{\sseq@thepathsofar}}%
+ \sseq@savedpaths@xaddtikzpath{\unexpanded\@xp{\sseq@thepathsofar}}%
\else
- \sseq@savedpaths@xadd{%
+ \sseq@savedpaths@xaddtikzpath{%
\@nx\sseq@tikzcommand@conditionaldraw{\unexpanded\@xp{\sseq@thepathsofar}}{\unexpanded\@xp{\sseq@pageconstraint}}
}%
\fi
@@ -1151,7 +1329,6 @@
}
-%TODO: fix this...
\def\sseq@updatepageconstraintrange{%
\sseq@protected@edef\sseq@pageconstraint{%
(\unexpanded\@xp{\sseq@pageconstraint})&&(\temp<=\page \ifx\tempmax\empty\else&&\page<=\tempmax\fi)%
@@ -1262,17 +1439,6 @@
\sseqnormalizemonomial@testend
}
-% This is supposed to take a space out of the input stream. For some reason \futurelet grabs it even though it's not supposed to...
-% Make sure braces go around argument, except that if they go around \sseq@nil, \futurelet will grab the the open brace and not see
-% the \sseq@nil. So we use a full expansion and don't put braces around \sseq@nil if that's our argument.
-% MOTHERFUCKING SPACES.
-\def\sseqnormalizemonomial@id#1{
- \ifx\sseq@nil#1
- \@xp\@firstoftwo
- \else
- \@xp\@secondoftwo
- \fi{\@nx\sseq@nil}{{#1}}
-}
\def\sseqnormalizemonomial@testend{
\ifx\testtok\sseq@nil
@@ -1281,12 +1447,8 @@
\egroup
\let\next\@gobble
\else
- \@xp\ifx\space\testtok % not sure why I have to test for spaces like this -- figured it out with trial and error, like in \ifintexpr
- % I'm not really sure why a space can show up here, but it crashes the macro and we don't care about spaces.
- % I can't \@gobble the space because it will ignore it and take the next argument. What I can do is \@firstofone it away, but that deletes braces
- % and in our case it's safe to put in extra braces but not to delete them. So I have \sseqnormalizemonomial@id...
- % LaTeX is really really weird.
- \def\next{\@xp\futurelet\@xp\testtok\@xp\sseqnormalizemonomial@testend\romannumeral-`0\sseqnormalizemonomial@id}
+ \@xp\ifx\space\testtok
+ \def\next{\@xp\futurelet\@xp\testtok\@xp\sseqnormalizemonomial@testend\romannumeral-`0}
\else
\let\next\sseqnormalizemonomial@
\fi