summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2017-08-03 21:07:30 +0000
committerKarl Berry <karl@freefriends.org>2017-08-03 21:07:30 +0000
commitff587f620cc7c6d0068c33b27a8e554bce2b08fe (patch)
tree0857cebe6e2e1325bb94305516fbf9b6e27326c0 /Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex
parent29d69088963132c0a036286f984331c74ac99f1a (diff)
spectralsequences (3aug17)
git-svn-id: svn://tug.org/texlive/trunk@44942 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex')
-rw-r--r--Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex892
1 files changed, 612 insertions, 280 deletions
diff --git a/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex b/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex
index 74667335805..a231aca7b42 100644
--- a/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex
+++ b/Master/texmf-dist/tex/latex/spectralsequences/sseqkeys.code.tex
@@ -1,8 +1,8 @@
%%
-%% Package: spectralsequences.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: sseqkeys.code.tex
@@ -12,7 +12,7 @@
%%
-
+% Run \pgfqkeys{directory}{keys} but for a list of directories. Helps to avoid code duplication.
\def\sseq@pgfqkeysdirlist#1#2{%
\sseq@temptoks{#2}%
\sseq@pgfqkeysdirlist@#1,\sseq@nil
@@ -27,7 +27,7 @@
% These are the things that are used outside of this section:
\let\sseq@pgfkeys@error@save\pgfkeys@error
\pgfkeys{/sseqpages/userstyles/.unknown/.code={\sseq@passoptionto{\sseq@sseqsetdirectory}}}
-\def\sseqset#1{\pgfqkeys{/sseqpages/userstyles}{#1}}
+\protected\def\sseqset#1{\pgfqkeys{/sseqpages/userstyles}{#1}}
\def\sseq@sseqsetdirectory{/sseqpages/global/default}
@@ -60,7 +60,7 @@
% on the first pass. Some only do things on the first pass or only do things on the second pass.
% For example, shifts: shifts apply a coordinate transform on the second pass, but also need to factor into the coordinates of
% classes etc which are computed at specification time not at draw time. So xshift=2 increases \sseq@x by 2 on it's first pass and
-% applies a coordinate transfrom by 2cm on the second pass.
+% applies a coordinate transform by 2cm on the second pass.
% normal mode does the firstpass options now and saves the secondpass options in \sseq@savedoptioncode for later use.
% firstpass mode does the firstpass options and throws away the secondpass options.
@@ -131,24 +131,33 @@
% This is for .unknown handlers. Try same key in different directory #1.
\def\sseq@passoptionto#1{\sseq@eval{\@nx\pgfqkeys{#1}{\pgfkeyscurrentname={\unexpanded\@xp{\pgfkeyscurrentvalue}}}}}
+% Immediately execute a key that is either a tikz or pgf key.
+% #1 -- key
+% #2 -- value
\def\sseq@pgfkeysdocommand#1#2{
\sseq@tempiffalse
- \sseq@pgfkeysdocommand@try{/tikz/#1}{#2}
- \sseq@pgfkeysdocommand@try{/pgf/#1}{#2}
- % is this really an internal error? Maybe we should have failed earlier?
+ \sseq@pgfkeysdocommand@try{/tikz}{#1}{#2}
+ \sseq@pgfkeysdocommand@try{/pgf}{#1}{#2}
\ifsseq@tempif\else\sseq@error@internal@nn{do-command-failed}{#1}{#2}\fi
}
-\def\sseq@pgfkeysdocommand@try#1#2{
+% Execute a key if \sseq@tempif is true and it is defined, if so set \sseq@tempif to false.
+% These are meant to cascade.
+% #1 -- directory
+% #2 -- key
+% #3 -- value
+\def\sseq@pgfkeysdocommand@try#1#2#3{
\ifsseq@tempif\else
- \pgfkeysifdefined{#1/.@cmd}{
+ \pgfkeysifdefined{#1/#2/.@cmd}{
\sseq@tempiftrue
- \pgfkeysgetvalue{#1/.@cmd}{\pgfkeys@code}%
- \pgfkeys@code#2\pgfeov
+ \def\pgfkeysdefaultpath{#1/}
+ \edef\pgfkeyscurrentkey{#1/#2}
+ \pgfkeysgetvalue{#1/#2/.@cmd}{\pgfkeys@code}%
+ \pgfkeys@code#3\pgfeov
}{
- \pgfkeysifdefined{#1}{
+ \pgfkeysifdefined{#1/#2}{
\sseq@tempiftrue
- \pgfkeyssetvalue{#1}{#2}
+ \pgfkeyssetvalue{#1/#2}{#3}
}{}
}
\fi
@@ -180,13 +189,13 @@
\@xp\pgfutil@in@\@xp-\@xp{\tikz@key}%
\ifpgfutil@in@%
% Ah, an arrow spec!
- \sseq@add@tikzkey@to@options{\@nx\tikz@processarrows{\tikz@key}}%
+ \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\@nx\tikz@processarrows{\tikz@key}}}%
\else%
% Ok, third chance: A shape!
\@xp\ifx\csname pgf@sh@s@\tikz@key\endcsname\relax%
\sseq@keys@unknown@error%
\else%
- \sseq@add@tikzkey@to@options{\def\@nx\tikz@shape{\tikz@key}}%
+ \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\def\@nx\tikz@shape{\tikz@key}}}%
\fi%
\fi%
}%
@@ -195,8 +204,8 @@
}
\def\sseq@keys@unknown@handlecolor{%
- \sseq@add@tikzkey@to@options{\@nx\tikz@addoption{\@nx\tikz@compat@color@set{\tikz@key}}}%
- \sseq@add@tikzkey@to@options{\def\@nx\tikz@textcolor{\tikz@key}}%
+ \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\@nx\tikz@addoption{\@nx\tikz@compat@color@set{\tikz@key}}}}%
+ \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\def\@nx\tikz@textcolor{\tikz@key}}}%
}
%%% \sseq@keys@try@addtooptions
@@ -223,9 +232,10 @@
\def\pgfkeysdefaultpath{#1/}%
\def\next{\egroup\@ifnextchar\sseq@nil{\@xp\@secondoftwo\@gobble}{\sseq@keys@try@addtooptions@}}%
\pgfkeysifdefined{#1/\pgfkeyscurrentname/.@cmd}{%
+ \edef\pgfkeyscurrentkey{#1/\pgfkeyscurrentname}%
\ifx\pgfkeyscurrentvalue\pgfkeysnovalue@text% Hmm... no value
\pgfkeysifdefined{#1/\pgfkeyscurrentname/.@def}%
- {\pgfkeysgetvalue{#1/\pgfkeyscurrentname/.@def}{\pgfkeyscurrentvalue}}
+ {\pgfkeysgetvalue{#1/\pgfkeyscurrentname/.@def}{\pgfkeyscurrentvalue}}%
{}% no default, so leave it
\fi%
\pgfkeysgetvalue{#1/\pgfkeyscurrentname/.@cmd}{\pgfkeys@code}%
@@ -236,29 +246,70 @@
}{%
\pgfkeysifdefined{#1/\pgfkeyscurrentname}{%
\egroup
- \sseq@add@tikzkey@to@options{\@nx\pgfkeyssetvalue{#1/\pgfkeyscurrentname}{\unexpanded\@xp{\pgfkeyscurrentvalue}}}%
+ \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\@nx\pgfkeyssetvalue{#1/\pgfkeyscurrentname}{\unexpanded\@xp{\pgfkeyscurrentvalue}}}}%
\def\next{\@xp\@firstoftwo\sseq@gobble@to@nil}%
}{}%
}%
\next
}
+% Iterate over list and run \pgfkeysalso's when we find them. Note that we use our variants of \pgfkeys@case@... which hand control back to this command,
+% so this is recursive -- the result is guaranteed not to have any instance of \pgfkeysalso in it!
\def\sseq@keys@addtooptions@checkalso#1{%
\let\pgfkeys@case@one\sseq@pgfkeys@case@one@store
\let\pgfkeys@case@two@extern\sseq@pgfkeys@case@two@extern@store
\sseq@keys@addtooptions@checkalso@#1\pgfkeysalso\sseq@nil
}
+
\def\sseq@keys@addtooptions@checkalso@#1\pgfkeysalso#2{%
- \sseq@add@tikzkey@to@options{\unexpanded{#1}}%
- \ifx\sseq@nil#2%
+ \def\sseq@tempa{/tikz/}%
+ \def\sseq@tempb{/pgf/}%
+ % This is an extra hook I needed to add so that my own keys can execute code when they need to...
+ \sseq@keys@addtooptions@checkdo#1\sseq@keys@do\sseq@nil
+ \ifx\sseq@nil#2% We're done, restore pgfkeys.
\let\pgfkeys@case@one\sseq@pgfkeys@case@one@save
\let\pgfkeys@case@two@extern\sseq@pgfkeys@case@two@extern@save
\else
- \pgfkeysalso{#2}%
- \@xp\sseq@keys@addtooptions@checkalso@
+ \ifx\expandafter#2 % if they wanted to expand the first token, handle that
+ \sseq@add@tikzkey@to@options{\sseq@options@secondpass@iftikz{\relax\relax}}% The last token was an \expandafter, we need to keep it from doing anything
+ \@xptwo\sseq@keys@addtooptions@checkalso@xp
+ \else
+ \pgfkeysalso{#2}%
+ \@xptwo\sseq@keys@addtooptions@checkalso@
+ \fi
+ \fi
+}
+
+\def\sseq@keys@addtooptions@checkalso@xp#1{%
+ \@xp\pgfkeysalso\@xp{#1}%
+ \sseq@keys@addtooptions@checkalso@
+}
+
+% Used to get collections code to run right.
+\def\sseq@keys@addtooptions@checkdo#1\sseq@keys@do#2{%
+ \sseq@add@tikzkey@to@options{\sseq@options@secondpass@iftikz{\unexpanded{#1}}}%
+ \ifx#2\sseq@nil\else
+ #2%
+ \@xp\sseq@keys@addtooptions@checkdo
+ \fi
+}
+
+% This has to be expandable, so \sseq@tempa and \sseq@tempb are set to "/tikz/" and "/pgf/" ahead of time
+% Defer the command if it is in directories /pgf or /tikz, otherwise run it now. TODO: explain here why we need this.
+\def\sseq@options@secondpass@iftikz{%
+ \ifx\pgfkeysdefaultpath\sseq@tempa
+ \@nx\sseq@options@secondpass
+ \else
+ \ifx\pgfkeysdefaultpath\sseq@tempb
+ \@nx\sseq@options@secondpass
+ \else
+ \@xptwo\@firstofone
+ \fi
\fi
}
+
+% Here we hook into pgfkeys. This is remarkably easy!
\let\sseq@pgfkeys@case@one@save\pgfkeys@case@one
\let\sseq@pgfkeys@case@two@extern@save\pgfkeys@case@two@extern
\def\sseq@pgfkeys@case@one@store{%
@@ -275,7 +326,7 @@
\else%
% The following line is the only change, it used to be (roughly) \pgfkeyssetvalue{\pgfkeyscurrentkey}{\pgfkeyscurrentvalue}
% which would immediately set the value. Instead we store in it \sseq@savedoptioncode
- \sseq@add@tikzkey@to@options{\@nx\pgfkeyssetvalue{\pgfkeyscurrentkey}{\unexpanded\@xp{\pgfkeyscurrentvalue}}}%
+ \sseq@add@tikzkey@to@options{\@nx\sseq@options@secondpass{\@nx\pgfkeyssetvalue{\pgfkeyscurrentkey}{\unexpanded\@xp{\pgfkeyscurrentvalue}}}}%
\fi%
}
@@ -296,6 +347,7 @@
/sseqpages/class/.is family,
/sseqpages/class/label/.is family,
/sseqpages/class/label/.unknown/.code={\sseq@keys@unknown},
+ /sseqpages/class/label/pin/.unknown/.code={\sseq@keys@unknown},
/sseqpages/class/node texts/.is family,
/sseqpages/class/node texts/.unknown/.code={\sseq@passoptionto{/tikz}},
/sseqpages/differential/.is family,
@@ -307,6 +359,7 @@
/sseqpages/tikz primitives/.is family,
/sseqpages/tikz primitives/.unknown/.code={\sseq@keys@unknown},
% One off directories
+ /sseqpages/fit/.is family,
/sseqpages/fit/.unknown/.code={\sseq@passoptionto{/sseqpages}},
/sseqpages/foreach/.unknown/.code={\sseq@passoptionto{/pgf/foreach}},
/sseqpages/class placement/.unknown/.code={\sseq@passoptionto{/tikz}}
@@ -314,10 +367,18 @@
\pgfqkeys{/sseqpages/class}{shape/.code={\edef\tikz@shape{\pgfkeyscurrentname}}} % shape=whatever shape passing
+\newif\ifsseq@pin
\pgfqkeys{/sseqpages/class/label}{% maybe implement multipart node labels this way? No way!
node/.sseq @ first pass code={\sseq@classlabelfalse},
- inside/.sseq @ first pass code={\sseq@classlabelfalse}
+ inside/.sseq @ first pass code={\sseq@classlabelfalse},
+ pin/.sseq @ first pass code = {
+ \let\sseq@savedoptioncode@save\sseq@savedoptioncode
+ \sseq@processoptions{class/label/pin}{#1}
+ \edef\sseq@savedoptioncode{\unexpanded\@xp{\sseq@savedoptioncode@save}\@nx\sseq@d@addto@macro\@nx\sseq@pinoptions{\unexpanded\@xp{\sseq@savedoptioncode}}}
+ },
+ pin/.sseq @ second pass append code = {\sseq@pintrue}
}
+\def\sseq@pinoptions{}
%% label directions
\def\sseq@labeldirectionlist{\\{above}\\{below}\\{left}\\{right}\\{above left}\\{above right}\\{below left}\\{below right}}
@@ -342,8 +403,7 @@
-\sseq@setlabeldirectionkeys{/sseqpages/class/label}[/.sseq @ first pass code]
- {\sseq@classlabeltrue\def\sseq@class@labelposition@name{#1}\def\sseq@class@labelposition@distance{##1}}
+\sseq@setlabeldirectionkeys{/sseqpages/class/label}[/.sseq @ first pass code]{\sseq@classlabeltrue}
\sseq@setlabeldirectionkeys{/sseqpages/class/label}[/.sseq @ second pass append code]{\sseq@class@positionlabel{#1}{##1}}
\sseq@setlabeldirectionkeys{/sseqpages/class/label}[/.default]{\sseq@defaultlabeldistance{#1}}
\sseq@setlabeldirectionkeys{/sseqpages/global/class/label}[/.default]{\sseq@defaultlabeldistance{#1}}
@@ -355,12 +415,12 @@
label distance/.code={\sseq@setdefaultlabeldistances{#1}}
}
-\def\sseq@class@positionlabel#1#2{\sseq@pgfkeysdocommand{#1}{#2}}
+\def\sseq@class@positionlabel#1#2{\ifx\tikz@fig@name\undefined\else\sseq@pgfkeysdocommand{#1}{#2 of \tikz@fig@name}\fi}
\sseq@addtostorelist\sseq@classlabeltextfn{} % \sseq@classlabeltextfn is public via "class label handler"
-\let\sseq@classlabeltextfn@default\@gobble
+\def\sseq@classlabeltextfn@default#1{\def\processedlabel{#1}}
\def\sseq@labeltextfn#1{#1} % labeltextfn is private
\def\sseq@labeltextfn@rotatescale#1{%
\@nx\ifmmode
@@ -403,8 +463,15 @@
\def\sseq@edgeoptionhook{}% This is just to make description work.
+%% Labels
+%% The code for this that actually does most of the work is inside of sseqmain.code.tex -- search for "Labels"
+%% This just handles the interface with the keyvalue system here.
+
+
%% Quote handling
% \sseq@handlequote will be installed later as the 'first char syntax' for ".
+% Problem is that 'first char syntax' isn't allowed to care what directory it is in, but we need different handling
+% for classes versus edges versus scopes. Solution is to use \pgfkeysalso and then define the handler in a key.
\def\sseq@protectlabel{\@nx\sseq@protectlabel\@nx}
\def\sseq@handlequote#1{\pgfkeysalso{handle quote=#1}}
\pgfkeys{%
@@ -415,20 +482,13 @@
\let\tikz@quotes@as\tikz@quotes@as@save
},
/sseqpages/handle quote/.code={%
- \begingroup % group gets ended by handleedgequotes
\let\tikz@quotes@as\sseq@handleedgequotes
\tikz@quote@parser{#1}%
+ \let\tikz@quotes@as\tikz@quotes@as@save
}
}
-\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
-
\def\sseq@handlescopequotes#1#2{% We use this via \let\tikz@quotes@as\sseq@handleclassquotes
/utils/exec={% so it's called inside \pgfkeysalso{stuff}. Need to surround with /utils/exec={} to get out.
\global\let\sseq@classnodetext\pgfutil@empty%
@@ -442,103 +502,6 @@
% so it's called inside \pgfkeysalso{stuff}. Need to surround with /utils/exec={} to get out.
\def\sseq@handleclassquotes#1#2{/utils/exec={\sseq@d@addto@macro\sseq@processlabels{\sseq@handleclassquotes@inner{#1}{#2}}}}
-\def\sseq@handleclassquotes@inner#1#2{%
- \begingroup\pgfscope
- \sseq@options@firstpassmode
- \sseq@thesseqstyle
- \sseq@thelabelstyle
- \sseq@theclasslabelstyle
- \the\sseq@scope@toks
- \sseq@options@normalmode
- \sseq@processoptions{class/label}{#2}%
- \ifx\sseq@classlabeltextfn\@gobble
- \def\processedlabel{#1}%
- \else
- \sseq@classlabeltextfn{#1}% labeltextfn is a private handler, classlabeltextfn is exposed via "class label handler"
- \fi
- \ifsseq@classlabel
- \sseq@options@firstpassmode
- \the\sseq@outerclasslabelstyle
- \sseq@xprotected@addto@macro\sseq@classlabelnodes{
- \@nx\ifsseq@needstikz
- node[
- /sseqpages/class/label,
- /utils/exec={
- \let\@nx\sseq@tikz@transform@save\@nx\tikz@transform
- \let\@nx\tikz@transform\relax % The next line was set up to fix the classlabelstyle glitch
- \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\unexpanded\@xp{\sseq@savedoptioncode}%
- % \@nx\iftikz@fullytransformed\@nx
- % \@nx\tikz@fullytransformedtrue
- % \else
- % \@nx{\@nx\pgftransformresetnontranslations\@nx\sseq@globalrotatetransform}
- % \@nx\fi
- \let\@nx\tikz@transform\@nx\sseq@tikz@transform@save
- }%
- ]{\sseq@labeltextfn{\processedlabel}}%
- \@nx\else
- \@nx\node[
- /sseqpages/class/label,
- /utils/exec={
- \let\@nx\sseq@tikz@transform@save\@nx\tikz@transform
- \let\@nx\tikz@transform\relax % The next line was set up to fix the classlabelstyle glitch
- \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\unexpanded\@xp{\sseq@savedoptioncode}
- % \@nx\iftikz@fullytransformed\@nx
- % \@nx\tikz@fullytransformedtrue
- % \else
- % \@nx{\@nx\pgftransformresetnontranslations\@nx\sseq@globalrotatetransform}
- % \@nx\fi
- \let\@nx\tikz@transform\@nx\sseq@tikz@transform@save
- }
- ]{\unexpanded\@xp{\@xp\sseq@labeltextfn\@xp{\processedlabel}}};%
- \@nx\fi
- }%
- \else
- \sseq@options@firstpassmode
- \the\sseq@innerclasslabelstyle
- \sseq@options@normalmode
- \sseq@protectedeval{\@nx\pgfqkeys{/sseqpages/class/label}{#2}}%
- \sseq@protected@xdef\sseq@classnodetext{\processedlabel}%
- \xdef\sseq@classnodetextoptions{%
- %\unexpanded{\def\pgfkeysdefaultpath{/sseqpages/class/node texts/}}%
- \sseq@thelabelstyle\sseq@theinnerclasslabelstyle\unexpanded\@xp{\sseq@savedoptioncode}%
- }%
- \fi
- \endpgfscope\endgroup
-}
-
-\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.
- \endgroup
- \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@theedgelabelstyle
- \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}}
- }
- }
- }
- }
- }
-}
\def\sseq@checktransform@error{\sseq@error@nn{illegal-transform}}
@@ -550,6 +513,7 @@
\let\sseq@tikzprimitives@coords@maybeclass\sseq@tikzprimitives@coords@notaclass
\let\sseq@checktransform\@gobbletwo
\let\sseq@tikz@shifttransform\sseq@okayshifttransform
+ % TODO: This needs fixing:
%((((((((((((((((((
\def\class##1){\sseq@setthiscall{\string\class##1)}\sseq@error@x{standard-parse}{\string\class}}%
\def\replaceclass##1){\sseq@setthiscall{\string\replaceclass##1)}\sseq@error@x{standard-parse}{\string\replaceclass}}%
@@ -560,6 +524,7 @@
\def\structlineoptions##1)##2){\sseq@setthiscall{\string\structlineoptions##1)##2)}\sseq@error@x{standard-parse}{\string\structlineoptions}}%
}
+% I don't think this is ever actually used...
\def\sseq@nodeparse{%
\let\sseq@tikzprimitives@coords@maybeclass\sseq@tikzprimitives@coords@maybeclass@save
\let\sseq@tikzprimitives@coords@maybeclass
@@ -596,10 +561,12 @@
background/.sseq @ first pass code={\sseq@error@n{option-tikz-prims-only}{background}}
}
+% Some class options. All of these will make changes local to the current \class command. They are communicated to \class via these commands,
+% which we initialize here as empty.
\def\sseq@class@tag{}
\def\sseq@class@tagprefix{}
\def\sseq@class@name{}
-\def\sseq@namehandler{}%\@xp\sseq@normalizepolynomial\@xp{\sseq@class@name}\let\sseq@class@name\sseq@polynomial}
+\def\sseq@namehandler{}
\def\sseq@currenttag{\sseq@class@tag}% for the user ??
\def\sseq@tooltip{}
\pgfqkeys{/sseqpages/scope}{
@@ -607,14 +574,16 @@
tag prefix/.code={\pgfkeys@spdef\temp{#1}\sseq@e@addto@macro\sseq@class@tagprefix{\unexpanded\@xp{#1}}}
}
+\def\sseq@classinsert{}
\pgfqkeys{/sseqpages/class}{
name/.code={\def\sseq@class@name{#1}\pgfkeysalso{/sseqpages/alias=#1}},
- show name/.code={\def\sseq@class@showname{#1}},
+ show name/.store in=\sseq@class@showname,
page/.code={\sseq@getnumrange\sseq@class@page{#1}},% page & gen are only for \classoptions.
generation/.code={\sseq@getnumrange\sseq@gen{#1}}, % \class tests if \sseq@class@page is set and throw an error if so.
tag/.code={\sseq@d@addto@macro\sseq@class@tag{#1}},
- offset/.code={\def\sseq@tempoffset{#1}},
- tooltip/.sseq @ first pass code={\def\sseq@tooltip{#1}}
+ offset/.store in=\sseq@tempoffset,
+ tooltip/.sseq @ first pass code={\def\sseq@tooltip{#1}},
+ insert/.store in=\sseq@classinsert
}
\pgfqkeys{/sseqpages/struct line}{
@@ -647,8 +616,9 @@
}
\pgfqkeys{/sseqpages}{needs tikz/.code=\sseq@needstikztrue}
+% All of these things need tikz to draw but otherwise require no special handling.
\sseq@needstikzandpass{/sseqpages}{%
- shade, blend mode, pattern, path picture, path fading, decorate, pin, label
+ shade, blend mode, pattern, path picture, path fading, decorate, pin, label % should pin be here?
}
\sseq@needstikzandpass{/sseqpages/differential}{%
@@ -671,8 +641,8 @@
% rectangle split/.code=\sseq@needstikzandpass,
% align/.code=\sseq@needstikzandpass,
-\sseq@addtostorelist\sseq@runoffarrow@start@differential@spec{...}
-\sseq@addtostorelist\sseq@runoffarrow@end@differential@spec{...}
+\sseq@addtostorelist\sseq@runoffarrow@start@differential@spec{}
+\sseq@addtostorelist\sseq@runoffarrow@end@differential@spec{>}
\sseq@addtostorelist\sseq@runoffarrow@start@structline@spec{...}
\sseq@addtostorelist\sseq@runoffarrow@end@structline@spec{...}
\sseq@pgfqkeysdirlist{/sseqpages/global,/sseqpages}{
@@ -704,11 +674,24 @@
%% Add key code to \sseq@savedoptioncode
% #1 -- a list of directories to search
% #2 -- keys
+%
+% This is pretty similar in basic concept to \sseq@processoptions, but instead of using the .unknown handlers to walk up the directory,
+% it just tries the key in each directory in the list. I'm not actually sure anymore why it was important to do it this way, but there probably was a good reason...
+%
% This is a faster and sloppier way of doing:
-%\def\sseq@temp{#1}
-%\pgfqkeys{/sseqpages/alwaysunknown}{#2}
+% \def\sseq@temp{#1}
+% \pgfqkeys{/sseqpages/alwaysunknown}{#2}
% and defining an event handler: alwaysunknown/.unknown/.code={\@xp\sseq@keys@try@addtooptions\@xp{\sseq@temp}{}{\sseq@keys@unknown}
+% That basically takes advantage of the pgfkeys parser but gives me back control over what to do with the parsed things.
+%
+% For some reason I made the probably misguided decision that that approach was too slow, even though this isn't performance
+% critical code. Maybe I had a better reason for doing this that I can't remember. Instead I copied pgfkeys but deleted all the
+% parts that are useless in this context, which is most of it. Occasionally bugs crop up here when it turns out I deleted a little too much.
+%
+% This uses a hook \sseq@addstylecodetooptions@unknown to allow the sseqs style to sift out the nonglobal keys and handle them differently.
+%
% Copied with modification from /pgf/utilities/pfgkeys.code.tex
+
\def\sseq@addstylecodetooptions#1#2{%
\def\sseq@directorylist{#1}%
\sseq@simple@pgfkeys@parse#2,\pgfkeys@mainstop
@@ -733,6 +716,7 @@
\pgfkeys@spdef\pgfkeyscurrentvalue{#2}%
\ifx\pgfkeyscurrentkey\pgfkeys@empty\else
\def\next{\@xp\sseq@keys@try@addtooptions\@xp{\sseq@directorylist}{}{\sseq@addstylecodetooptions@unknown}}%
+ % We deleted the general "first char syntax" handler, so we need to do our own check for the quote.
\sseq@simple@pgfkeys@checkquote#1\sseq@nil{%
\def\pgfkeyscurrentname{handle quote}%
\def\pgfkeyscurrentvalue{#1}%
@@ -747,6 +731,7 @@
\@xp\next
\fi
}
+% This is a hook for the "sseqs" style.
\let\sseq@addstylecodetooptions@unknown\sseq@keys@unknown
\long\def\sseq@simple@pgfkeys@checkquote#1#2\sseq@nil{%
@@ -757,17 +742,42 @@
\fi
}
-\def\sseq@sseqstyle@globalpart{}
-
\def\sseq@stylelist{}
\def\sseq@clearchangestyles{}
+% The basic idea here is we make a tokens list \sseq@structlinestyle and define a key "struct lines" that takes a list of keys
+% and adds the keys to \sseq@structlinestyle. In order to do this, I need some special trick to delete spaces.
+% The macro \sseq@setmacronospaces defined in spectralsequences.sty accomplishes this.
\def\sseq@newstyles#1#2{\def\sseq@temppath{#1}\sseq@newstyles@#2,\sseq@nil}
\def\sseq@newstyles@#1,{\sseq@newsseqstyle{\sseq@trimleadingspaces#1}\@ifnextchar\sseq@nil{\@gobble}{\sseq@newstyles@}}
-\def\sseq@set@newstyle#1{\pgfqkeys{/sseqpages}{#1}\pgfqkeys{/sseqpages/global}{#1}\pgfqkeys{/sseqpages/global/default}{#1}\pgfqkeys{/sseqpages/first pass}{#1}}
+\def\sseq@set@newstyle#1{\pgfqkeys{/sseqpages}{#1}\pgfqkeys{/sseqpages/global}{#1}\pgfqkeys{/sseqpages/global/default}{#1}}
+
+% Here are two useful wrappers around addstylecodetotoks.
+
+% #1 -- token list
+% #2 -- path
+% #3 -- code
+\def\sseq@addstylecodetotoks#1#2#3{%
+ \let\sseq@savedoptioncode@store\sseq@savedoptioncode
+ \edef\sseq@savedoptioncode{\the#1}%
+ \sseq@addstylecodetooptions{#2}{#3}%
+ #1\@xp{\sseq@savedoptioncode}%
+ \let\sseq@savedoptioncode\sseq@savedoptioncode@store
+}
+
+% #1 -- macro
+% #2 -- path
+% #3 -- code
+\def\sseq@addstylecodetomacro#1#2#3{%
+ \let\sseq@savedoptioncode@store\sseq@savedoptioncode
+ \let\sseq@savedoptioncode#1%
+ \sseq@addstylecodetooptions{#2}{#3}%
+ \let#1\sseq@savedoptioncode
+ \let\sseq@savedoptioncode\sseq@savedoptioncode@store
+}
\def\sseq@newsseqstyle#1{%
\sseq@setmacronospaces\sseq@tempcmd{sseq@#1style}%
@@ -780,23 +790,15 @@
\sseq@x@addto@macro\sseq@clearchangestyles{\sseq@tempcmdb{}}%
\sseq@set@newstyle{%
#1s/.ecode={%
- \let\@nx\sseq@savedoptioncode@store\@nx\sseq@savedoptioncode
- \edef\@nx\sseq@savedoptioncode{\@nx\the\sseq@tempcmd}%
- \@nx\sseq@addstylecodetooptions{\sseq@temppath}{##1}%
- \sseq@tempcmd\@nx\@xp{\@nx\sseq@savedoptioncode}%
+ \@nx\sseq@addstylecodetotoks{\sseq@tempcmd}{\sseq@temppath}{##1}
\@nx\ifsseq@inprogress
\@nx\sseq@savedpaths@xadd{\sseq@tempcmd{\@nx\the\sseq@tempcmd}}%
\@nx\fi
- \let\@nx\sseq@savedoptioncode\@nx\sseq@savedoptioncode@store
},%
change #1s/.ecode={%
\@nx\ifsseq@ispageenv\@nx\else\@nx\sseq@error@nn{change-style-data}{#1}{##1}\@nx\fi
\@nx\ifsseq@hasname\@nx\else\@nx\sseq@error@nn{change-style-standalone}{#1}{##1}\@nx\fi
- \let\@nx\sseq@savedoptioncode@store\@nx\sseq@savedoptioncode
- \edef\@nx\sseq@savedoptioncode{\@nx\the\sseq@tempcmdb}%
- \@nx\sseq@addstylecodetooptions{\sseq@temppath}{##1}%
- \sseq@tempcmdb\@nx\@xp{\@nx\sseq@savedoptioncode}%
- \let\@nx\sseq@savedoptioncode\@nx\sseq@savedoptioncode@store
+ \@nx\sseq@addstylecodetotoks{\sseq@tempcmdb}{\sseq@temppath}{##1}
}
}%
}
@@ -808,12 +810,13 @@
% sseqs has to be handled separately, because it must decide whether an option is a global option or not
% and handle them at different times. This makes the code a little trickier.
+\def\sseq@sseqstyle@globalpart{}
\sseq@g@addto@macro\sseq@stylelist{\sseq@sseqstyle{\the\sseq@sseqstyle}}%
\sseq@g@addto@macro\sseq@clearchangestyles{\sseq@sseqstyle@page{}}%
\sseq@set@newstyle{
sseqs/.code={%
- \let\sseq@savedoptioncode@store\sseq@savedoptioncode
- \let\sseq@savedoptioncode\sseq@sseqstyle@globalpart
+ % This will get called on each key that isn't a defined global option. Then we add it to \sseq@sseqstyle to be applied
+ % locally to absolutely everything.
\def\sseq@addstylecodetooptions@unknown{%
\let\sseq@sseqstyle@globalpart\sseq@savedoptioncode
\edef\sseq@savedoptioncode{\the\sseq@sseqstyle}%
@@ -821,32 +824,30 @@
\sseq@sseqstyle\@xp{\sseq@savedoptioncode}%
\let\sseq@savedoptioncode\sseq@sseqstyle@globalpart
}%
- \sseq@addstylecodetooptions{/sseqpages/global}{#1}%
- \let\sseq@sseqstyle@globalpart\sseq@savedoptioncode
+ \sseq@addstylecodetomacro\sseq@sseqstyle@globalpart{/sseqpages/global}{#1}%
\ifsseq@inprogress
\sseq@savedpaths@xadd{\sseq@sseqstyle{\the\sseq@sseqstyle}}%
\fi
+ % Restore hook
\let\sseq@addstylecodetooptions@unknown\sseq@keys@unknown
- \let\sseq@savedoptioncode\sseq@savedoptioncode@store
},%
+ % It's not clear to me that "change sseqs" should even exist as an option.
change sseqs/.code={%
\ifsseq@ispageenv\else\sseq@error@nn{change-style-data}{sseq}{#1}\fi
\ifsseq@hasname\else\sseq@error@nn{change-style-standalone}{sseq}{#1}\fi
- \let\sseq@savedoptioncode@store\sseq@savedoptioncode
- \edef\sseq@savedoptioncode{\the\sseq@sseqstyle@page}%
- \sseq@addstylecodetooptions{\sseq@temppath}{#1}%
- \sseq@sseqstyle@page\@xp{\sseq@savedoptioncode}%
- \let\sseq@savedoptioncode\sseq@savedoptioncode@store
+ \sseq@addstylecodetotoks{\sseq@sseqstyle@page}{\sseq@temppath}{#1}%
}
}
+% sseq needs special handling, so is done by hand above.
%\sseq@newstyles{/sseqpages/}{sseq}% DON'T make this /global/default! Bad things will happen.
\sseq@newstyles{/sseqpages/label,/sseqpages}{edge, label, edge label, differential label, struct line label}
\sseq@newstyles{/sseqpages/class,/sseqpages}{class, permanent cycle, transient cycle, this page cycle}
\sseq@newstyles{/sseqpages/differential,/sseqpages}{differential}
\sseq@newstyles{/sseqpages/struct line,/sseqpages}{struct line, this page struct line}
\sseq@newstyles{/sseqpages/class/label}{class label, inner class label, outer class label}
+\sseq@newstyles{/sseqpages/class/label/pin}{pin}
\sseq@newstyles{/sseqpages/tikz primitives}{tikz primitive}
\sseq@newstyles{/sseqpages/fit}{circle class}
@@ -860,11 +861,6 @@
permanent classes/.code={\pgfkeysalso{permanent cycles={#1}}},
transient classes/.code={\pgfkeysalso{transient cycles={#1}}},
this page classes/.code={\pgfkeysalso{this page cycles={#1}}},
- cycle style/.code={\pgfkeysalso{class style={#1}}},
- permanent class style/.code={\pgfkeysalso{permanent cycle style={#1}}},
- transient class style/.code={\pgfkeysalso{transient cycle style={#1}}},
- this page class style/.code={\pgfkeysalso{this page cycle style={#1}}},
- class label position/.code={\pgfkeysalso{class label positions={#1}}}
}%
\def\sseq@newplotstyle#1{
@@ -874,21 +870,13 @@
\@xp\def\sseq@tempcmdb{}
\pgfqkeys{/sseqpages/global}{%
#1 style/.ecode={
- \unexpanded{\let\sseq@savedoptioncode@store\sseq@savedoptioncode}
- \let\@nx\sseq@savedoptioncode\@xp\@nx\sseq@tempcmd
- \unexpanded{\sseq@addstylecodetooptions{/tikz}}{##1}
- \let\@xp\@nx\sseq@tempcmd\@nx\sseq@savedoptioncode
- \unexpanded{\let\sseq@savedoptioncode\sseq@savedoptioncode@store}
+ \@nx\sseq@addstylecodetomacro{\@xp\@nx\sseq@tempcmd}{/tikz}{##1}
}
}
% Only difference here is \sseq@tempcmdb -- which puts it in the default code -- instead of \sseq@tempcmd
\pgfqkeys{/sseqpages/global/default}{%
#1 style/.ecode={
- \unexpanded{\let\sseq@savedoptioncode@store\sseq@savedoptioncode}
- \let\@nx\sseq@savedoptioncode\@xp\@nx\sseq@tempcmdb
- \unexpanded{\sseq@addstylecodetooptions{/tikz}}{##1}
- \let\@xp\@nx\sseq@tempcmdb\@nx\sseq@savedoptioncode
- \unexpanded{\let\sseq@savedoptioncode\sseq@savedoptioncode@store}
+ \@nx\sseq@addstylecodetomacro{\@xp\@nx\sseq@tempcmdb}{/tikz}{##1}
}
}
}
@@ -896,10 +884,152 @@
\def\sseq@newplotstyles#1{\def\sseq@temppath{#1}\sseq@newplotstyles@#1,\sseq@nil}
\def\sseq@newplotstyles@#1,{\sseq@newplotstyle{\sseq@trimleadingspaces#1}\@ifnextchar\sseq@nil{\@gobble}{\sseq@newplotstyles@}}
-
\sseq@newplotstyles{x tick, y tick}
+%%
+%%
+%% Families (also called collections in code)
+%%
+%% These are supposed to make it easy to display / hide and change appearance of logically connected families of classes.
+%% In order to allow a set of options to be given that applies uniformly to all features, we separately apply the options in each of these bins.
+%%
+
+
+\def\sseq@featurelist{\\{class}\\{differential}\\{structline}\\{circleclass}\\{tikzprimitive}}
+\def\sseq@mapfeaturelist#1{\def\\##1{#1}\sseq@featurelist}
+
+\def\sseq@familylist{}
+
+\def\sseq@collections@featuretype{}
+\def\sseqnewfamily#1{%
+ % Make five bins associated to the new family, one for each feature type. Add them to storelist with empty defaults.
+ \sseq@mapfeaturelist{
+ \@xp\sseq@setmacronospaces\csname sseq@tempcmd@##1\endcsname{sseq@user@#1@##1@style}
+ \@xp\sseq@setmacronospaces\csname sseq@tempcmd@##1@default\endcsname{sseq@user@#1@##1@style@default}
+ \sseq@eval{\@nx\sseq@addtostorelist\@xptwo\@nx\csname sseq@tempcmd@##1\endcsname{\@xptwo\@nx\csname sseq@tempcmd@##1@default\endcsname}}
+ \@xptwo\def\csname sseq@user@#1@##1@style@default\endcsname{}
+ }
+ % This is for deciding what set of options to apply to a feature
+ \@xp\sseq@setnospaces\csname sseq@tempcmd\endcsname{sseq@user@#1}
+%
+ % A flag to decide whether to draw the family. Set/unset using "draw family" and "no family".
+ \@xp\sseq@addtostorelist\csname sseq@#1@maybedraw\endcsname{}
+ \pgfqkeys{/sseqpages/global}{%
+ #1 style/.ecode={%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@class{/sseqpages/class,/sseqpages/collections/class}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@differential{/sseqpages/differential,/sseqpages/collections/differential}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@structline{/sseqpages/struct line,/sseqpages/collections/struct line}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@circleclass{/sseqpages/fit,/sseqpages/collections/fit}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@tikzprimitive{/sseqpages/tikz primitives,/sseqpages/collections/tikz primitives}{##1}%
+ },
+ draw #1/.ecode = {\def\@xp\@nx\csname sseq@#1@maybedraw\endcsname{\@nx\sseq@drawtrue}},
+ no #1/.ecode = {\def\@xp\@nx\csname sseq@#1@maybedraw\endcsname{\@nx\sseq@drawfalse}}
+ }%
+ \pgfqkeys{/sseqpages/global/default}{%
+ #1 style/.ecode={%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@class@default{/sseqpages/class}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@differential@default{/sseqpages/differential}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@structline@default{/sseqpages/struct line}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@circleclass@default{/sseqpages/fit}{##1}%
+ \@nx\sseq@addstylecodetomacro\@xp\@nx\sseq@tempcmd@tikzprimitive@default{/sseqpages/tikz primitives}{##1}%
+ },
+ draw #1/.ecode = {\def\@xp\@nx\csname sseq@#1@maybedraw@default\endcsname{\@nx\sseq@drawtrue}},
+ no #1/.ecode = {\def\@xp\@nx\csname sseq@#1@maybedraw@default\endcsname{\@nx\sseq@drawfalse}}
+ }%
+%
+ \pgfqkeys{/sseqpages}{
+ #1/.ecode={
+ \@nx\sseq@d@addto@macro\@nx\sseq@familylist{\@nx\csname sseq@#1@maybedraw\endcsname}
+ \@nx\sseq@options@secondpass{
+ \unexpanded\@xp{\@xp\csname\sseq@tempcmd @\sseq@collections@featuretype @style\endcsname}
+ }
+ }
+ }
+}
+
+
+
+
+\def\sseq@collections@classlabels@hook{}
+\def\sseq@collections@innerclasslabels@hook{}
+\def\sseq@collections@outerclasslabels@hook{}
+\def\sseq@collections@pins@hook{}
+
+\def\sseq@collections@labels@hook{}
+\def\sseq@collections@edgelabels@hook{}
+\def\sseq@collections@differentiallabels@hook{}
+\def\sseq@collections@structlinelabels@hook{}
+
+\def\sseq@collections@setempty#1{\sseq@collections@setempty@#1,\sseq@nil}
+\def\sseq@collections@setempty@#1,{
+ \pgfqkeys{/sseqpages/collections}{
+ class/#1/.code={},
+ differential/#1/.code={},
+ struct line/#1/.code={},
+ fit/#1/.code={},
+ tikz primitives/#1/.code={}
+ }
+ \@ifnextchar\sseq@nil{\@gobble}{\sseq@collections@setempty@}
+}
+
+\sseq@collections@setempty{%
+ classes, cycles, permanent classes, permanent cycles, transient classes, transient cycles, this page classes, this page cycles,
+ edges, differentials,struct lines, this page struct lines,circleclasses, tikz primitives,
+ labels, edge labels, differential labels, struct line labels,
+ class labels, inner class labels, outer class labels,pins
+}
+
+% #1 -- path
+% #2 -- hook name
+% #3 -- code
+\def\sseq@collections@addtohook#1#2#3{
+ \sseq@keys@do{
+ \let\sseq@savedoptioncode@store\sseq@savedoptioncode\let\sseq@savedoptioncode\empty
+ \pgfqkeys{#1}{#3}
+ \edef\sseq@savedoptioncode{\unexpanded\@xp{\sseq@savedoptioncode@store}\def\@nx#2{\unexpanded\@xp{\sseq@savedoptioncode}}}
+ }
+}
+
+\pgfqkeys{/sseqpages/collections}{
+ class/classes/.style={/sseqpages/class/.cd,#1},
+ class/cycles/.style={/sseqpages/class/.cd,#1},
+ class/permanent classes/.code={\ifsseq@permanentcycle\pgfkeysalso{/sseqpages/class/.cd,#1}\fi},
+ class/permanent cycles/.code={\ifsseq@permanentcycle\pgfkeysalso{/sseqpages/class/.cd,#1}\fi},
+ class/transient classes/.code={\ifsseq@permanentcycle\else\pgfkeysalso{/sseqpages/class/.cd,#1}\fi},
+ class/transient cycles/.code={\ifsseq@permanentcycle\else\pgfkeysalso{/sseqpages/class/.cd,#1}\fi},
+ class/this page classes/.code={\ifsseq@thispage\pgfkeysalso{/sseqpages/class/.cd,#1}\fi},
+ class/this page cycles/.code={\ifsseq@thispage\pgfkeysalso{/sseqpages/class/.cd,#1}\fi},
+ differential/edges/.style={/sseqpages/differential/.cd,#1},
+ differential/differentials/.style={/sseqpages/differential/.cd,#1},
+ struct line/edges/.style={/sseqpages/struct line/.cd,#1},
+ struct line/struct lines/.style={/sseqpages/struct line/.cd,#1},
+ struct line/this page struct lines/.code={\ifsseq@thispage\pgfkeysalso{/sseqpages/struct line/.cd,#1}\fi},
+ fit/circleclasses/.style={/sseqpages/fit/.cd,#1},
+ tikz primitives/tikz primitives/.style={/sseqpages/tikz primitives/.cd,#1},
+% labels
+ class/class labels/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/class/label}{\sseq@collections@classlabels@hook}{#1}}},
+ class/inner class labels/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/class/label}{\sseq@collections@innerclasslabels@hook}{#1}}},
+ class/outer class labels/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/class/label}{\sseq@collections@outerclasslabels@hook}{#1}}},
+ class/pins/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/class/label/pin}{\sseq@collections@pins@hook}{#1}}},
+%
+ class/labels/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@labels@hook}{#1}}},
+ differential/labels/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@labels@hook}{#1}}},
+ struct line/labels/.code/.expanded={\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@labels@hook}{#1}}},
+%
+ differential/edge labels/.code/.expanded=
+ {\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@edgelabels@hook}{#1}}},
+ struct line/edge labels/.code/.expanded=
+ {\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@edgelabels@hook}{#1}}},
+ differential/differential labels/.code/.expanded=
+ {\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@differentiallabels@hook}{#1}}},
+ struct line/struct line labels/.code/.expanded=
+ {\unexpanded\@xp{\sseq@collections@addtohook{/sseqpages/label}{\sseq@collections@structlinelabels@hook}{#1}}},
+}
+
+
+
+
%%% Global keys handlers and infrastructure
\def\sseq@keys@lastpart{%
@@ -909,6 +1039,50 @@
\edef\sseq@temp@ii{\pgfkeyscurrentkey}%
}
+\def\sseq@sanitize@intexpr#1#2{
+ \sseq@ifintexpr{#1}{
+ \edef\sseq@sanitize@output{\the\numexpr#1}
+ }{
+ \sseq@error@xx{invalid-intexpr}{\unexpanded{#2}}{#1}
+ \sseq@break
+ }
+}
+
+\def\sseq@sanitize@positiveintexpr#1#2{
+ \sseq@sanitize@intexpr{#1}{#2}
+ \ifnum\sseq@sanitize@output<1\relax
+ \sseq@error@xx{invalid-positive-intexpr}{\unexpanded{#2}}{#1}
+ \@xp\sseq@break
+ \fi
+}
+
+\def\sseq@sanitize@dimenexpr#1#2{
+ \sseq@ifpgfmathexpr{#1}{
+ \ifpgfmathunitsdeclared\else
+ \sseq@error@xx{invalid-dimenexpr}{\unexpanded{#2}}{#1}
+ \@xp\sseq@break
+ \fi
+ \edef\sseq@sanitize@output{\sseq@mathresult}
+ }{
+ \sseq@error@xx{invalid-dimenexpr}{\unexpanded{#2}}{#1}
+ \sseq@break
+ }
+}
+
+\def\sseq@sanitize@color#1#2{
+ \begingroup
+ \global\sseq@gtempiffalse
+ \def\c@lor@error##1{\global\sseq@gtempiftrue}
+ \color{#1}
+ \endgroup
+ \ifsseq@gtempif
+ \sseq@error@xx{invalid-color}{\unexpanded{#2}}{#1}
+ \@xp\sseq@break
+ \else
+ \def\sseq@sanitize@output{#1}
+ \fi
+}
+
\pgfqkeys{/handlers}{
.sseq store in/.code 2 args={%
\sseq@addtostorelist#1{#2}%
@@ -918,6 +1092,44 @@
/sseqpages/global/default/\sseq@temp/.store in/.expand once=\csname \sseq@macroname#1@default\endcsname
}%
},
+ .sseq store in sanitize/.code n args={3}{%
+ \sseq@addtostorelist#1{#2}%
+ \sseq@keys@lastpart
+ \pgfkeys{%
+ \sseq@temp@ii/.code/.expanded={%
+ \unexpanded{#3{##1}}{\sseq@temp=\unexpanded{##1}}%
+ \unexpanded{\edef#1{\unexpanded\@xp{\sseq@sanitize@output}}}%
+ %\show\@nx#1
+ \sseq@breakpoint
+ },
+ \sseq@temp@ii/.value required,
+ /sseqpages/global/default/\sseq@temp/.code/.expanded={%
+ \unexpanded{#3{##1}}{\sseq@temp=\unexpanded{##1}}%
+ \edef\@xp\@nx\csname \sseq@macroname#1@default\endcsname\unexpanded{{\unexpanded\@xp{\sseq@sanitize@output}}}%
+ \sseq@breakpoint
+ },
+ /sseqpages/global/default/\sseq@temp/.value required
+ }%
+
+ },
+ .sseq store int in/.code 2 args={
+ \sseq@keys@lastpart
+ \pgfkeysalso{%
+ \sseq@temp@ii/.sseq store in sanitize={#1}{#2}\sseq@sanitize@intexpr
+ }
+ },
+ .sseq store positive int in/.code 2 args={
+ \sseq@keys@lastpart
+ \pgfkeysalso{%
+ \sseq@temp@ii/.sseq store in sanitize={#1}{#2}\sseq@sanitize@positiveintexpr
+ }
+ },
+ .sseq store dimen in/.code 2 args={
+ \sseq@keys@lastpart
+ \pgfkeysalso{%
+ \sseq@temp@ii/.sseq store in sanitize={#1}{#2}\sseq@sanitize@dimenexpr
+ }
+ },
.sseq append to style/.code 2 args={%
\sseq@addkeytostorelist{#1}{\pgfkeysalso{#2}}%
\sseq@keys@lastpart
@@ -970,8 +1182,8 @@
\sseq@usedparam\sseq@tempb
\fi
\pgfkeys{%
- /sseqpages/global/\sseq@temp/.ecode={\@nx\pgfkeysalso{\sseq@tempb{x}={##1},\sseq@tempb{y}={##1}}},%
- /sseqpages/global/default/\sseq@temp/.ecode={\@nx\pgfkeysalso{\sseq@tempb{x}={##1},\sseq@tempb{y}={##1}}}%
+ /sseqpages/global/\sseq@temp/.code/.expanded={\@nx\pgfkeysalso{\sseq@tempb{x}=\unexpanded{{##1}},\sseq@tempb{y}=\unexpanded{{##1}}}},%
+ /sseqpages/global/default/\sseq@temp/.code/.expanded={\@nx\pgfkeysalso{\sseq@tempb{x}=\unexpanded{{##1}},\sseq@tempb{y}=\unexpanded{{##1}}}}%
}%
}
}
@@ -987,32 +1199,35 @@
}
}
-\def\sseq@add@tikzkey@to@options@forstylehander#1{\sseq@e@addto@options{\@nx\sseq@options@secondpass{#1}}}
+\def\sseq@patchrepeat#1#2#3{%
+ \patchcmd#1{#2}{#3}{\sseq@patchrepeat{#1}{#2}{#3}}{}%
+}
+
+\def\sseq@stylehandler@processpath#1#2{%
+ \def\sseq@savedoptioncode{}%
+ \sseq@eval{\@nx\sseq@addstylecodetooptions{/sseqpages/#1}{\unexpanded\@xp{\sseq@keybody{*1}}}}%
+ \edef\sseq@savedoptioncode##1{\unexpanded\@xp{\sseq@savedoptioncode}}%
+ \sseq@patchrepeat\sseq@savedoptioncode{*1}{##1}%
+ \sseq@eval{\@nx\pgfqkeys{/sseqpages/#1}{\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode{##1}}}}}%
+}
+
+\def\sseq@add@tikzkey@to@options@forstylehander#1{\sseq@e@addto@options{#1}}
\pgfqkeys{/handlers}{ % defines sseq style, etc
sseq @@ make style handler/.style 2 args={%
.sseq #1/.code={%
+ \def\sseq@keybody####1{##1}%
\sseq@keys@lastpart
\let\sseq@savedoptioncode@store\sseq@savedoptioncode
\def\sseq@keys@unknown@error{}%
- \def\sseq@savedoptioncode{}%
\let\sseq@add@tikzkey@to@options\sseq@add@tikzkey@to@options@forstylehander
- \sseq@addstylecodetooptions{/sseqpages/scope}{##1}%
- \sseq@eval{\@nx\pgfkeys{/sseqpages/scope/\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode}}}}%
- \def\sseq@savedoptioncode{}%
- \sseq@addstylecodetooptions{/sseqpages/class}{##1}%
- \sseq@eval{\@nx\pgfkeys{/sseqpages/class/\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode}}}}%
- \def\sseq@savedoptioncode{}%
- \sseq@addstylecodetooptions{/sseqpages/differential}{##1}%
- \sseq@eval{\@nx\pgfkeys{/sseqpages/differential/\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode}}}}%
- \def\sseq@savedoptioncode{}%
- \sseq@addstylecodetooptions{/sseqpages/struct line}{##1}%
- \sseq@eval{\@nx\pgfkeys{/sseqpages/struct line/\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode}}}}%
- \def\sseq@savedoptioncode{}%
- \sseq@addstylecodetooptions{/sseqpages/circle classes}{##1}
- \sseq@eval{\@nx\pgfkeys{/sseqpages/circle classes/\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode}}}}%
- \def\sseq@savedoptioncode{}%
- \sseq@addstylecodetooptions{/sseqpages/tikz primitives}{##1}%
- \sseq@eval{\@nx\pgfkeys{/sseqpages/tikz primitives/\sseq@temp/.#2={\unexpanded\@xp{\sseq@savedoptioncode}}}}%
+%
+ \sseq@stylehandler@processpath{scope}{#2}%
+ \sseq@stylehandler@processpath{class}{#2}%
+ \sseq@stylehandler@processpath{differential}{#2}%
+ \sseq@stylehandler@processpath{struct line}{#2}%
+ \sseq@stylehandler@processpath{circle classes}{#2}%
+ \sseq@stylehandler@processpath{tikz primitives}{#2}%
+%
\let\sseq@savedoptioncode\sseq@savedoptioncode@store
\let\sseq@addstylecodetooptions@unknown\sseq@keys@unknown
\let\sseq@keys@unknown@error\sseq@keys@unknown@error@normal
@@ -1036,7 +1251,7 @@
sseq @@ make code handler=code,
sseq @@ make code handler=prefix code,
sseq @@ make code handler=append code,
-%
+% these just are the same as /.style, etc.
.global sseq style/.code={\pgfkeys{\pgfkeyscurrentpath/.code=\pgfkeysalso{#1}}},
.global sseq prefix style/.code={\pgfkeys{\pgfkeyscurrentpath/.add code={\pgfkeysalso{#1}}{}}},
.global sseq append style/.code={\pgfkeys{\pgfkeyscurrentpath/.add code={}{\pgfkeysalso{#1}}}},
@@ -1147,11 +1362,19 @@
name/.sseq default error,
~page/.code={
\ifsseq@hasname
- \sseq@ifintexpr{#1}{
- \def\sseq@thepage{#1}\sseq@thepagecount=#1\relax\let\page\sseq@thepage
- }{
- \sseq@error{invalid-page}{#1}
- }
+ \sseq@getnumrange\sseq@thepage{#1}
+ \sseq@thepagecount=\sseq@thepage\relax
+ \let\page\sseq@thepage
+ \edef\sseq@thepagemm{\the\numexpr\sseq@thepagecount-1\relax}
+ \ifx\sseq@thepagemax\undefined
+ \edef\sseq@thepagemaxpp{\the\numexpr\sseq@thepagecount+1\relax}
+ \else
+ \ifnum\sseq@thepagemax=\z@
+ \let\sseq@thepagemaxpp\sseq@infinity
+ \else
+ \edef\sseq@thepagemaxpp{\the\numexpr\sseq@thepagemax+1\relax}
+ \fi
+ \fi
\else
\sseq@error{page-no-name}
\fi
@@ -1168,6 +1391,11 @@
},
grid/.code={\ifcsname sseq@grid@#1\endcsname\@xp\let\@xp\sseq@grid\csname sseq@grid@#1\endcsname\else\sseq@error@n{unknown-grid}{#1}\fi},
grid/.sseq default code={\ifcsname sseq@grid@#1\endcsname\@xp\let\@xp\sseq@grid@default\csname sseq@grid@#1\endcsname\else\sseq@error@n{unknown-grid}{#1}\fi},
+ grid color/.sseq store in sanitize=\sseq@gridcolor{gray}\sseq@sanitize@color,
+ grid step/.sseq x y alias,
+ grid step/.value required,
+ x grid step/.sseq store positive int in=\sseq@xgridstep{1},
+ y grid step/.sseq store positive int in=\sseq@ygridstep{1},
math nodes/.sseq is if=mathnodes, % TODO: make this locally toggleable
custom clip/.sseq store in=\sseq@customclip{},
clip/.sseq is if=clip,
@@ -1178,7 +1406,7 @@
draw orphan edges/.sseq is if=draworphanedges,
no orphan edges/.sseq is if false={draworphanedges},
class pattern/.sseq store in=\sseq@classpattern{standard},
- class pattern/.append code={\ifcsname sseq@\sseq@classpattern xoffset1/1\endcsname\else\sseq@error{unknown-class-pattern}\fi},
+ class pattern/.add code={\ifcsname sseq@#1xoffset1/1\endcsname\else\sseq@error{unknown-class-pattern}\@xp\sseq@break\fi}{\sseq@breakpoint},
class placement transform/.code={%
\bgroup
\let\tikz@transform\pgfutil@empty
@@ -1218,8 +1446,6 @@
\sseq@addtostorelist\sseq@classplacementtransform{}
-\sseq@addiftostorelist@truedefault{borderxaxis}\sseq@addiftostorelist@truedefault{borderyaxis}
-\sseq@addtostorelist\sseq@xaxisorigin{0}\sseq@addtostorelist\sseq@yaxisorigin{0}
%%% Range keys and commands
\sseq@globalkeys{%
@@ -1249,18 +1475,27 @@
\@xp\sseq@addtostorelist\@xp\sseq@xmaxpp\@xp{\sseq@infinity}
\@xp\sseq@addtostorelist\@xp\sseq@ymaxpp\@xp{\sseq@infinity}
+\sseq@addiftostorelist{specifiedxrange}
+\sseq@addiftostorelist{specifiedyrange}
\def\sseq@xrange#1#2{%
\global\let\sseq@xminmax\@gobbletwo % Don't need to calculate range of nodes if user specifies it
- \gdef\sseq@xmin{#1}%
- \gdef\sseq@xmax{#2}%
+ \global\sseq@specifiedxrangetrue
+ \sseq@sanitize@intexpr{#1}{x range={#1}{#2}}
+ \sseq@sanitize@intexpr{#2}{x range={#1}{#2}}
+ \xdef\sseq@xmin{\the\numexpr#1}%
+ \xdef\sseq@xmax{\the\numexpr#2}%
\let\xmin\sseq@xmin
\let\xmax\sseq@xmax
% Need to know decremented \xmin and incremented \xmax to decide which nodes to print
\sseq@tempcount=#1 \advance\sseq@tempcount-1\xdef\sseq@xminmm{\the\sseq@tempcount}%
\sseq@tempcount=#2 \advance\sseq@tempcount1\xdef\sseq@xmaxpp{\the\sseq@tempcount}%
+ \sseq@breakpoint
}
\def\sseq@yrange#1#2{%
\global\let\sseq@yminmax\@gobbletwo %
+ \sseq@sanitize@intexpr{#1}{x range={#1}{#2}}
+ \sseq@sanitize@intexpr{#2}{x range={#1}{#2}}
+ \global\sseq@specifiedyrangetrue
\gdef\sseq@ymin{#1}%
\gdef\sseq@ymax{#2}%
\let\ymin\sseq@ymin
@@ -1340,6 +1575,7 @@
%%% Axes and Layout options
\sseq@addtostorelist{\sseq@xtickfn}{} % These should initially be the identity macro, but addtostorelist doesn't accept functions as default
\sseq@addtostorelist{\sseq@ytickfn}{} % so the default is instated in begin{sseqdata} / begin{sseqpicture}.
+
\sseq@globalkeys{%
title/.sseq store in=\sseq@title{},
title style/.sseq append to style={/sseqpages/global/every title}{at={(0.5*\xmin+0.5*\xmax,\ymax)}},
@@ -1358,13 +1594,9 @@
no labels/.sseq x y alias=no #1 label,
draw labels/.sseq x y alias=draw #1 label,
%
- no x axis/.sseq is if false={drawxaxis},
- no y axis/.sseq is if false={drawyaxis},
- no axes/.value forbidden,
- no axes/.sseq x y alias=no #1 axis,
- draw x axis/.sseq is if=drawxaxis,
- draw y axis/.sseq is if=drawyaxis,
- draw axes/.sseq x y alias=draw #1 axis,
+ no x axis/.style={x axis type=none},
+ no y axis/.style={y axis type=none},
+ no axes/.style={axes type=none},
rotate labels/.sseq is if=rotatelabels,
%
draw x ticks/.sseq is if=drawxaxisticks,
@@ -1377,62 +1609,135 @@
draw ticks/.default=true,
tick step/.sseq x y alias,
tick step/.value required,
- x tick step/.sseq store in=\sseq@xtickstep{1},
- y tick step/.sseq store in=\sseq@ytickstep{1},
+ x tick step/.sseq store positive int in=\sseq@xtickstep{1},
+ y tick step/.sseq store positive int in=\sseq@ytickstep{1},
+ tick offset/.sseq x y alias,
+ tick offset/.value required,
+ x tick offset/.sseq store int in=\sseq@xtickstepoffset{0},
+ y tick offset/.sseq store int in=\sseq@ytickstepoffset{0},
+ major tick step/.sseq x y alias,
+ x major tick step/.sseq store int in=\sseq@xmajortickstep{0},
+ y major tick step/.sseq store int in=\sseq@ymajortickstep{0},
+ minor tick step/.sseq x y alias,
+ x minor tick step/.sseq store int in=\sseq@xminortickstep{0},
+ y minor tick step/.sseq store int in=\sseq@yminortickstep{0},
x tick handler/.code={\def\sseq@xtickfn##1{#1}},
x tick handler/.sseq default code={\def\sseq@xtickfn@default##1{#1}},
y tick handler/.code={\def\sseq@ytickfn##1{#1}},
y tick handler/.sseq default code={\def\sseq@ytickfn@default##1{#1}},
- class label handler/.code = {\long\def\sseq@classlabeltextfn##1{#1}}, % \long so that \ifx\classlabeltextfn\@gobble compares true if this is empty (\@gobble is long...)
- class label handler/.sseq default code={\long\def\sseq@classlabeltextfn@default##1{#1}},
+ class label handler/.code = { % \long so that \ifx\classlabeltextfn\@gobble compares true if this is empty (\@gobble is long...)
+ \long\def\sseq@classlabeltextfn##1{#1}
+ \ifx\sseq@classlabeltextfn\@gobble
+ \def\sseq@classlabeltextfn##1{\def\processedlabel{##1}}
+ \else
+ \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabeltextfn{}}}
+ \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabeltextfn{blah}}}
+ \ifx\sseq@tempa\sseq@tempb
+ \long\def\sseq@classlabeltextfn##1{#1{##1}}
+ \fi
+ \fi
+ },
+ class label handler/.sseq default code={
+ \long\def\sseq@classlabeltextfn@default##1{#1}
+ \ifx\sseq@classlabeltextfn@default\@gobble
+ \def\sseq@classlabeltextfn@default##1{\def\processedlabel{##1}}
+ \else
+ \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabeltextfn@default{}}}
+ \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabeltextfn@default{blah}}}
+ \ifx\sseq@tempa\sseq@tempb
+ \long\def\sseq@classlabeltextfn@default##1{#1{##1}}
+ \fi
+ \fi
+ },
x tick style/.sseq store in=\sseq@xtickstyle{},
y tick style/.sseq store in=\sseq@ytickstyle{},
tick style/.sseq x y alias,
%
- x axis style/.is choice,
- y axis style/.is choice,
- axes style/.sseq x y alias=axis style,
- ~x axis style/border/.code={\sseq@drawxaxistrue\sseq@borderxaxistrue},
- ~y axis style/border/.code={\sseq@drawyaxistrue\sseq@borderyaxistrue},
- ~x axis style/center/.code={
- \sseq@drawxaxistrue\sseq@borderxaxisfalse
- \ifx\sseq@xaxisgap\sseq@xaxisgap@default
- \def\sseq@xaxisgap{0cm}
- \fi
- },
- ~y axis style/center/.code={\sseq@drawyaxistrue\sseq@borderyaxisfalse\ifx\sseq@yaxisgap\sseq@yaxisgap@default\def\sseq@yaxisgap{0cm}\fi},
- ~x axis style/none/.code={\sseq@drawxaxisfalse},
- ~y axis style/none/.code={\sseq@drawyaxisfalse},
- x axis origin/.sseq store in=\sseq@xaxisorigin{0},
- y axis origin/.sseq store in=\sseq@yaxisorigin{0},
+ axes type/.sseq x y alias=axis type,
+ axes type/.add code={\let\sseq@axistypesanitizer\sseq@axistypesanitizerb}{\let\sseq@axistypesanitizer\sseq@axistypesanitizera},
+ axes type/.value required,
+ x axis type/.sseq store in sanitize=\sseq@xaxistype{border}\sseq@axistypesanitizer,
+ x axis type/.value required,
+ y axis type/.sseq store in sanitize=\sseq@yaxistype{border}\sseq@axistypesanitizer,
+ y axis type/.value required,
+ x axis origin/.sseq store int in=\sseq@xaxisorigin@center@{0},
+ y axis origin/.sseq store int in=\sseq@yaxisorigin@center@{0},
axes origin/.sseq x y alias=axis origin,
}
+
+\def\sseq@validaxestypesa{border, center, or none. The value frame only works with the 'axes type' key.}
+\def\sseq@validaxestypesb{border, center, frame, or none.}
+\let\sseq@validaxestypes\sseq@validaxestypesa
+
+\let\sseq@axistypekeya\@firstofone
+\def\sseq@axistypekeyb#1{axes type}
+\let\sseq@axistypekey\sseq@axistypekeya
+
+\def\sseq@uptoequal#1{\sseq@uptoequal@#1\sseq@nil}
+\def\sseq@uptoequal@#1=#2\sseq@nil{#1}
+\def\sseq@axistypesanitizerb#1#2{
+ \let\sseq@validaxestypes\sseq@validaxestypesb
+ \let\sseq@axistypekey\sseq@axistypekeyb
+ \@xp\ifx\csname sseq@leftgridpadding@y#1\endcsname\relax
+ \sseq@error@xx{invalid-axis-type}{#1}{\sseq@uptoequal{#2}}
+ \sseq@breakfi
+ \else
+ \def\sseq@sanitize@output{#1}
+ \fi
+ \let\sseq@validaxestypes\sseq@validaxestypesa
+ \let\sseq@axistypekey\sseq@axistypekeya
+}
+
+\def\sseq@axistype@frame{frame}
+\def\sseq@axistypesanitizera#1#2{
+ \def\temp{#1}
+ \ifx\sseq@axistype@frame\temp
+ \sseq@error@xx{invalid-axis-type}{#1}{\sseq@uptoequal{#2}}
+ \sseq@breakfi
+ \fi
+ \sseq@axistypesanitizerb{#1}{#2}
+}
+\let\sseq@axistypesanitizer\sseq@axistypesanitizera
+
\pgfqkeys{/sseqpages}{%
- class label handler/.code = {\long\def\sseq@classlabeltextfn##1{#1}}
+ class label handler/.code = { % \long so that \ifx\classlabeltextfn\@gobble compares true if this is empty (\@gobble is long...)
+ \long\def\sseq@classlabeltextfn##1{#1}
+ \ifx\sseq@classlabeltextfn\@gobble
+ \def\sseq@classlabeltextfn##1{\def\processedlabel{##1}}
+ \else
+ \edef\sseq@tempa{\unexpanded\@xp{\sseq@classlabeltextfn{}}}
+ \edef\sseq@tempb{\unexpanded\@xp{\sseq@classlabeltextfn{blah}}}
+ \ifx\sseq@tempa\sseq@tempb
+ \long\def\sseq@classlabeltextfn##1{#1{##1}}
+ \fi
+ \fi
+ }
}
\sseq@globalkeys{
axes gap/.sseq x y alias=axis gap,
axes gap/.value required,
- x axis gap/.sseq store in=\sseq@xaxisgap{0.5cm},
- y axis gap/.sseq store in=\sseq@yaxisgap{0.5cm},
+ x axis gap/.sseq store dimen in=\sseq@xaxisgap{0.5cm},
+ y axis gap/.sseq store dimen in=\sseq@yaxisgap{0.5cm},
tick gap/.sseq x y alias,
tick gap/.value required,
- x tick gap/.sseq store in=\sseq@xlabelgap{0.5cm},
- y tick gap/.sseq store in=\sseq@ylabelgap{0.5cm},
- x axis extend start/.sseq store in=\sseq@xaxis@start@extend{0.9cm},
- y axis extend start/.sseq store in=\sseq@yaxis@start@extend{0.9cm},
+ x tick gap/.sseq store dimen in=\sseq@xlabelgap{0.5cm},
+ y tick gap/.sseq store dimen in=\sseq@ylabelgap{0.5cm},
+ x axis tail/.sseq store dimen in=\sseq@xaxis@tail{0.9cm},
+ y axis tail/.sseq store dimen in=\sseq@yaxis@tail{0.9cm},
+ x axis extend start/.sseq store dimen in=\sseq@xaxis@start@extend{0.5cm},
+ y axis extend start/.sseq store dimen in=\sseq@yaxis@start@extend{0.5cm},
axes extend start/.sseq x y alias=axis extend start,
- x axis extend end/.sseq store in=\sseq@xaxis@end@extend{0.5cm},
- y axis extend end/.sseq store in=\sseq@yaxis@end@extend{0.5cm},
+ x axis extend end/.sseq store dimen in=\sseq@xaxis@end@extend{0.5cm},
+ y axis extend end/.sseq store dimen in=\sseq@yaxis@end@extend{0.5cm},
axes extend end/.sseq x y alias=axis extend end,
- x axis clip padding/.sseq store in=\sseq@xclip@axisgap{0.1cm},
- y axis clip padding/.sseq store in=\sseq@yclip@axisgap{0.1cm},
+ x axis clip padding/.sseq store dimen in=\sseq@xclip@axisgap{0.1cm},
+ y axis clip padding/.sseq store dimen in=\sseq@yclip@axisgap{0.1cm},
axes clip padding/.sseq x y alias=axis clip padding,
- right clip padding/.sseq store in=\sseq@clip@padding@right{0.1cm},
- left clip padding/.sseq store in=\sseq@clip@padding@left{0.4cm},
- top clip padding/.sseq store in=\sseq@clip@padding@top{0.1cm},
- bottom clip padding/.sseq store in=\sseq@clip@padding@bottom{0.4cm}
+ right clip padding/.sseq store dimen in=\sseq@clip@padding@right{0.1cm},
+ left clip padding/.sseq store dimen in=\sseq@clip@padding@left{0.1cm},
+ top clip padding/.sseq store dimen in=\sseq@clip@padding@top{0.1cm},
+ bottom clip padding/.sseq store dimen in=\sseq@clip@padding@bottom{0.1cm}
}
%%%
@@ -1445,6 +1750,9 @@
\sseq@addtostorelist\sseq@globalrotatetransform{}
\sseq@addtostorelist\sseq@globalscaletransform{}
+\sseq@addtostorelist\sseq@xscale{1}
+\sseq@addtostorelist\sseq@yscale{1}
+
\def\sseq@globaldetoneoption#1#2{%
\ifsseq@globaldetone\else
\sseq@error@n{det-one-after-scale}{#2}
@@ -1454,7 +1762,7 @@
}
\def\sseq@globalscaleoption#1{%
\sseq@globaldetonefalse
- \@xp\gdef\@xp\sseq@globalscaletransform\@xp{\sseq@globalscaletransform#1}#1%
+ \@xp\gdef\@xp\sseq@globalscaletransform\@xp{\sseq@globalscaletransform#1}%
}
\pgfqkeys{/sseqpages/global}{%
x/.sseq @ illegal,
@@ -1481,28 +1789,44 @@
mirror/.forward to=/sseqpages/global/xmirror,
mirror/.forward to=/sseqpages/global/ymirror,
xscale/.code={%
- \pgfmathparse{int(#1-1)}%
- \ifnum\pgfmathresult<\z@%
+ \sseq@ifpgfmathexpr{int(#1-1)}{}{
+ \sseq@error@nn{invalid-scale}{x}{#1}%
+ \sseq@break
+ }
+ \ifpgfmathunitsdeclared
+ \sseq@error@nn{unit-scale}{x}{#1}%
+ \sseq@break
+ \fi
+ \ifnum\sseq@mathresult<\z@
\sseq@error@nn{negative-scale}{x}{#1}%
+ \sseq@break
\fi
- \sseq@globalscaleoption{\pgftransformxscale{#1}}%
+ \sseq@globalscaleoption{\pgfsetxvec{\pgfpointxy{#1}{0}}}
+ \pgfmathparse{\sseq@xscale*#1}
+ \edef\sseq@xscale{\pgfmathresult}
+ \sseq@breakpoint
},
xscale/.value required,
yscale/.code={%
- \pgfmathparse{int(#1-1)}%
- \ifnum\pgfmathresult<\z@
+ \sseq@ifpgfmathexpr{int(#1-1)}{}{
+ \sseq@error@nn{invalid-scale}{y}{#1}%
+ \sseq@break
+ }
+ \ifpgfmathunitsdeclared
+ \sseq@error@nn{unit-scale}{y}{#1}%
+ \sseq@break
+ \fi
+ \ifnum\sseq@mathresult<\z@
\sseq@error@nn{negative-scale}{y}{#1}%
+ \sseq@break
\fi
- \sseq@globalscaleoption{\pgftransformyscale{#1}}%
+ \sseq@globalscaleoption{\pgfsetyvec{\pgfpointxy{0}{#1}}}
+ \pgfmathparse{\sseq@yscale*#1}
+ \edef\sseq@yscale{\pgfmathresult}
+ \sseq@breakpoint
},
yscale/.value required,
- scale/.code={%
- \pgfmathparse{int(#1-1)}%
- \ifnum\pgfmathresult<\z@
- \sseq@error@nn{negative-scale}{}{#1}%
- \fi
- \sseq@globalscaleoption{\pgftransformscale{#1}}%
- },
+ scale/.sseq x y alias=#1scale,
scale/.value required
}
@@ -1520,11 +1844,11 @@
x/.code={\sseq@error@n{option-illegal}{#1}},
y/.code={\sseq@error@n{option-illegal}{#1}},
z/.code={\sseq@error@n{option-illegal}{#1}},
- xshift/.sseq @ second pass code={\sseq@shifttransform{x}{#1}}, % I don't know why it has to be this way,
- xshift/.sseq @ first pass append code={\sseq@firstpass@shifttransform{x}{#1}}, % but it definitely breaks if I change it...
+ xshift/.sseq @ first pass code=\sseq@tikz@firstpass@checkshifttransform{x}{#1},
+ yshift/.sseq @ first pass code=\sseq@tikz@firstpass@checkshifttransform{y}{#1},
+ xshift/.append code=\sseq@options@scopeshiftsecondpass{\sseq@tikz@shifttransform{x}{#1}},%% Note special scopeshiftsecondpass command
+ yshift/.append code=\sseq@options@scopeshiftsecondpass{\sseq@tikz@shifttransform{y}{#1}},%%
xshift/.value required,
- yshift/.sseq @ second pass code={\sseq@shifttransform{y}{#1}},
- yshift/.sseq @ first pass append code={\sseq@firstpass@shifttransform{y}{#1}},
yshift/.value required,
shift/.sseq @ transform, shift/.value required,
shift only/.sseq @ transform,
@@ -1541,7 +1865,6 @@
transform canvas/.sseq @ transform, transform canvas/.value required
}
-% These two should be exactly the same
\def\sseq@shift@firstpassprocess#1{\sseq@shift@firstpassprocess@#1\sseq@nil}
\def\sseq@shift@firstpassprocess@#1#2\sseq@nil{\ifx#1\pgfpointxy\sseq@shift@firstpassprocess@@#2\else\sseq@standardparse\fi}
\def\sseq@shift@firstpassprocess@@#1#2{
@@ -1556,6 +1879,15 @@
\sseq@tikz@shifttransform{y}{#2}
}
+% special second pass handler for scopes to prevent shifts from causing out of memory style errors,
+% see the longer comment at the definition of sseq@scope in main.code.tex
+\def\sseq@options@scopeshiftsecondpass{\sseq@options@secondpass}
+
+\sseq@pgfqkeysdirlist{/sseqpages/scope,/sseqpages/tikz primitives,/sseqpages,/sseqpages/label,/sseqpages/class/label}{
+ align/.sseq @ second pass code=\tikzset{align/#1},
+ align/.sseq @ first pass append code={\sseq@needstikztrue\def\sseq@classquotes@smugglehook@inner{\sseq@needstikztrue\tikzset{align/#1}}}
+}
+
\sseq@pgfqkeysdirlist{/sseqpages/scope,/sseqpages/tikz primitives}{
shift/.code={
\sseq@options@firstpass{\tikz@scan@one@point\sseq@shift@firstpassprocess#1\relax}
@@ -1563,8 +1895,8 @@
},
xshift/.sseq @ first pass code=\sseq@tikz@firstpass@checkshifttransform{x}{#1},
yshift/.sseq @ first pass code=\sseq@tikz@firstpass@checkshifttransform{y}{#1},
- xshift/.sseq @ second pass append code=\sseq@tikz@shifttransform{x}{#1},
- yshift/.sseq @ second pass append code=\sseq@tikz@shifttransform{y}{#1},
+ xshift/.append code=\sseq@options@scopeshiftsecondpass{\sseq@tikz@shifttransform{x}{#1}},%% Note special scopeshiftsecondpass command
+ yshift/.append code=\sseq@options@scopeshiftsecondpass{\sseq@tikz@shifttransform{y}{#1}},%%
rotate around/.sseq @ second pass code={\sseq@standardparse\sseq@pgfkeysdocommand{rotate}{#1}},
rotate/.sseq @ stdparse do transform, rotate/.value required,
xslant/.sseq @ stdparse do transform, xslant/.value required,
@@ -1589,7 +1921,7 @@
\let\sseq@firstpass@shifttransform\sseq@firstpass@checkshifttransform
\def\sseq@checkshifttransform#1#2{%
- \pgfmathparse{#2}%
+ \pgfmathparse{(#2)}%
\sseq@ifpgfmathresultisunitlessint{%
\@xp\pgfmathint\@xp{\pgfmathresult}%
\@xp\advance\csname sseq@#1\endcsname\pgfmathresult\relax
@@ -1619,7 +1951,7 @@
\sseq@ifpgfmathresultisunitlessint{%
\@xp\pgfmathint\@xp{\pgfmathresult}%
\@xp\advance\csname sseq@\sseq@getfirstchar#1\sseq@nil\endcsname\pgfmathresult\relax
- \sseq@pgfkeysdocommand{#1shift}{#2cm}
+ \sseq@pgfkeysdocommand{#1shift}{#2cm*\csname sseq@#1scale\endcsname}
}{
\sseq@standardparse
\ifpgfmathunitsdeclared