diff options
author | Norbert Preining <norbert@preining.info> | 2021-06-16 03:01:15 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2021-06-16 03:01:15 +0000 |
commit | 2c0c7988beae1efa245bfb9fec0a25d41d88047d (patch) | |
tree | eb29ed898d242ae356a592081c53f11dbd751870 /graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex | |
parent | 2faf2507ca4d1d6d153f4c2b4c4c78479d459f06 (diff) |
CTAN sync 202106160301
Diffstat (limited to 'graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex')
-rw-r--r-- | graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex b/graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex index ac87e08304..86732077b0 100644 --- a/graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex +++ b/graphics/pgf/contrib/circuitikz/tex/pgfcircutils.tex @@ -120,4 +120,261 @@ } \long\def\ctikzsubcircuitactivate#1{\csname #1@setanchors\endcsname} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Basic utility macros +%% +%% Functions provided here are: +%% \pgf@circ@ifempty{<argument>}{<true>}{<false>} +%% Tests whether <argument> is completely empty. +%% \pgf@circ@ifblank{<argument>}{<true>}{<false>} +%% Tests whether <argument> is either empty or only contains spaces. +%% \pgf@circ@trimspaces@do{<argument>}{<next>} +%% Trims at most one space from either end of <argument> and forwards the +%% result to <next> as <next>{<trimmed argument>} + +% these two are pretty standard code +\long\def\pgf@circ@ifempty#1% + {% + \if\relax\detokenize{#1}\relax + \expandafter\pgfutil@firstoftwo + \else + \expandafter\pgfutil@secondoftwo + \fi + } +\long\def\pgf@circ@ifblank#1% + {% + \if\relax\detokenize\expandafter{\pgfutil@gobble#1.}\relax + \expandafter\pgfutil@firstoftwo + \else + \expandafter\pgfutil@secondoftwo + \fi + } + +% \pgfutil@trimspaces needs two expansions. The first expansion we'll do during +% the definition. +\def\pgf@circ@trimspaces@do#1% + {% + \def\pgf@circ@trimspaces@do##1% + {\expandafter\pgf@circ@trimspaces@do@\expandafter{#1}}% + } +\expandafter\pgf@circ@trimspaces@do\expandafter{\pgfutil@trimspaces{#1}} +\def\pgf@circ@trimspaces@do@#1#2{#2{#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% list handling +%% +%% Contribution by Jonathan P. Spratte (blame him!) +%% +%% The list implementation here has a few limitations. Those are: +%% 1. not long, so no \par in the lists (but many used functions in pgfutil +%% aren't long as well) +%% 2. list elements can't contain a Q with category code 3 (but the used +%% function \pgfutil@trimspaces doesn't support them as well, and this +%% should be a very rare token anyway) +%% 3. list elements can't contain the token \pgf@circ@set@list as that is used +%% as the end marker +%% 4. currently these lists are meant for numeric data (hence only +%% \pgf@circ@if@num@in@list is provided as a test), as a result there is +%% another limitation for the data here. If the list element contains no +%% hyphen '-', the element will be stored without further processing +%% 'as-is' (well, after trimming spaces). If there is a hyphen we assume +%% well-behaved input data and will interpret this as a num-range without +%% further tests. +%% +%% Functions provided here are: +%% \pgf@circ@set@list<macro>{<csv-list>} +%% Parses the <csv-list> and stores the result inside <macro> (local +%% assignment). If a num-range given as <start - stop> (with or without +%% spaces) is found it will be expanded to <start>,<start+1>,...,<stop>. +%% \pgf@circ@if@num@in@list<macro>{<value>}{<true>}{<false>} +%% Checks whether <value> (numeric value, evaluated once with \numexpr) is +%% found inside the list stored in <macro>. There are two special cases: If +%% <macro> is undefined <false> is executed. If the list contains only one +%% element and that is `all' <true> is executed. + +% set the catcode of our marker +\chardef\pgf@circ@temp=\the\catcode`\Q +\catcode`\Q=3 + +% lists will have the structure +% <marker><element 1><marker>...<element n><marker> +% As marker we use a Q with category 3. Under the assumption that no list +% element does ever contain that token we can set the elements without braces, +% allowing us to use \pgfutil@in@ to search for elements (see above). The other +% token that isn't allowed to show up in the list is \pgf@circ@set@list, that we +% use as another marker during parsing. +% The other big restriction in this implementation is that lists can't contain a +% \par (but \pgfutil@in@ doesn't support that anyway so there is not much +% sense in supporting it here) +\pgfutil@protected\def\pgf@circ@set@list#1#2% + {% + % clear the error flag + \let\pgf@circ@error@marker\pgf@circ@undefined + % set the list + \edef#1% + {Q\pgf@circ@set@list@sanitize#2,\pgf@circ@set@list,\pgf@circ@set@list}% + % there was an error, throw the error message, recovery was already done by + % ignoring the offending elements. + \ifx\pgf@circ@error@marker\relax + \begingroup + \newlinechar`\^^J + \pgfutil@packageerror{circuitikz} + {% + Unallowed marker found in list^^J% + \pgfutil@unexpanded{#2}.^^J% + Offending elements were ignored.% + } + {Lists can't contain a Q with category code 3}% + \endgroup + \fi + } +% just a utility for the <marker> test +\def\pgf@circ@set@list@gobbletomarker#1Q{} +% quick way to check whether list parsing is done by gobbling up to a marker, in +% this case the marker is \pgf@circ@set@list +\def\pgf@circ@set@list@sanitize@checkend#1\pgf@circ@set@list{} +% will only be called after the last element is handled, will gobble the +% remainder of the current sanitizing step +\def\pgf@circ@set@list@sanitize@end\pgf@circ@set@list#1\pgf@circ@set@list{} +% grabs the next list element, checks whether we're done, and if not sanitizes +% it (meaning stripping spaces from either end and placing the <marker>). +\def\pgf@circ@set@list@sanitize#1,% + {% + \pgf@circ@set@list@sanitize@checkend + #1\pgf@circ@set@list@sanitize@end\pgf@circ@set@list + \pgf@circ@set@list@sanitize@a{#1}% + } +% testing whether a list element contains the used <marker> expandably, if it +% does set the flag, else continue sanitizing. +\def\pgf@circ@set@list@sanitize@a#1% + {% + \expandafter\pgf@circ@ifempty\expandafter + % if this is empty no marker was found + {\pgf@circ@set@list@gobbletomarker#1Q} + {% + \pgf@circ@ifblank{#1} + {}% ignore blank entries + {\pgf@circ@trimspaces@do{#1}\pgf@circ@set@list@sanitize@b}% + } + {% + % panic, there was a marker found in a list element. We'll recover by + % ignoring the current element after setting a flag. When we do + % \csname ...\endcsname on an undefined macro name TeX will let that + % macro to relax and we exploit this to expandable set a flag and + % gobbling the result. + \expandafter\pgfutil@gobble\csname pgf@circ@error@marker\endcsname + }% + % get the next element + \pgf@circ@set@list@sanitize + } +% we'll protect any element from further expanding using \unexpanded and place +% the marker after the element, and ignore empty/blank elements +\def\pgf@circ@set@list@sanitize@b#1% + {% + \expandafter\pgf@circ@ifempty\expandafter + % if this is empty no hyphen is found + {\pgf@circ@gobbletohyphen#1-} + {\pgfutil@unexpanded{#1}Q} + {\pgf@circ@set@list@parse@range{#1}}% + } +\def\pgf@circ@gobbletohyphen#1-{} +\def\pgf@circ@set@list@parse@range#1{\pgf@circ@set@list@parse@range@a#1Q} +\def\pgf@circ@set@list@parse@range@a#1-#2Q% + {% + \expandafter\pgf@circ@set@list@parse@range@b + \the\numexpr#1\expandafter Q\the\numexpr#2Q% + } +\def\pgf@circ@set@list@parse@range@b#1Q#2Q% + {% + \ifnum#1<#2 + % expand to the range from #1 to #2 (inclusive) + \pgf@circ@set@list@range{#1}{#2}% + \else + \ifnum#2<#1 + % if #2 is smaller than #1 just swap the order + \pgf@circ@set@list@range{#2}{#1}% + \else + % last case, they are equal, so just put the result here + #1Q% + \fi + \fi + } +\def\pgf@circ@set@list@parse@range@norange#1Q#2{\pgfutil@unexpanded{#2}Q} +\def\pgf@circ@set@list@range#1#2% + {% + #1Q% + \ifnum#1<#2 + \expandafter\pgfutil@secondoftwo + \fi + \pgfutil@gobble + {\expandafter\pgf@circ@set@list@range\expandafter{\the\numexpr#1+1}{#2}}% + } + +% flag for special value +\def\pgf@circ@all@flag{QallQ} +\pgfutil@protected\def\pgf@circ@if@num@in@list#1#2% + {% + % test whether the list macro is defined, if it isn't result is false + \pgfutil@ifx\pgf@circ@undefined#1% + {\pgfutil@secondoftwo} + {% + % test whether the list macro is just the special value 'all', if so + % true, else search (and start that by evaluating a numexpr) + \pgfutil@ifx\pgf@circ@all@flag#1% + {\pgfutil@firstoftwo} + {% + \expandafter\pgf@circ@if@num@in@list@a\expandafter + {\the\numexpr#2}% + #1% + }% + }% + } +% next step is expanding the list macro +\pgfutil@protected\def\pgf@circ@if@num@in@list@a#1#2% + {\expandafter\pgf@circ@if@num@in@list@b\expandafter{#2}{#1}} +% now use \pgfutil@in@ to check whether there is the searched list element +\pgfutil@protected\def\pgf@circ@if@num@in@list@b#1#2% + {% + \begingroup + % put the <marker> around the number to make sure only full matches are + % found. \pgfutil@in@ will set \ifpgfutil@in@ to true if it finds a match + \pgfutil@in@{Q#2Q}{#1}% + \expandafter + \endgroup + \ifpgfutil@in@ + \expandafter\pgfutil@firstoftwo + \else + \expandafter\pgfutil@secondoftwo + \fi + } + +% reset the catcode of Q +\catcode`\Q=\pgf@circ@temp + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% temporary fix for old TikZ versions (remove me) +%% +%% All blame to Romano Giannetti for this code! +%% +%% This tries to be smart and provide \pgfutil@unexpanded and \pgfutil@ifx if +%% PGF doesn't provide them. + +\ifx\pgfutil@unexpanded\pgf@circ@undefined + \ifpgfutil@format@is@context + \let\pgfutil@unexpanded\normalunexpanded + \else + \let\pgfutil@unexpanded\unexpanded + \fi +\fi + +\ifx\pgfutil@ifx\pgf@circ@undefined + \long\def\pgfutil@ifx#1#2{% + \ifx#1#2% + \expandafter\pgfutil@firstoftwo + \else + \expandafter\pgfutil@secondoftwo + \fi} +\fi + \endinput |