%% file: tzplot.sty %% %% tzplot %% %% (C) Copyright 2017-2021 In-Sung Cho %% %% This work may be distributed and/or modified %% under the conditions of the LaTeX Project Public License, %% either version 1.3c of this license or (at your option) any later version. %% The latest version of this license is in %% http://www.latex-project.org/lppl.txt. %% %% ------------------------------------------------- \ProvidesPackage{tzplot-v1.0}[2021/02/28 v1.0 Plot Graphs with TikZ Abbreviations] % expl3,xparse: LPPL % tikz: LPPL and/or GNU GPL \RequirePackage{expl3,xparse} \RequirePackage{tikz} \usetikzlibrary{ calc,backgrounds,positioning,intersections, arrows,shapes,patterns, plotmarks, % for \tzplot[mark] decorations.pathreplacing, % for tzshowcontrols/show path construction, tzbrace calligraphy, % for calligraphic brace (load after decorations.pathreplacing) } %% backgrounds \pgfdeclarelayer{background} \pgfdeclarelayer{behind} \pgfdeclarelayer{above} \pgfdeclarelayer{foreground} \pgfsetlayers{background,behind,main,above,foreground} %% usage: \begin{pgfonlayer}{foreground} ... \end{pgfonlayer} %%%%% defaults \def\tz@default@radius{1.2pt} % fixed \def\tz@initial@radius{\tz@default@radius} % changeable \NewDocumentCommand\settzdotradius{m}{\renewcommand\tz@initial@radius{#1}} \newcommand\tzdotradius{\tz@initial@radius} % circle dot (using radius) \def\tz@default@Cdot@radius{1.2pt} % fixed \def\tz@initial@Cdot@radius{\tz@default@Cdot@radius} % changeable \NewDocumentCommand\settzcdotradius{m}{\renewcommand\tz@initial@Cdot@radius{#1}} \newcommand\tzCdotradius{\tz@initial@Cdot@radius} % node dot (using minimum size) \def\tz@default@dot@size{2.4pt} % fixed \def\tz@initial@dot@size{\tz@default@dot@size} % changeable \NewDocumentCommand\settzdotsize{m}{\renewcommand\tz@initial@dot@size{#1}} \newcommand\tzdotsize{\tz@initial@dot@size} % mark (using mark size, which is a radius) % tikz initial = 2pt \def\tz@default@mark@size{2pt} % fixed \def\tz@initial@mark@size{\tz@default@mark@size} % changeable \NewDocumentCommand\settzmarksize{m}{\renewcommand\tz@initial@mark@size{#1}} \newcommand\tzmarksize{\tz@initial@mark@size} % opacity \def\tz@default@fill@opacity{0.3} % fixed \def\tz@initial@fill@opacity{\tz@default@fill@opacity} % changeable \NewDocumentCommand\settzfillopacity{m}{\renewcommand\tz@initial@fill@opacity{#1}} \newcommand\tzfillopacity{\tz@initial@fill@opacity} % fillcolor \def\tz@default@fill@color{black!50} % fixed \def\tz@initial@fill@color{\tz@default@fill@color} % changeable \NewDocumentCommand\settzfillcolor{mg} {% \renewcommand\tz@initial@fill@color{#1} \IfValueT {#2} {\renewcommand\tz@initial@fill@opacity{#2}} } \newcommand\tzfillcolor{\tz@initial@fill@color} % link style \def\tz@default@link@style{to} % fixed \def\tz@initial@link@style{\tz@default@link@style} % changeable \NewDocumentCommand\settzlinkstyle{m}{\renewcommand\tz@initial@link@style{#1}} \newcommand\tzlinkstyle{\tz@initial@link@style} % path style \def\tz@default@path@style{to} % fixed \def\tz@initial@path@style{\tz@default@path@style} % changeable \NewDocumentCommand\settzpathstyle{m}{\renewcommand\tz@initial@path@style{#1}} \newcommand\tzpathstyle{\tz@initial@path@style} % tangent epsilon \def\tz@default@tangent@epsilonL{.01} \def\tz@default@tangent@epsilonR{.01} \def\tz@initial@tangent@epsilonL{\tz@default@tangent@epsilonL} \def\tz@initial@tangent@epsilonR{\tz@default@tangent@epsilonL} \NewDocumentCommand\settztangentepsilon{mg} {% \renewcommand\tz@initial@tangent@epsilonL{#1} \IfNoValueTF {#2} {\renewcommand\tz@initial@tangent@epsilonR{#1}} {\renewcommand\tz@initial@tangent@epsilonR{#2}} } \newcommand\tztangentepsilonL{\tz@initial@tangent@epsilonL} \newcommand\tztangentepsilonR{\tz@initial@tangent@epsilonR} \let\tztangentatepsilonL\tztangentepsilonL \let\tztangentatepsilonR\tztangentepsilonR % tzpath layer %% (NOT USED!!!) (to be considered later) \def\tz@default@tzpath@layer{main} % fixed \def\tz@initial@tzpath@layer{\tz@default@tzpath@layer} % changeable \NewDocumentCommand\settzpathlayer{m}{\renewcommand\tz@initial@tzpath@layer{#1}} \newcommand\tzpathlayer{\tz@initial@tzpath@layer} % tangent layer \def\tz@default@tangent@layer{behind} % fixed \def\tz@initial@tangent@layer{\tz@default@tangent@layer} % changeable \NewDocumentCommand\settztangentlayer{m}{\renewcommand\tz@initial@tangent@layer{#1}} \newcommand\tztangentlayer{\tz@initial@tangent@layer} \let\tztangentatlayer\tztangentlayer % secant layer \def\tz@default@secant@layer{behind} % fixed \def\tz@initial@secant@layer{\tz@default@secant@layer} % changeable \NewDocumentCommand\settzsecantlayer{m}{\renewcommand\tz@initial@secant@layer{#1}} \newcommand\tzsecantlayer{\tz@initial@secant@layer} \let\tzsecantatlayer\tzsecantlayer %%%%% TikZ alias styles \tikzset{ a/.style={above=#1}, b/.style={below=#1}, c/.style={centered=#1}, l/.style={left=#1}, r/.style={right=#1}, al/.style={above left=#1}, ar/.style={above right=#1}, bl/.style={below left=#1}, br/.style={below right=#1}, } %%%%% tzplot styles \tikzset{>=stealth} % to revert use {>=to} %% tzdot (for node dot style) \tikzset{ tzdot/.style= {draw,solid,thin,circle,inner sep=0pt,minimum size=#1}, tzdot/.default=\tzdotsize } %% tzdot options (for node dot style) \tikzset{ tzdot options/.style={tzdot=\tzdotsize,#1} } %% tzmark \tikzset{ tzmark/.style= {mark options={solid,thin},mark size=#1}, tzmark/.default=\tzmarksize } %% tznode (NOT USED!) -- user choice \tikzset{ tznode/.style= {solid,thin,circle,inner sep=0pt,minimum size=#1}, tznode/.default=0pt } %% tzdotted \tikzset{% tzdotted/.style={% dotted=none, line cap=round, dash pattern=on 0pt off 1cm/(#1) }, tzdotted/.default=10 } %% tzdashed \tikzset{ tzdashed/.style={% dashed=none, dash pattern=on 5mm/(#1) off 5mm/(#1) }, tzdashed/.default=10 } %% tzhelplines \tikzset{% tzhelplines/.style={help lines,-,tzdotted} } %% tzshorten \tikzset{% tzshorten/.style 2 args ={shorten <=#1, shorten >=#2}, tzshoretn/.default={2pt}{2pt} } %% tzextend (negative tzshorten) \tikzset{% tzextend/.style 2 args ={shorten <=-#1, shorten >=-#2}, tzextend/.default={2pt}{2pt} } %% tzshowcontrols % (for \tzbezier: tikz manual p.645) \tikzset{% tzshowcontrols/.style={% postaction={% decoration={% show path construction, curveto code={% \draw [dotted,#1] (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta) -- (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast); } }, decorate } } } %===================================================== %%===================================================== %%===================================================== \ExplSyntaxOn %%===================================================== %%===================================================== %%%%% help lines \NewDocumentCommand\tzhelplines{ s O{} r() d() } { \IfBooleanTF { #1 } { \IfNoValueTF { #4 } { \draw [ tzhelplines , use~as~bounding~box , #2 ] (0,0) grid (#3); } { \draw [ tzhelplines , use~as~bounding~box , #2 ] (#3) grid (#4); } } { \IfNoValueTF { #4 } { \draw [ tzhelplines , #2 ] (0,0) grid (#3); } { \draw [ tzhelplines , #2 ] (#3) grid (#4); } } } %%%%% \tzbbox \NewDocumentCommand\tzbbox{ r() d() } { \IfNoValueTF { #2 } { \useasboundingbox (0,0) rectangle (#1); } { \useasboundingbox (#1) rectangle (#2); } } %%%%% \tzgetxyval \NewDocumentCommand\tzgetxyval{ r() m m } { \tikz@scan@one@point\pgfutil@firstofone(#1)\relax% \pgfmathparse{\the\pgf@x/28.45274}% convert pt to cm \edef#2{\pgfmathresult}% \pgfmathparse{\the\pgf@y/28.45274}% convert pt to cm \edef#3{\pgfmathresult}% } %%% --- end of \tzgetxyval %%%%%% \tzgetxyval (experimental) %%%%%% seems not working %\NewDocumentCommand\tzgetxyval{ g r() m m } %{ % \IfNoValueTF { #1 } % { % \def\tzptToDim{28.45274} % cm: default % } % { % \str_case:nnTF { #1 } % { % {pt} { \def\tzptToDim{1} } % {mm} { \def\tzptToDim{2.845274} } % {cm} { \def\tzptToDim{28.45274} } % {bp} { \def\tzptToDim{1.00374} } % {dd} { \def\tzptToDim{1.07} } % {pc} { \def\tzptToDim{12} } % {in} { \def\tzptToDim{72.26999} } % } % { % \def\tzptToDim{1} % default unit in tikz % } % } % \tikz@scan@one@point\pgfutil@firstofone(#2)\relax% % \pgfmathparse{\the\pgf@x/\tzptToDim}% convert pt to dim % \edef#3{\pgfmathresult}% % \pgfmathparse{\the\pgf@y/\tzptToDim}% convert pt to dim % \edef#4{\pgfmathresult}% %} % %%%% --- end of \tzgetxyval %%%%% Dots %%% Node Dots %%% (basic: using minimum size) %%% \tzdot %%% *[opt](coor){text}[pos,opt](size) \bool_new:N \l_tzdot_shift_coor_bool \NewDocumentCommand\tzdot{ s O{} d<> r() +G{} O{} D(){\tz@initial@dot@size} } { \tl_clear:N \l_tzdot_cmd_tl \IfValueT { #7 } { \renewcommand\tzdotsize{ #7 } } \IfValueTF { #3 } { \tl_set:Nn \l_tzdot_shift_coor_tl { #3 } \bool_set_true:N \l_tzdot_shift_coor_bool } { \tl_clear:N \l_tzdot_shift_coor_tl \bool_set_false:N \l_tzdot_shift_coor_bool } \bool_if:NTF \l_tzdot_shift_coor_bool { \tl_put_right:Nx \l_tzdot_cmd_tl { ( [ shift = { (\l_tzdot_shift_coor_tl) } ]#4 ) node } } { \tl_put_right:Nn \l_tzdot_cmd_tl { (#4) node } } \IfBooleanTF { #1 } { \tl_put_right:Nn \l_tzdot_cmd_tl { [ tzdot , fill , } } { \tl_put_right:Nn \l_tzdot_cmd_tl { [ tzdot , } } \tl_put_right:Nx \l_tzdot_cmd_tl { label = { \exp_not:n { #6 } \c_colon_str \exp_not:n { #5 } } , } \tl_put_right:Nn \l_tzdot_cmd_tl { minimum~size = \tzdotsize , #2 ] {} } \exp_last_unbraced:Nf \path \l_tzdot_cmd_tl ; } %%% --- end of \tzdot %%% multiple dots %%% coding CAUTION! : _tzdot_ changed to _tzdots_ %%% \tzdots %%% repeat pattern: (coor){label}[pos] \tl_new:N \l_tzdots_opt_tl \tl_new:N \l_tzdots_cmd_tl \bool_new:N \l_tzdots_shift_coor_bool \NewDocumentCommand\tzdots{ s O{} d<> } { \tl_clear:N \l_tzdots_cmd_tl \IfBooleanTF { #1 } { \tl_set:Nn \l_tzdots_STYLE_fill_tl { fill } } { \tl_set:Nn \l_tzdots_STYLE_fill_tl { fill = none } } \tl_if_empty:nTF { #2 } { \tl_set:Nn \l_tzdots_opt_tl { tzdot } } { \tl_set:Nn \l_tzdots_opt_tl { tzdot , #2 } } \IfValueTF { #3 } { \tl_set:Nn \l_tzdots_shift_coor_tl { #3 } \bool_set_true:N \l_tzdots_shift_coor_bool } { \tl_clear:N \l_tzdots_shift_coor_tl \bool_set_false:N \l_tzdots_shift_coor_bool } \tzdots_check_token:n } \cs_new:Npn \tzdots_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzdots_sub_fn #1 } % { \tzdots_stop_action } \str_case:nnF { #1 } { { ( } { \tzdots_sub_fn #1 } { ; } { \tzdots_late_opt_fn } } { \tzdots_stop_action } } \NewDocumentCommand\tzdots_sub_fn { r() +G{} O{} } { \bool_if:NTF \l_tzdots_shift_coor_bool { \tl_put_right:Nx \l_tzdots_cmd_tl {% if shift ( [ shift = { (\l_tzdots_shift_coor_tl) } ]#1 ) } } { \tl_put_right:Nn \l_tzdots_cmd_tl { (#1) } } \tl_put_right:Nx \l_tzdots_cmd_tl { node [ \l_tzdots_STYLE_fill_tl , minimum~size = \exp_not:n { \tzdotsize } , label = { \exp_not:n { #3 } \c_colon_str \exp_not:n { #2 } } , } \tl_put_right:No \l_tzdots_cmd_tl % expand `once' { \l_tzdots_opt_tl ] {} } \tzdots_check_token:n } \NewDocumentCommand\tzdots_late_opt_fn { D(){\tz@initial@dot@size} } { \renewcommand\tzdotsize{ #1 } \tzdots_stop_action } \NewDocumentCommand\tzdots_stop_action {} { \exp_last_unbraced:Nf \path \l_tzdots_cmd_tl ; } %%% --- end of \tzdots %%%%% Circle Dots -- (code original, using radius) \keys_define:nn { keytzCdot } { tzcdot .tl_set:N = \key_tzCdot_radius_tl } %% (keep) %% \tzcdot --- circle dot (original) %%% *[](coor){label}[angle](radius) \clist_new:N \l_tzCdot_opt_clist \bool_new:N \l_tzCdot_shift_coor_bool \NewDocumentCommand\tzcdot{ s o d<> r() +G{} O{} d() } { \tl_clear:N \l_tzCdot_opt_tl % (needed) \tl_clear:N \l_tzCdot_cmd_tl % default dot radius == arg specifier D<>{\tz@initial@radius} \renewcommand\tzCdotradius{\tz@initial@Cdot@radius} \IfValueT { #7 } { \renewcommand\tzCdotradius{ #7 } } \IfBooleanTF { #1 } { \tl_set:Nn \l_tzCdot_fill_tl { fill , solid, thin } } { \tl_set:Nn \l_tzCdot_fill_tl { solid , thin } } \IfValueTF { #3 } { \tl_set:Nn \l_tzCdot_shift_coor_tl { #3 } \bool_set_true:N \l_tzCdot_shift_coor_bool } { \tl_clear:N \l_tzCdot_shift_coor_tl \bool_set_false:N \l_tzCdot_shift_coor_bool } \IfNoValueTF { #2 } { \tl_clear:N \l_tzCdot_opt_tl % arg specifier O{} } { \clist_clear:N \l_tzCdot_opt_tested_clist \clist_set:Nn \l_tzCdot_opt_input_clist { #2 } \clist_map_inline:Nn \l_tzCdot_opt_input_clist { \str_if_in:nnTF { ##1 } { tzcdot } { % (matched item) \clist_pop:NN \l_tzCdot_opt_input_clist \l_tmpa_tl \keys_set:nV { keytzCdot } \l_tmpa_tl % form: { tzcdot=\l_tmpa_tl } \exp_args:NNo \renewcommand\tzCdotradius { \key_tzCdot_radius_tl } \clist_map_break: % non-tested list remains } { % (tested items -> list) \clist_pop:NN \l_tzCdot_opt_input_clist \l_tmpb_tl \clist_put_right:NV \l_tzCdot_opt_tested_clist \l_tmpb_tl } } \clist_concat:NNN \l_tzCdot_opt_clist \l_tzCdot_opt_tested_clist % tested list \l_tzCdot_opt_input_clist % remained list \clist_if_empty:NF \l_tzCdot_opt_clist { % expand x needed \tl_set:Nx \l_tzCdot_opt_tl { \clist_use:Nn \l_tzCdot_opt_clist {,} } } } \tl_put_right:Nx \l_tzCdot_cmd_tl { [ \l_tzCdot_fill_tl , } \tl_put_right:No \l_tzCdot_cmd_tl % expand `once' { \l_tzCdot_opt_tl ] } \bool_if:NTF \l_tzCdot_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzCdot_cmd_tl { ( [ shift = { (\l_tzCdot_shift_coor_tl) } ]#4 ) } } { \tl_put_right:Nn \l_tzCdot_cmd_tl { ( #4 ) } } % no shift (normal) \tl_put_right:Nn \l_tzCdot_cmd_tl { circle ( \tzCdotradius ) } \tl_put_right:Nx \l_tzCdot_cmd_tl { node [ inner~sep = 0pt , label = { \exp_not:n { #6 } \c_colon_str \exp_not:n { #5 } } ] {} } \exp_last_unbraced:No \draw \l_tzCdot_cmd_tl ; } %%% --- end of \tzcdot %%% multiple dots %%% coding CAUTION! : _tzCdot_ changes to _tzCdots %%% *[] (){}[] (){}[] repeated (){}[] ; (radius) %%% repeat pattern: (coor){label}[angle] \clist_new:N \l_tzCdots_opt_clist \bool_new:N \l_tzCdots_size_call_bool \bool_new:N \l_tzCdots_shift_coor_bool \NewDocumentCommand\tzcdots{ s o d<> } { \renewcommand\tzCdotradius{\tz@initial@Cdot@radius} \tl_clear:N \l_tzCdots_opt_tl % (needed) \tl_clear:N \l_tzCdots_cmd_tl \IfBooleanTF { #1 } { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzCdots_shift_coor_tl { #3 } \bool_set_true:N \l_tzCdots_shift_coor_bool } { \tl_clear:N \l_tzCdots_shift_coor_tl \bool_set_false:N \l_tzCdots_shift_coor_bool } \IfNoValueTF { #2 } { \tl_clear:N \l_tzCdots_opt_tl % arg specifier O{} } { \clist_clear:N \l_tzCdots_opt_tested_clist \clist_set:Nn \l_tzCdots_opt_input_clist { #2 } \clist_map_inline:Nn \l_tzCdots_opt_input_clist { \str_if_in:nnTF { ##1 } { tzcdot } { \clist_pop:NN \l_tzCdots_opt_input_clist \l_tmpa_tl \keys_set:nV { keytzCdot } \l_tmpa_tl \exp_args:NNo \renewcommand\tzCdotradius { \key_tzCdot_radius_tl } \bool_set_true:N \l_tzCdots_size_call_bool \clist_map_break: } { \clist_pop:NN \l_tzCdots_opt_input_clist \l_tmpb_tl \clist_put_right:NV \l_tzCdots_opt_tested_clist \l_tmpb_tl } } \clist_concat:NNN \l_tzCdots_opt_clist \l_tzCdots_opt_tested_clist \l_tzCdots_opt_input_clist \clist_if_empty:NF \l_tzCdots_opt_clist { \tl_set:Nx \l_tzCdots_opt_tl { \clist_use:Nn \l_tzCdots_opt_clist {,} } } } \tzCdots_check_token:n } \cs_new:Npn \tzCdots_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzCdots_sub_fn #1 } % { \tzCdots_stop_action } \str_case:nnF { #1 } { { ( } { \tzCdots_sub_fn #1 } { ; } { \tzCdots_late_opt_fn } } { \tzCdots_stop_action } } \NewDocumentCommand\tzCdots_sub_fn { r() +G{} O{} } { \bool_if:NTF \l_tzCdots_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzCdots_cmd_tl { ( [ shift = { (\l_tzCdots_shift_coor_tl) } ]#1 ) circle (\tzCdotradius) } } {% no shift (normal) \tl_put_right:Nn \l_tzCdots_cmd_tl { (#1) circle (\tzCdotradius) } } \tl_put_right:Nx \l_tzCdots_cmd_tl { node [ inner~sep = 0pt , label = { \exp_not:n { #3 } \c_colon_str \exp_not:n { #2 } } ] {} } \tzCdots_check_token:n } \NewDocumentCommand\tzCdots_late_opt_fn { d() } { \IfValueT { #1 } { \bool_if:NF \l_tzCdots_size_call_bool { \renewcommand\tzCdotradius { #1 } } } \tzCdots_stop_action } \NewDocumentCommand\tzCdots_stop_action {} { \tl_if_empty:NTF \l_tzCdots_opt_tl { \tl_put_left:Nn \l_tzCdots_cmd_tl { ] } } { \tl_put_left:No \l_tzCdots_cmd_tl { \l_tzCdots_opt_tl ] } % expand `once' } \bool_if:NTF \l_tmpa_bool { \tl_put_left:Nn \l_tzCdots_cmd_tl { [ fill , solid , thin , } } { \tl_put_left:Nn \l_tzCdots_cmd_tl { [ solid , thin , } } \exp_last_unbraced:Nf \draw \l_tzCdots_cmd_tl ; \bool_set_false:N \l_tzCdots_size_call_bool } %%% --- end of \tzcdots %%% \tzshoworigin (node text and dot at the origin) \NewDocumentCommand\tzshoworigin { s O{} d<> D(){0,0} +g O{} D(){\tz@initial@dot@size} } { \IfValueTF { #5 } {% if shift \IfValueTF { #3 } { \path [ shift = {(#3)} ] (#4) node [ text~height = 1.25ex , text~depth=.25ex , below~left , #6 ] { #5 } ; \IfBooleanT { #1 } { \tzdot* [ #2 ] ([shift={(#3)}] #4) (#7) } } {% no shift \path (#4) node [ text~height = 1.25ex , text~depth=.25ex , below~left , #6 ] { #5 } ; \IfBooleanT { #1 } { \tzdot* [ #2 ] (#4) (#7) } } } { \IfValueTF { #3 } {% if shift \IfBooleanTF { #1 } { \tzdot* [ #2 ] ([shift={(#3)}] #4) (#7) } { \path [ shift = {(#3)} ] (#4) node [ text~height = 1.25ex , text~depth=.25ex , below~left , #6 ] { 0 } ; } } {% no shift \IfBooleanTF { #1 } { \tzdot* [ #2 ] (#4) (#7) } { \path (#4) node [ text~height = 1.25ex , text~depth=.25ex , below~left , #6 ] { 0 } ; } } } } %%% --- end of \tzshoworigin %%%%% Coordinates %%% \tzcoor()(){label}[pos] \NewDocumentCommand\tzcoor{ s O{} d<> r() r() +G{} O{} D(){\tz@initial@dot@size} } { \tl_clear:N \l_tzcoor_cmd_tl \IfBooleanTF { #1 } { \IfValueTF { #3 } { \path ([shift={(#3)}]#4) coordinate (#5) ; \tzdot*[#2]([shift={(#3)}]#4){#6}[#7](#8) } { \path (#4) coordinate (#5) ; \tzdot*[#2](#4){#6}[#7](#8) } } { \IfValueTF { #3 } { \tl_put_right:Nn \l_tzcoor_cmd_tl { ([shift={(#3)}]#4) coordinate } } { \tl_put_right:Nn \l_tzcoor_cmd_tl { (#4) coordinate } } \tl_put_right:Nn \l_tzcoor_cmd_tl { [ inner~sep = 0pt , } \tl_put_right:Nx \l_tzcoor_cmd_tl { label = { \exp_not:n { #7 } \c_colon_str \exp_not:n { #6 } } } \tl_put_right:Nn \l_tzcoor_cmd_tl { ] (#5) } \exp_last_unbraced:No \path \l_tzcoor_cmd_tl ; } } %%% --- end of \tzcoor %%% \tzcoors \bool_new:N \l_tzcoors_shift_coor_bool %%% \tzcoors*[opt] ()(){}[] ()(){}[] repeated ()(){}[]; %% repeat pattern: (coor)(name){label}[pos] \NewDocumentCommand\tzcoors{ s O{} d<> } { \tl_clear:N \l_tzcoors_cmd_tl \tl_clear:N \l_tzcoors_tzdot_cmd_tl \IfBooleanTF { #1 } { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfValueTF { #2 } { \tl_set:Nn \l_tzcoors_opt_tl { #2 } } { \tl_clear:N \l_tzcoors_opt_tl } \IfValueTF { #3 } { \tl_set:Nn \l_tzcoors_shift_coor_tl { #3 } \bool_set_true:N \l_tzcoors_shift_coor_bool } { \tl_clear:N \l_tzcoors_shift_coor_tl \bool_set_false:N \l_tzcoors_shift_coor_bool } \tzcoors_check_token:n } \cs_new:Npn \tzcoors_check_token:n #1 { % \str_if_eq:nnTF { #1 } { ( } % { \tzcoors_sub_fn ( } % { \tzcoors_stop_action } \str_case:nnF { #1 } { { ( } { \tzcoors_sub_fn #1 } { ; } { \tzcoors_late_opt_fn } } { \tzcoors_stop_action } } \NewDocumentCommand\tzcoors_sub_fn { r() r() +G{} O{} } { \bool_if:NTF \l_tmpa_bool { % collect only coor info \bool_if:NTF \l_tzcoors_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzcoors_cmd_tl { ([ shift = { (\l_tzcoors_shift_coor_tl) } ]#1) } } {% no shift (normal) \tl_put_right:Nn \l_tzcoors_cmd_tl { (#1) } } \tl_put_right:Nn \l_tzcoors_cmd_tl { coordinate (#2) } % collect dot info: (coor) [ dot opt ] {} \bool_if:NTF \l_tzcoors_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzcoors_tzdot_cmd_tl { ([ shift = { (\l_tzcoors_shift_coor_tl) } ]#1) } } {% no shift \tl_put_right:Nn \l_tzcoors_tzdot_cmd_tl { (#1) } } \tl_put_right:Nn \l_tzcoors_tzdot_cmd_tl { node [ fill , tzdot = \tzdotsize , } \tl_put_right:Nx \l_tzcoors_tzdot_cmd_tl { label = { \exp_not:n { #4 } \c_colon_str \exp_not:n { #3 } } , } \tl_put_right:No \l_tzcoors_tzdot_cmd_tl { \l_tzcoors_opt_tl % expand `once' ] {} } } { \bool_if:NTF \l_tzcoors_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzcoors_cmd_tl { ([ shift = { (\l_tzcoors_shift_coor_tl) } ]#1) coordinate } } {% no shift (normal) \tl_put_right:Nn \l_tzcoors_cmd_tl { (#1) coordinate } } \tl_put_right:Nx \l_tzcoors_cmd_tl { [ label = { \exp_not:n { #4 } \c_colon_str \exp_not:n { #3 } } ] } \tl_put_right:Nn \l_tzcoors_cmd_tl { (#2) } } \tzcoors_check_token:n } \NewDocumentCommand\tzcoors_late_opt_fn { D(){\tz@initial@dot@size} } { \renewcommand\tzdotsize{ #1 } \tzcoors_stop_action } \cs_new:Npn \tzcoors_stop_action { \exp_last_unbraced:Nf \path \l_tzcoors_cmd_tl ; \bool_if:NT \l_tmpa_bool { \exp_last_unbraced:Nf \path \l_tzcoors_tzdot_cmd_tl ; } } %%% --- end of \tzcoors %%% \tzcoorsquick --- with labels (quick view) \bool_new:N \l_tzcoors_quick_shift_coor_bool \NewDocumentCommand\tzcoorsquick { s O{} d<> } { \tl_clear:N \l_tzcoors_quick_cmd_tl \tl_clear:N \l_tzcoors_quick_tzdot_cmd_tl \IfBooleanTF { #1 } { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfValueTF { #2 } { \tl_set:Nn \l_tzcoors_quick_opt_tl { #2 } } { \tl_clear:N \l_tzcoors_quick_opt_tl } \IfValueTF { #3 } { \tl_set:Nn \l_tzcoors_quick_shift_coor_tl { #3 } \bool_set_true:N \l_tzcoors_quick_shift_coor_bool } { \tl_clear:N \l_tzcoors_quick_shift_coor_tl \bool_set_false:N \l_tzcoors_quick_shift_coor_bool } \tzcoors_quick_check_token:n } \cs_new:Npn \tzcoors_quick_check_token:n #1 { % \str_if_eq:nnTF { #1 } { ( } % { \tzcoorsquick_sub_fn ( } % { \tzcoorsquick_stop_action } \str_case:nnF { #1 } { { ( } { \tzcoorsquick_sub_fn #1 } { ; } { \tzcoorsquick_late_opt_fn } } { \tzcoorsquick_stop_action } } % repetition *** \NewDocumentCommand\tzcoorsquick_sub_fn { r() r() +g O{} } { \IfValueTF { #3 } { \tl_set:Nx \l_tmpa_tl { \exp_not:n { #3 } } } { \tl_set:Nn \l_tmpa_tl { #2 } } % automatic view \tl_if_empty:nTF { #4 } { \bool_if:NTF \l_tmpa_bool { \tl_set:Nn \l_tmpb_tl { } } % texts with dots (tikz default: above) { \tl_set:Nn \l_tmpb_tl { center } } % only texts } { \tl_set:Nx \l_tmpb_tl { \exp_not:n { #4 } } } \bool_if:NTF \l_tmpa_bool { %% glancing labels with dots % collect only coor info % collect only coor info \bool_if:NTF \l_tzcoors_quick_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzcoors_quick_cmd_tl { ([ shift = { (\l_tzcoors_quick_shift_coor_tl) } ]#1) } } {% no shift (normal) \tl_put_right:Nn \l_tzcoors_quick_cmd_tl { (#1) } } \tl_put_right:Nn \l_tzcoors_quick_cmd_tl { coordinate (#2) } % collect dot info: (coor) [ dot opt ] {} \bool_if:NTF \l_tzcoors_quick_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzcoors_quick_tzdot_cmd_tl { ([ shift = { (\l_tzcoors_quick_shift_coor_tl) } ]#1) } } {% no shift \tl_put_right:Nn \l_tzcoors_quick_tzdot_cmd_tl { (#1) } } \tl_put_right:Nn \l_tzcoors_quick_tzdot_cmd_tl { node [ fill , tzdot = \tzdotsize , } \tl_put_right:Nx \l_tzcoors_quick_tzdot_cmd_tl { label = { \l_tmpb_tl \c_colon_str { \l_tmpa_tl } } , } \tl_put_right:No \l_tzcoors_quick_tzdot_cmd_tl { \l_tzcoors_quick_opt_tl % expand `once' ] {} } } { %% glancing just labels (right on the coors) % collect coor and node info \bool_if:NTF \l_tzcoors_quick_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzcoors_quick_cmd_tl { ([ shift = { (\l_tzcoors_quick_shift_coor_tl) } ]#1) coordinate } } {% no shift (normal) \tl_put_right:Nn \l_tzcoors_quick_cmd_tl { (#1) coordinate } } \tl_put_right:Nx \l_tzcoors_quick_cmd_tl { [ label = { \l_tmpb_tl \c_colon_str { \l_tmpa_tl } } ] } \tl_put_right:Nn \l_tzcoors_quick_cmd_tl { (#2) } } \tzcoors_quick_check_token:n } \NewDocumentCommand\tzcoorsquick_late_opt_fn{ D(){\tz@initial@dot@size} } { \renewcommand\tzdotsize{ #1 } \tzcoorsquick_stop_action } \cs_new:Npn \tzcoorsquick_stop_action { \exp_last_unbraced:Nf \path \l_tzcoors_quick_cmd_tl ; \bool_if:NT \l_tmpa_bool { \exp_last_unbraced:Nf \path \l_tzcoors_quick_tzdot_cmd_tl ; } } %%% --- end of \tzcoorsquick %%%%% Lines %%% \tzline %% do not use: inner sep=0pt %%% \tzline \bool_new:N \l_tzline_shift_coor_bool %%% \tzline \NewDocumentCommand\tzline{ s t+ o d<> d"" } { \tl_clear:N \l_tzline_cmd_tl \IfBooleanTF { #1 } % (*) or not (NOT USED!) { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } % (+) or not { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #4 } { \tl_set:Nn \l_tzline_shift_coor_tl { #4 } \bool_set_true:N \l_tzline_shift_coor_bool } { \tl_clear:N \l_tzline_shift_coor_tl \bool_set_false:N \l_tzline_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzline_opt_tl { #3 } } { \tl_clear:N \l_tzline_opt_tl } \IfValueTF { #5 } { \tl_set:Nn \l_tzline_namepath_tl { name~path = #5 } } { \tl_clear:N \l_tzline_namepath_tl } \tzline_check_token:n } \cs_new:Npn \tzline_check_token:n #1 { \str_if_eq:nnT { #1 } { ( } { \tzline_sub_fn ( } % \tzline_stop_action } %% structure: (coorA) -- node [pos] {text} (coorB) node [pos] {text} \NewDocumentCommand\tzline_sub_fn{ r() +G{} O{} d<> r() +G{} O{} D<>{} } { % determine connect line STYLE \tl_set:Nn \l_tzline_STYLE_A_tl { -- } \IfValueTF { #4 } { \tl_set:Nn \l_tzline_STYLE_C_tl { #4 } } { \bool_if:NTF \l_tmpb_bool { \tl_set:Nn \l_tzline_STYLE_C_tl { ++ } } { \tl_set:Nn \l_tzline_STYLE_C_tl { } } } % insert connect line STYLE \bool_if:NTF \l_tzline_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzline_cmd_tl { ([ shift = { (\l_tzline_shift_coor_tl) } ]#1) } } {% no shift (normal) \tl_put_right:Nn \l_tzline_cmd_tl { (#1) } } \tl_put_right:No \l_tzline_cmd_tl % once { \l_tzline_STYLE_A_tl %% just -- } \tl_put_right:Nn \l_tzline_cmd_tl { ~ node [ above , #3 ] { #2 } } \tl_put_right:No \l_tzline_cmd_tl % once { \l_tzline_STYLE_C_tl } \bool_if:NTF \l_tmpb_bool {% if ++ \tl_put_right:Nn \l_tzline_cmd_tl { (#5) } } {% no ++ \bool_if:NTF \l_tzline_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzline_cmd_tl { ([ shift = { (\l_tzline_shift_coor_tl) } ]#5) } } {% no shift (normal) \tl_put_right:Nn \l_tzline_cmd_tl { (#5) } } } \tl_put_right:Nn \l_tzline_cmd_tl { node [ #7 ] { #6 } } % final action \tl_put_left:No \l_tzline_cmd_tl { \l_tzline_opt_tl ] % expand `once' } \tl_put_left:Nx \l_tzline_cmd_tl { [ \l_tzline_namepath_tl , } \exp_last_unbraced:Nf \draw \l_tzline_cmd_tl #8 ; } %%% --- end of \tzline %%% \tzlines \bool_new:N \l_tzlines_shift_coor_bool %% do not use: inner sep=0pt \NewDocumentCommand\tzlines{ s t+ O{} d<> D""{} } { \tl_clear:N \l_tzlines_cmd_tl \tl_clear:N \l_tzlines_STYLE_tl \IfBooleanTF { #1 } % (*) or not (NOT USED!) { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } % (+) or not { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #4 } { \tl_set:Nn \l_tzlines_shift_coor_tl { #4 } \bool_set_true:N \l_tzlines_shift_coor_bool } { \tl_clear:N \l_tzlines_shift_coor_tl \bool_set_false:N \l_tzlines_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzlines_opt_tl { #3 } } { \tl_clear:N \l_tzlines_opt_tl } \IfValueTF { #5 } { \tl_set:Nn \l_tzlines_namepath_tl { name~path = #5 } } { \tl_clear:N \l_tzlines_namepath_tl } \int_zero:N \l_tmpa_int \tzlines_check_token:n } \cs_new:Npn \tzlines_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzlines_sub_fn #1 } % { \tzlines_stop_action } \str_case:nnF { #1 } { { ( } { \tzlines_sub_fn #1 } { ; } { \tzlines_late_opt_fn } } { \tzlines_stop_action } } \NewDocumentCommand\tzlines_sub_fn{ r() +G{} O{} d<> } { \int_incr:N \l_tmpa_int % (from the second round) put line STYLE before the next cmd-tl \int_compare:nT { \l_tmpa_int > 1 } { \tl_put_right:No \l_tzlines_cmd_tl { \l_tzlines_STYLE_tl } \tl_clear:N \l_tzlines_STYLE_tl } % collect cmd-tl \bool_if:NTF \l_tzlines_shift_coor_bool {% shift-coor \bool_if:NTF \l_tmpb_bool {% if ++ \int_compare:nTF { \l_tmpa_int > 1 } { \tl_put_right:Nn \l_tzlines_cmd_tl { (#1) } } % no shift from 2nd { \tl_put_right:Nx \l_tzlines_cmd_tl { ([ shift = { (\l_tzlines_shift_coor_tl) } ]#1) } % shift first } } {% no ++ \tl_put_right:Nx \l_tzlines_cmd_tl { ([ shift = { (\l_tzlines_shift_coor_tl) } ]#1) } % shift all coors } } { \tl_put_right:Nn \l_tzlines_cmd_tl { (#1) } } % no shift (normal) % (from the first round on) determine and save STYLE % determine connect line STYLE \tl_set:Nn \l_tzlines_STYLE_A_tl { -- } % save node info (for later use, at the end) \tl_set:Nn \l_tzlines_STYLE_B_tl { ~ node [ #3 ] { #2 } } \IfValueTF { #4 } { \tl_set:Nn \l_tzlines_STYLE_C_tl { #4 } % empty, + , or ++ } { \bool_if:NTF \l_tmpb_bool { \tl_set:Nn \l_tzlines_STYLE_C_tl { ++ } } { \tl_set:Nn \l_tzlines_STYLE_C_tl { } } } \tl_put_right:No \l_tzlines_STYLE_tl { \l_tzlines_STYLE_A_tl } \tl_put_right:No \l_tzlines_STYLE_tl { \l_tzlines_STYLE_B_tl } \tl_put_right:No \l_tzlines_STYLE_tl { \l_tzlines_STYLE_C_tl } \tzlines_check_token:n } \NewDocumentCommand\tzlines_late_opt_fn { D<>{} } { \tl_set:Nn \l_tzlines_code_at_end_tl { #1 } \tzlines_stop_action } \NewDocumentCommand\tzlines_stop_action {} { \tl_put_right:No \l_tzlines_cmd_tl { \l_tzlines_STYLE_B_tl } \tl_clear:N \l_tzlines_STYLE_tl % gathering options \tl_put_left:No \l_tzlines_cmd_tl { \l_tzlines_opt_tl ] % expand `once' needed } \tl_put_left:Nx \l_tzlines_cmd_tl { [ \l_tzlines_namepath_tl , } % final action \exp_last_unbraced:Nf \draw \l_tzlines_cmd_tl \l_tzlines_code_at_end_tl ; } %%% --- end of \tzlines %%% \tzpolygon (closed path of \tzlines) \bool_new:N \l_tzpolygon_shift_coor_bool %% do not use: inner sep=0pt \NewDocumentCommand\tzpolygon{ s t+ O{} d<> D""{} } { \tl_clear:N \l_tzpolygon_cmd_tl \tl_clear:N \l_tzpolygon_STYLE_tl \IfBooleanTF { #1 } % fill(*) or not { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } % (+) or not { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #4 } { \tl_set:Nn \l_tzpolygon_shift_coor_tl { #4 } \bool_set_true:N \l_tzpolygon_shift_coor_bool } { \tl_clear:N \l_tzpolygon_shift_coor_tl \bool_set_false:N \l_tzpolygon_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nx \l_tzpolygon_opt_tl { #3 } } { \tl_clear:N \l_tzpolygon_opt_tl } \IfValueTF { #5 } { \tl_set:Nn \l_tzpolygon_namepath_tl { name~path = #5 } } { \tl_clear:N \l_tzpolygon_namepath_tl } \int_zero:N \l_tmpa_int \tzpolygon_check_token:n } \cs_new:Npn \tzpolygon_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzpolygon_sub_fn #1 } % { \tzpolygon_stop_action } \str_case:nnF { #1 } { { ( } { \tzpolygon_sub_fn #1 } { ; } { \tzpolygon_late_opt_fn } } { \tzpolygon_stop_action } } \NewDocumentCommand\tzpolygon_sub_fn{ r() +G{} O{} d<> } { \int_incr:N \l_tmpa_int % (from the second round) put line STYLE before the next cmd-tl \int_compare:nT { \l_tmpa_int > 1 } { \tl_put_right:No \l_tzpolygon_cmd_tl { \l_tzpolygon_STYLE_tl } \tl_clear:N \l_tzpolygon_STYLE_tl } % collect cmd-tl \bool_if:NTF \l_tzpolygon_shift_coor_bool {% shift-coor \bool_if:NTF \l_tmpb_bool {% if ++ \int_compare:nTF { \l_tmpa_int > 1 } { \tl_put_right:Nn \l_tzpolygon_cmd_tl { (#1) } } % no shift from 2nd { \tl_put_right:Nx \l_tzpolygon_cmd_tl { ([ shift = { (\l_tzpolygon_shift_coor_tl) } ]#1) } % shift first } } {% no ++ \tl_put_right:Nx \l_tzpolygon_cmd_tl { ([ shift = { (\l_tzpolygon_shift_coor_tl) } ]#1) } % shift all coors } } { \tl_put_right:Nn \l_tzpolygon_cmd_tl { (#1) } } % no shift (normal) % (from the first round on) determine and save STYLE % determine connect line STYLE \tl_set:Nn \l_tzpolygon_STYLE_A_tl { -- } % save node info (for later use, at the end) \tl_set:Nn \l_tzpolygon_STYLE_B_tl { ~ node [ #3 ] { #2 } } \IfValueTF { #4 } { \tl_set:Nn \l_tzpolygon_STYLE_C_tl { #4 } % empty, + , or ++ } { \bool_if:NTF \l_tmpb_bool { \tl_set:Nn \l_tzpolygon_STYLE_C_tl { ++ } } { \tl_set:Nn \l_tzpolygon_STYLE_C_tl { } } } \tl_put_right:No \l_tzpolygon_STYLE_tl { \l_tzpolygon_STYLE_A_tl } \tl_put_right:No \l_tzpolygon_STYLE_tl { \l_tzpolygon_STYLE_B_tl } \tl_put_right:No \l_tzpolygon_STYLE_tl { \l_tzpolygon_STYLE_C_tl } \tzpolygon_check_token:n } \NewDocumentCommand\tzpolygon_late_opt_fn { G{\tz@initial@fill@opacity} D<>{} } { \renewcommand\tzfillopacity{ #1 } \tl_set:Nn \l_tzpolygon_code_at_end_tl { #2 } \tzpolygon_stop_action } \NewDocumentCommand\tzpolygon_stop_action {} { \tl_put_right:No \l_tzpolygon_cmd_tl { \l_tzpolygon_STYLE_B_tl } \tl_clear:N \l_tzpolygon_STYLE_tl % fill or not \tl_put_left:No \l_tzpolygon_cmd_tl { \l_tzpolygon_opt_tl ] % expand `once' needed } \bool_if:NTF \l_tmpa_bool { \tl_put_left:Nx \l_tzpolygon_cmd_tl { [ fill=\tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , \l_tzpolygon_namepath_tl , } } { \tl_put_left:Nx \l_tzpolygon_cmd_tl { [ \l_tzpolygon_namepath_tl , } } % final action \exp_last_unbraced:Nf \draw \l_tzpolygon_cmd_tl \l_tzpolygon_code_at_end_tl -- cycle ; } %%% --- end of \tzpolygon %%% \tzpath %% draw=none version of \tzlinks (mainly for filling area) \bool_new:N \g_tzpath_BEGIN_cmd_bool \bool_new:N \g_tzpath_END_cmd_bool \bool_new:N \l_tzpath_shift_coor_bool %% \tzpathAtBegin \NewDocumentCommand\tzpathAtBegin{ m } { \bool_gset_true:N \g_tzpath_BEGIN_cmd_bool \tl_gset:No \g_tzpath_BEGIN_cmd_tl { #1 } } %% \tzpathAtEnd \NewDocumentCommand\tzpathAtEnd{ m } { \bool_gset_true:N \g_tzpath_END_cmd_bool \tl_gset:No \g_tzpath_END_cmd_tl { #1 } } %%% \tzpath %% do not use: inner sep=0pt \NewDocumentCommand\tzpath{ s t+ G{\tz@initial@path@style} O{} d<> D""{} } { \tl_clear:N \l_tzpath_cmd_tl \tl_clear:N \l_tzpath_STYLE_tl \IfValueT { #3 } { \renewcommand\tzpathstyle{ #3 } } \IfBooleanTF { #1 } % (*) or not (NOT USED!) { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } % (+) or not { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #5 } { \tl_set:Nn \l_tzpath_shift_coor_tl { #5 } \bool_set_true:N \l_tzpath_shift_coor_bool } { \tl_clear:N \l_tzpath_shift_coor_tl \bool_set_false:N \l_tzpath_shift_coor_bool } \IfValueTF { #4 } { \tl_set:Nx \l_tzpath_opt_tl { #4 } } { \tl_clear:N \l_tzpath_opt_tl } \IfValueTF { #6 } { \tl_set:Nn \l_tzpath_namepath_tl { name~path = #6 } } { \tl_clear:N \l_tzpath_namepath_tl } \int_zero:N \l_tmpa_int \tzpath_check_token:n } \cs_new:Npn \tzpath_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzpath_sub_fn #1 } % { \tzpath_stop_action } \str_case:nnF { #1 } { { ( } { \tzpath_sub_fn #1 } { ; } { \tzpath_late_opt_fn } } { \tzpath_stop_action } } \NewDocumentCommand\tzpath_sub_fn{ r() O{} +G{} O{} d<> } { \int_incr:N \l_tmpa_int % (from the second round) put line STYLE before the next cmd-tl \int_compare:nT { \l_tmpa_int > 1 } { \tl_put_right:No \l_tzpath_cmd_tl { \l_tzpath_STYLE_tl } \tl_clear:N \l_tzpath_STYLE_tl } % collect cmd-tl \bool_if:NTF \l_tzpath_shift_coor_bool {% shift-coor \bool_if:NTF \l_tmpb_bool {% if ++ \int_compare:nTF { \l_tmpa_int > 1 } { \tl_put_right:Nn \l_tzpath_cmd_tl { (#1) } } % no shift from 2nd { \tl_put_right:Nx \l_tzpath_cmd_tl { ([ shift = { (\l_tzpath_shift_coor_tl) } ]#1) } % shift first } } {% no ++ \tl_put_right:Nx \l_tzpath_cmd_tl { ([ shift = { (\l_tzpath_shift_coor_tl) } ]#1) } % shift all coors } } { \tl_put_right:Nn \l_tzpath_cmd_tl { (#1) } } % no shift (normal) % (from the first round on) determine and save STYLE % determine connect line STYLE \tl_if_empty:nTF { #2 } { \tl_set:Nn \l_tzpath_STYLE_A_tl { ~ \tzpathstyle ~ } } { \tl_set:Nn \l_tzpath_STYLE_A_tl { #2 } } % save node info (for later use, at the end) \tl_if_empty:nTF { #3 } { \tl_clear:N \l_tzpath_STYLE_B_tl } { \tl_set:Nn \l_tzpath_STYLE_B_tl { ~ node [ #4 ] { #3 } } } \IfValueTF { #5 } { \tl_set:Nn \l_tzpath_STYLE_C_tl { #5 } } { \bool_if:NTF \l_tmpb_bool { \tl_set:Nn \l_tzpath_STYLE_C_tl { ++ } } { \tl_set:Nn \l_tzpath_STYLE_C_tl { } } } \tl_put_right:No \l_tzpath_STYLE_tl { \l_tzpath_STYLE_A_tl } \tl_put_right:No \l_tzpath_STYLE_tl { \l_tzpath_STYLE_B_tl } \tl_put_right:No \l_tzpath_STYLE_tl { \l_tzpath_STYLE_C_tl } \tzpath_check_token:n } \NewDocumentCommand\tzpath_late_opt_fn { G{\tz@initial@fill@opacity} D<>{} } { \renewcommand\tzfillopacity{ #1 } \tl_set:Nn \l_tzpath_code_at_end_tl { #2 } \tzpath_stop_action } \NewDocumentCommand\tzpath_stop_action {} { \tl_if_empty:NF \l_tzpath_STYLE_B_tl { \tl_put_right:No \l_tzpath_cmd_tl { \l_tzpath_STYLE_B_tl } } \tl_clear:N \l_tzpath_STYLE_tl %% add at begin/end \bool_if:NT \g_tzpath_BEGIN_cmd_bool { \tl_put_left:Nx \l_tzpath_cmd_tl { \g_tzpath_BEGIN_cmd_tl } } \bool_if:NT \g_tzpath_END_cmd_bool { \tl_put_right:Nx \l_tzpath_cmd_tl { \g_tzpath_END_cmd_tl } } %% collect options \tl_put_left:No \l_tzpath_cmd_tl { \l_tzpath_opt_tl ] } % expand `once' needed % * or not \bool_if:NTF \l_tmpa_bool { \tl_put_left:Nx \l_tzpath_cmd_tl { [ fill=\tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , \l_tzpath_namepath_tl , } } { \tl_put_left:Nx \l_tzpath_cmd_tl { [ \l_tzpath_namepath_tl , } } %% final action \exp_last_unbraced:Nf \path \l_tzpath_cmd_tl \l_tzpath_code_at_end_tl ; %% path \bool_gset_false:N \g_tzpath_BEGIN_cmd_bool \bool_gset_false:N \g_tzpath_END_cmd_bool } %%% --- end of \tzpath %%% \tzto \bool_new:N \g_tzto_BEGIN_cmd_bool \bool_new:N \g_tzto_END_cmd_bool \bool_new:N \l_tzto_shift_coor_bool %% \tztoAtBegin \NewDocumentCommand\tztoAtBegin{ m } { \bool_gset_true:N \g_tzto_BEGIN_cmd_bool \tl_gset:No \g_tzto_BEGIN_cmd_tl { #1 } } %% \tztoAtEnd \NewDocumentCommand\tztoAtEnd{ m } { \bool_gset_true:N \g_tzto_END_cmd_bool \tl_gset:No \g_tzto_END_cmd_tl { #1 } } %%% \tzto (main) \NewDocumentCommand\tzto{ s t+ o d<> d"" } { \tl_clear:N \l_tzto_cmd_tl \IfBooleanTF { #1 } % (*) or not (NOT USED!) { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } % (+) or not { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #4 } { \tl_set:Nn \l_tzto_shift_coor_tl { #4 } \bool_set_true:N \l_tzto_shift_coor_bool } { \tl_clear:N \l_tzto_shift_coor_tl \bool_set_false:N \l_tzto_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzto_opt_tl { #3 } } { \tl_clear:N \l_tzto_opt_tl } \IfValueTF { #5 } { \tl_set:Nn \l_tzto_namepath_tl { name~path = #5 } } { \tl_clear:N \l_tzto_namepath_tl } \tzto_check_token:n } \cs_new:Npn \tzto_check_token:n #1 { \str_if_eq:nnT { #1 } { ( } { \tzto_sub_fn ( } % \tzto_stop_action } \NewDocumentCommand\tzto_sub_fn{ r() +G{} O{} r() +G{} O{} D<>{} } { \bool_if:NTF \l_tzto_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzto_cmd_tl { ([ shift = { (\l_tzto_shift_coor_tl) } ]#1) } } { \tl_put_right:Nn \l_tzto_cmd_tl { (#1) } } \tl_put_right:Nn \l_tzto_cmd_tl { to ~node [ above , #3 ] { #2 } } \bool_if:NTF \l_tmpb_bool {% if ++ \tl_put_right:Nn \l_tzto_cmd_tl { ++ (#4) } } {% no ++ \bool_if:NTF \l_tzto_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzto_cmd_tl { ([ shift = { (\l_tzto_shift_coor_tl) } ]#4) } } { \tl_put_right:Nn \l_tzto_cmd_tl { (#4) } } } \tl_put_right:Nn \l_tzto_cmd_tl { node [ #6 ] { #5 } } % add at begin/end \bool_if:NT \g_tzto_BEGIN_cmd_bool { \tl_put_left:Nx \l_tzto_cmd_tl { \g_tzto_BEGIN_cmd_tl } } \bool_if:NT \g_tzto_END_cmd_bool { \tl_put_right:Nx \l_tzto_cmd_tl { \g_tzto_END_cmd_tl } } % final action \tl_put_left:No \l_tzto_cmd_tl { \l_tzto_opt_tl ] % expand `once' needed } \tl_put_left:Nx \l_tzto_cmd_tl { [ \l_tzto_namepath_tl , } \exp_last_unbraced:Nf \draw \l_tzto_cmd_tl #7 ; \bool_gset_false:N \g_tzto_BEGIN_cmd_bool \bool_gset_false:N \g_tzto_END_cmd_bool % \tl_clear:N \g_tzto_BEGIN_cmd_tl % \tl_clear:N \g_tzto_END_cmd_tl } %%% --- end of \tzto %%% \tztos (longer version of \tzto) \bool_new:N \g_tztos_BEGIN_cmd_bool \bool_new:N \g_tztos_END_cmd_bool \bool_new:N \l_tztos_shift_coor_bool %% \tztosAtBegin \NewDocumentCommand\tztosAtBegin{ m } { \bool_gset_true:N \g_tztos_BEGIN_cmd_bool \tl_gset:No \g_tztos_BEGIN_cmd_tl { #1 } } %% \tztosAtEnd \NewDocumentCommand\tztosAtEnd{ m } { \bool_gset_true:N \g_tztos_END_cmd_bool \tl_gset:No \g_tztos_END_cmd_tl { #1 } } %%% \tztos (main) %% do not use: inner sep=0pt \NewDocumentCommand\tztos{ s t+ O{} d<> D""{} } { \tl_clear:N \l_tztos_cmd_tl \tl_clear:N \l_tztos_STYLE_tl % \IfValueT { #3 } % { \renewcommand\tztostyle{ #3 } } \IfBooleanTF { #1 } % (*) or not (NOT USED!) { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } % (+) or not { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #4 } { \tl_set:Nn \l_tztos_shift_coor_tl { #4 } \bool_set_true:N \l_tztos_shift_coor_bool } { \tl_clear:N \l_tztos_shift_coor_tl \bool_set_false:N \l_tztos_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tztos_opt_tl { #3 } } { \tl_clear:N \l_tztos_opt_tl } \IfValueTF { #5 } { \tl_set:Nn \l_tztos_namepath_tl { name~path = #5 } } { \tl_clear:N \l_tztos_namepath_tl } \int_zero:N \l_tmpa_int \tztos_check_token:n } \cs_new:Npn \tztos_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tztos_sub_fn #1 } % { \tztos_stop_action } \str_case:nnF { #1 } { { ( } { \tztos_sub_fn #1 } { ; } { \tztos_late_opt_fn } } { \tztos_stop_action } } %% (coor)[to opt]{text}[node opt] \NewDocumentCommand\tztos_sub_fn{ r() O{} +G{} O{} } { \int_incr:N \l_tmpa_int % (from the second round) put line STYLE before the next cmd-tl \int_compare:nT { \l_tmpa_int > 1 } { \tl_put_right:No \l_tztos_cmd_tl { \l_tztos_STYLE_tl } \tl_clear:N \l_tztos_STYLE_tl } % collect cmd-tl \bool_if:NTF \l_tztos_shift_coor_bool {% shift-coor \bool_if:NTF \l_tmpb_bool {% if ++ \int_compare:nTF { \l_tmpa_int > 1 } { \tl_put_right:Nn \l_tztos_cmd_tl { (#1) } } % no shift from 2nd { \tl_put_right:Nx \l_tztos_cmd_tl { ([ shift = { (\l_tztos_shift_coor_tl) } ]#1) } % shift first } } {% no ++ \tl_put_right:Nx \l_tztos_cmd_tl { ([ shift = { (\l_tztos_shift_coor_tl) } ]#1) } % shift all coors } } { \tl_put_right:Nn \l_tztos_cmd_tl { (#1) } } % no shift (normal) % (from the first round on) determine and save STYLE % determine connect line STYLE \tl_set:Nn \l_tztos_STYLE_A_tl { ~ to [ #2 ] } % save node info (for later use, at the end) \tl_if_empty:nTF { #3 } { \tl_clear:N \l_tztos_STYLE_B_tl } { \tl_set:Nn \l_tztos_STYLE_B_tl { ~ node [ #4 ] { #3 } } } \bool_if:NTF \l_tmpb_bool { \tl_set:Nn \l_tztos_STYLE_C_tl { ++ } } { \tl_set:Nn \l_tztos_STYLE_C_tl { } } \tl_put_right:No \l_tztos_STYLE_tl { \l_tztos_STYLE_A_tl } \tl_put_right:No \l_tztos_STYLE_tl { \l_tztos_STYLE_B_tl } \tl_put_right:No \l_tztos_STYLE_tl { \l_tztos_STYLE_C_tl } \tztos_check_token:n } \NewDocumentCommand\tztos_late_opt_fn { D<>{} } { \tl_set:Nn \l_tztos_code_at_end_tl { #1 } \tztos_stop_action } \NewDocumentCommand\tztos_stop_action {} { \tl_if_empty:NF \l_tztos_STYLE_B_tl { \tl_put_right:No \l_tztos_cmd_tl { \l_tztos_STYLE_B_tl } } \tl_clear:N \l_tztos_STYLE_tl % add at begin/end \bool_if:NT \g_tztos_BEGIN_cmd_bool { \tl_put_left:Nx \l_tztos_cmd_tl { \g_tztos_BEGIN_cmd_tl } } \bool_if:NT \g_tztos_END_cmd_bool { \tl_put_right:Nx \l_tztos_cmd_tl { \g_tztos_END_cmd_tl } } % fill or not \tl_put_left:No \l_tztos_cmd_tl { \l_tztos_opt_tl ] % expand `once' needed for user convenience } \tl_put_left:Nx \l_tztos_cmd_tl { [ \l_tztos_namepath_tl , } % final action \exp_last_unbraced:Nf \draw \l_tztos_cmd_tl \l_tztos_code_at_end_tl ; %% draw \bool_gset_false:N \g_tztos_BEGIN_cmd_bool \bool_gset_false:N \g_tztos_END_cmd_bool % \tl_clear:N \g_tztos_BEGIN_cmd_tl % \tl_clear:N \g_tztos_END_cmd_tl } %%% --- end of \tztos %%%%% Figures: circles, frames, ellipses, triangles, etc. %%% \tzcircle \NewDocumentCommand\tzcircle { s O{} d<> D""{} r() r() G{\tz@initial@fill@opacity} } { \renewcommand\tzfillopacity{#7} \IfBooleanTF { #1 } { \IfValueTF { #3 } {% if shift \draw [ fill = \tzfillcolor , fill~opacity = #7 , text~opacity = 1 , name~path = #4 , #2 ] ([shift={(#3)}]#5) circle (#6) ; } {% no shift (normal) \draw [ fill = \tzfillcolor , fill~opacity = #7 , text~opacity = 1 , name~path = #4 , #2 ] (#5) circle (#6) ; } } { \IfValueTF { #3 } { \draw [ #2 ] ([shift={(#3)}]#5) circle (#6) ; } { \draw [ #2 ] (#5) circle (#6) ; } } } %%% \tzellipse \NewDocumentCommand\tzellipse { s O{} d<> D""{} r() r() G{\tz@initial@fill@opacity} } { \renewcommand\tzfillopacity{#7} \IfBooleanTF { #1 } { \IfValueTF { #3 } {% if shift \draw [ fill = \tzfillcolor , fill~opacity = #7 , text~opacity = 1 , name~path = #4 , #2 ] ([shift={(#3)}]#5) ellipse (#6) ; } {% no shift (normal) \draw [ fill = \tzfillcolor , fill~opacity = #7 , text~opacity = 1 , name~path = #4 , #2 ] (#5) ellipse (#6) ; } } { \IfValueTF { #3 } { \draw [ name~path = #4 , #2 ] ([shift={(#3)}]#5) ellipse (#6) ; } { \draw [ name~path = #4 , #2 ] (#5) ellipse (#6) ; } } } %%% \tzframe \NewDocumentCommand\tzframe { s t+ O{} d<> D""{} r() r() G{\tz@initial@fill@opacity} } { \renewcommand\tzfillopacity{#8} \IfBooleanTF { #1 } { \IfBooleanTF { #2 } { \IfValueTF { #4 } {% if shift \draw [ fill = \tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , name~path = #5 , #3 ] ([shift={(#4)}]#6) rectangle ++ (#7) ; } {% no shift \draw [ fill = \tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , name~path = #5 , #3 ] (#6) rectangle ++ (#7) ; } } { \IfValueTF { #4 } {% if shift \draw [ fill = \tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , name~path = #5 , #3 ] ([shift={(#4)}]#6) rectangle ([shift={(#4)}]#7) ; } {% no shift \draw [ fill = \tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , name~path = #5 , #3 ] (#6) rectangle (#7) ; } } } { \IfBooleanTF { #2 } { \IfValueTF { #4 } {% if shift \draw [ name~path = #5 , #3 ] ([shift={(#4)}]#6) rectangle ++ (#7) ; } {% no shift \draw [ name~path = #5 , #3 ] (#6) rectangle ++ (#7) ; } } { \IfValueTF { #4 } {% if shift \draw [ name~path = #5 , #3 ] ([shift={(#4)}]#6) rectangle ([shift={(#4)}]#7) ; } {% no shift \draw [ name~path = #5 , #3 ] (#6) rectangle (#7) ; } } } } %%% \tzparabola \bool_new:N \l_tzparabola_shift_coor_bool \NewDocumentCommand\tzparabola { s t+ O{} d<> D""{} } { \tl_clear:N \l_tzparabola_cmd_tl \IfBooleanTF { #1 } % NOT USED!!! { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #5 } { \tl_set:Nn \l_tzparabola_pathname_tl { name~path = #5 } } { \tl_clear:N \l_tzparabola_pathname_tl } \IfValueTF { #4 } { \tl_set:Nn \l_tzparabola_shift_coor_tl { #4 } \bool_set_true:N \l_tzparabola_shift_coor_bool } { \tl_clear:N \l_tzparabola_shift_coor_tl \bool_set_false:N \l_tzparabola_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzparabola_opt_tl { #3 } } { \tl_clear:N \l_tzparabola_opt_tl } \tzparabola_check_token:n } \cs_new:Npn \tzparabola_check_token:n #1 { \str_if_eq:nnT { #1 } { ( } { \tzparabola_sub_fn ( } % \tzparabola_stop_action } \NewDocumentCommand\tzparabola_sub_fn { r() r() d() +G{} O{} G{\tz@initial@fill@opacity} D<>{} } { \renewcommand\tzfillopacity{#6} %% NOT USED! (to be removed) \bool_if:NTF \l_tzparabola_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzparabola_cmd_tl { ([shift = { (\l_tzparabola_shift_coor_tl) } ]#1) } } {% no shift (normal) \tl_put_right:Nn \l_tzparabola_cmd_tl { (#1) } } \IfNoValueTF { #3 } {%% 2 coors \bool_if:NTF \l_tmpb_bool {% if + (relative coor) \bool_if:NTF \l_tzparabola_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzparabola_cmd_tl { parabola ([shift = { (\l_tzparabola_shift_coor_tl) } ]$(#1)+(#2)$) } } {% no shift (normal) \tl_put_right:Nn \l_tzparabola_cmd_tl { parabola ($(#1)+(#2)$) } } } {% no + (absolute coor) \bool_if:NTF \l_tzparabola_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzparabola_cmd_tl { parabola ([shift = { (\l_tzparabola_shift_coor_tl) } ]#2) } } {% no shift (normal) \tl_put_right:Nn \l_tzparabola_cmd_tl { parabola (#2) } } } } {%% 3 coors \bool_if:NTF \l_tmpb_bool {% if + (relative coor) \tl_put_right:Nn \l_tzparabola_cmd_tl { parabola~bend + (#2) } \bool_if:NTF \l_tzparabola_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzparabola_cmd_tl { ([shift = { (\l_tzparabola_shift_coor_tl) } ]$(#1)+(#3)$) } } {% no shift (normal) \tl_put_right:Nn \l_tzparabola_cmd_tl { ($(#1)+(#3)$) } } } {% no + (absolute coor) \bool_if:NTF \l_tzparabola_shift_coor_bool { \tl_put_right:Nx \l_tzparabola_cmd_tl { parabola~bend ([shift = { (\l_tzparabola_shift_coor_tl) } ]#2) } } { \tl_put_right:Nn \l_tzparabola_cmd_tl { parabola~bend (#2) } } \bool_if:NTF \l_tzparabola_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzparabola_cmd_tl { ([shift = { (\l_tzparabola_shift_coor_tl) } ]#3) } } {% no shift (normal) \tl_put_right:Nn \l_tzparabola_cmd_tl { (#3) } } } } \tl_put_left:No \l_tzparabola_cmd_tl { \l_tzparabola_opt_tl ] } % expand `once' \tl_put_left:Nx \l_tzparabola_cmd_tl { [ \l_tzparabola_pathname_tl , } % final action \exp_last_unbraced:Nf \draw \l_tzparabola_cmd_tl node [ #5 ] { #4 } #7 ; } %%% -- end of \tzparabola %%% \tzbezier \bool_new:N \l_tzbezier_shift_coor_bool \NewDocumentCommand\tzbezier{ s t+ O{} d<> D""{tzplot~path} } { \tl_clear:N \l_tzbezier_cmd_tl \IfBooleanTF { #1 } %% NOT USED! { \bool_set_true:N \l_tmpa_bool } { \bool_set_true:N \l_tmpa_bool } \IfBooleanTF { #2 } { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \IfValueTF { #5 } { \tl_set:Nn \l_tzbezier_pathname_tl { name~path = #5 } } { \tl_clear:N \l_tzbezier_pathname_tl } \IfValueTF { #4 } { \tl_set:Nn \l_tzbezier_shift_coor_tl { #4 } \bool_set_true:N \l_tzbezier_shift_coor_bool } { \tl_clear:N \l_tzbezier_shift_coor_tl \bool_set_false:N \l_tzbezier_shift_coor_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzbezier_opt_tl { #3 } } { \tl_clear:N \l_tzbezier_opt_tl } \tzbezier_check_token:n } \cs_new:Npn \tzbezier_check_token:n #1 { \str_if_eq:nnT { #1 } { ( } { \tzbezier_sub_fn ( } % \tzbezier_stop_action } \NewDocumentCommand\tzbezier_sub_fn{ r() r() r() d() +G{} O{} D<>{} } { \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { ([shift = { (\l_tzbezier_shift_coor_tl) } ]#1) .. controls } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { (#1) .. controls } } \IfNoValueTF { #4 } {%% 3 coors \bool_if:NTF \l_tmpb_bool {% if + (relative coor) \tl_put_right:Nn \l_tzbezier_cmd_tl { + (#2) } \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { .. ([shift = { (\l_tzbezier_shift_coor_tl) } ]$(#1)+(#3)$) } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { .. ($(#1)+(#3)$) } } } {% no + (absolute coor) % control coor \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { ([ shift = { (\l_tzbezier_shift_coor_tl) } ]#2) } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { (#2) } } %% end coor \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { .. ([shift = { (\l_tzbezier_shift_coor_tl) } ]#3) } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { .. (#3) } } } } {%% 4 coors \bool_if:NTF \l_tmpb_bool {% if + (relative coor) \tl_put_right:Nn \l_tzbezier_cmd_tl { + (#2) and + (#3) } \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { .. ([shift = { (\l_tzbezier_shift_coor_tl) } ]$(#1)+(#4)$) } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { .. ($(#1)+(#4)$) } } } {% no + (absolute coor) %% control coors \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { ([ shift = { (\l_tzbezier_shift_coor_tl) } ]#2) and ([ shift = { (\l_tzbezier_shift_coor_tl) } ]#3) } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { (#2) and (#3) } } %% end coor \bool_if:NTF \l_tzbezier_shift_coor_bool {% if shift \tl_put_right:Nx \l_tzbezier_cmd_tl { .. ([shift = { (\l_tzbezier_shift_coor_tl) } ]#4) } } {% no shift (normal) \tl_put_right:Nn \l_tzbezier_cmd_tl { .. (#4) } } } } \tl_put_left:No \l_tzbezier_cmd_tl { \l_tzbezier_opt_tl ] } \tl_put_left:Nx \l_tzbezier_cmd_tl { [ \l_tzbezier_pathname_tl , } % final action \exp_last_unbraced:Nf \draw \l_tzbezier_cmd_tl node [ #6 ] { #5 } #7 ; } %%% -- end of \tzbezier %%% \tzarc \use:x{ \NewDocumentCommand \exp_not:N \tzarc { s t' O{} d<> D""{} r() >{ \SplitArgument {2} { \tl_to_str:n {:} } } r() } } { \IfBooleanTF { #1 } {}{} % NOT USED! \tl_clear:N \l_tzarc_cmd_tl \tzarc_args_process #7 \fp_set:Nn \l_tmpa_fp { \tzarcAngleA } \fp_set:Nn \l_tmpb_fp { \tzarcAngleB } \tl_put_right:Nn \l_tzarc_cmd_tl { [ name~path = #5 , #3 ] } \IfValueTF { #4 } {% if shift \tl_put_right:Nn \l_tzarc_cmd_tl { ([shift={(#4)}]#6) ++ (\tzarcAngleA \c_colon_str \tzarcRadius) } } {% no shift (normal) \tl_put_right:Nn \l_tzarc_cmd_tl { (#6) ++ (\tzarcAngleA \c_colon_str \tzarcRadius) } } \tl_put_right:Nx \l_tzarc_cmd_tl { \fp_compare:nTF { \l_tmpa_fp < \l_tmpb_fp } { arc ( \tzarcAngleA \c_colon_str \IfBooleanTF {#2} {\tzarcAngleB - 360} {\tzarcAngleB} \c_colon_str \tzarcRadius ) } { arc ( \IfBooleanTF {#2} {\tzarcAngleA - 360} {\tzarcAngleA} \c_colon_str \tzarcAngleB \c_colon_str \tzarcRadius ) } } \tzarc_sub_fn:n } \NewDocumentCommand\tzarc_args_process{ m m m } { \def\tzarcAngleA{#1} \def\tzarcAngleB{#2} \def\tzarcRadius{#3} } \cs_new:Npn \tzarc_sub_fn:n { \tzarc_final_actions } \NewDocumentCommand\tzarc_final_actions{ +G{} O{} D<>{} } { \tl_put_right:Nn \l_tzarc_cmd_tl { node [ #2 ] { #1 } #3 } \exp_last_unbraced:Nf \draw \l_tzarc_cmd_tl ; } %%% --- end of \tzarc %%% \tzarcfrom % (works like tikz original) \use:x{ \NewDocumentCommand \exp_not:N \tzarcfrom { s t' O{} d<> D""{} r() >{ \SplitArgument {2} { \tl_to_str:n {:} } } r() } } { \IfBooleanTF { #1 } {}{} % NOT USED! \tl_clear:N \l_tzarcfrom_cmd_tl \tzarcfrom_args_process #7 \fp_set:Nn \l_tmpa_fp { \tzarcfromAngleA } \fp_set:Nn \l_tmpb_fp { \tzarcfromAngleB } \tl_put_right:Nn \l_tzarcfrom_cmd_tl { [ name~path = #5 , #3 ] } \IfValueTF { #4 } {% if shift \tl_put_right:Nn \l_tzarcfrom_cmd_tl { ([shift={(#4)}]#6) } } {% no shift (normal) \tl_put_right:Nn \l_tzarcfrom_cmd_tl { (#6) } % ++ (\tzarcfromAngleA \c_colon_str \tzarcfromRadius) } \tl_put_right:No \l_tzarcfrom_cmd_tl { \fp_compare:nTF { \l_tmpa_fp < \l_tmpb_fp } { arc ( \tzarcfromAngleA \c_colon_str \IfBooleanTF {#2} {\tzarcfromAngleB - 360} {\tzarcfromAngleB} \c_colon_str \tzarcfromRadius ) } { arc ( \IfBooleanTF {#2} {\tzarcfromAngleA - 360} {\tzarcfromAngleA} \c_colon_str \tzarcfromAngleB \c_colon_str \tzarcfromRadius ) } } \tzarcfrom_sub_fn:n } \NewDocumentCommand\tzarcfrom_args_process{ m m m } { \def\tzarcfromAngleA{#1} \def\tzarcfromAngleB{#2} \def\tzarcfromRadius{#3} } \cs_new:Npn \tzarcfrom_sub_fn:n { \tzarcfrom_final_actions } \NewDocumentCommand\tzarcfrom_final_actions{ +G{} O{} D<>{} } { \tl_put_right:Nn \l_tzarcfrom_cmd_tl { node [ #2 ] { #1 } #3 } \exp_last_unbraced:Nf \draw \l_tzarcfrom_cmd_tl ; } %%% --- end of \tzarcfrom %%% \tzarcsfrom % (works like tikz original) \tl_new:N \l_tzarcsfrom_code_at_end_tl \NewDocumentCommand\tzarcsfrom { s t' O{} d<> D""{} r() } { \IfBooleanTF { #1 } {}{} % NOT USED! { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfBooleanTF { #2 } { \bool_set_true:N \l_tmpb_bool } { \bool_set_false:N \l_tmpb_bool } \tl_clear:N \l_tzarcsfrom_cmd_tl \tl_put_right:Nn \l_tzarcsfrom_cmd_tl { [ name~path = #5 , #3 ] } \IfValueTF { #4 } {% if shift \tl_put_right:Nn \l_tzarcsfrom_cmd_tl { ([shift={(#4)}]#6) } } {% no shift \tl_put_right:Nn \l_tzarcsfrom_cmd_tl { (#6) } % ++ (\tzarcsfromAngleA \c_colon_str \tzarcsfromRadius) } \tzarcsfrom_check_token:n } \cs_new:Npn \tzarcsfrom_check_token:n #1 { \str_case:nnF { #1 } { { ( } { \tzarcsfrom_sub_fn #1 } { ; } { \tzarcsfrom_late_opt_fn } } { \tzarcsfrom_stop_action } } \use:x{ \NewDocumentCommand \exp_not:N \tzarcsfrom_sub_fn { >{ \SplitArgument {2} { \tl_to_str:n {:} } } r() +G{} O{} } } { \tzarcsfrom_args_process #1 \fp_set:Nn \l_tmpa_fp { \tzarcsfromAngleA } \fp_set:Nn \l_tmpb_fp { \tzarcsfromAngleB } \tl_put_right:Nx \l_tzarcsfrom_cmd_tl { \fp_compare:nTF { \l_tmpa_fp < \l_tmpb_fp } { arc ( \tzarcsfromAngleA \c_colon_str \bool_if:NTF \l_tmpb_bool {\tzarcsfromAngleB - 360} {\tzarcsfromAngleB} \c_colon_str \tzarcsfromRadius ) } { arc ( \bool_if:NTF \l_tmpb_bool {\tzarcsfromAngleA - 360} {\tzarcsfromAngleA} \c_colon_str \tzarcsfromAngleB \c_colon_str \tzarcsfromRadius ) } } \tl_put_right:Nn \l_tzarcsfrom_cmd_tl { node [ #3 ] { #2 } } \tzarcsfrom_check_token:n } \NewDocumentCommand\tzarcsfrom_late_opt_fn { D<>{} } { \tl_set:Nn \l_tzarcsfrom_code_at_end_tl { #1 } \tzarcsfrom_stop_action } \NewDocumentCommand\tzarcsfrom_stop_action {} { \tl_put_right:No \l_tzarcsfrom_cmd_tl { \l_tzarcsfrom_code_at_end_tl } \exp_last_unbraced:Nf \draw \l_tzarcsfrom_cmd_tl ; } \NewDocumentCommand\tzarcsfrom_args_process{ m m m } { \def\tzarcsfromAngleA{#1} \def\tzarcsfromAngleB{#2} \def\tzarcsfromRadius{#3} } %%% --- end of \tzarcsfrom %%% \tzwedge \use:x{ \NewDocumentCommand \exp_not:N \tzwedge { s t' O{} d<> D""{} r() >{ \SplitArgument {2} { \tl_to_str:n {:} } } r() } } { \tl_clear:N \l_tzwedge_cmd_tl \tzwedge_args_process #7 \fp_set:Nn \l_tmpa_fp { \tzwedgeAngleA } \fp_set:Nn \l_tmpb_fp { \tzwedgeAngleB } \IfBooleanTF { #1 } { \tl_put_right:Nn \l_tzwedge_cmd_tl { [ fill=\tzfillcolor , fill~opacity = \tzfillopacity , text~opacity = 1 , name~path = #5 , #3 ] } } { \tl_put_right:Nn \l_tzwedge_cmd_tl { [ name~path = #5 , #3 ] } } \IfValueTF { #4 } { \tl_put_right:Nn \l_tzwedge_cmd_tl { ([shift={(#4)}]#6) -- ++ (\tzwedgeAngleA \c_colon_str \tzwedgeRadius) } } { \tl_put_right:Nn \l_tzwedge_cmd_tl { (#6) -- ++ (\tzwedgeAngleA \c_colon_str \tzwedgeRadius) } } \tl_put_right:No \l_tzwedge_cmd_tl { \fp_compare:nTF { \l_tmpa_fp < \l_tmpb_fp } { arc ( \tzwedgeAngleA \c_colon_str \IfBooleanTF {#2} {\tzwedgeAngleB - 360} {\tzwedgeAngleB} \c_colon_str \tzwedgeRadius ) } { arc ( \IfBooleanTF {#2} {\tzwedgeAngleA - 360} {\tzwedgeAngleA} \c_colon_str \tzwedgeAngleB \c_colon_str \tzwedgeRadius ) } } \tzwedge_sub_fn:n } \cs_new:Npn \tzwedge_sub_fn:n { \tzwedge_final_actions } \NewDocumentCommand\tzwedge_final_actions{ +G{} O{} G{.3} } { \tl_if_empty:nTF { #3 } { \renewcommand\tzfillopacity{\tz@initial@fill@opacity} } { \renewcommand\tzfillopacity{#3} } \tl_put_right:Nn \l_tzwedge_cmd_tl { node [ midway , #2 ] { #1 } } \exp_last_unbraced:Nf \draw \l_tzwedge_cmd_tl -- cycle ; } \NewDocumentCommand\tzwedge_args_process{ m m m } { \def\tzwedgeAngleA{#1} \def\tzwedgeAngleB{#2} \def\tzwedgeRadius{#3} } %%% --- end of \tzwedge %%%%% plot of Tikz %%% \tzplot \bool_new:N \l_tzplot_shift_coor_bool \NewDocumentCommand\tzplot{ s O{} G{0} O{} d<> D""{} } { \tl_clear:N \l_tzplot_opt_cmd_tl \tl_clear:N \l_tzplot_cmd_tl \tl_clear:N \l_tzplot_nodes_cmd_tl \tl_clear:N \l_tzplot_coors_cmd_tl \tl_clear:N \l_tzplot_code_at_end_tl \renewcommand\tzmarksize{\tz@initial@mark@size} \tl_put_right:Nn \l_tzplot_opt_cmd_tl { [ name~path = #6 , tension = #3 , smooth , tzmark = \tzmarksize , } \IfBooleanT { #1 } { \tl_put_right:Nn \l_tzplot_opt_cmd_tl { mark = * , draw = none , } } \IfValueTF { #5 } { \tl_set:Nn \l_tzplot_shift_coor_tl { #5 } \bool_set_true:N \l_tzplot_shift_coor_bool } { \tl_clear:N \l_tzplot_shift_coor_tl \bool_set_false:N \l_tzplot_shift_coor_bool } \tl_put_right:Nn \l_tzplot_opt_cmd_tl { #2 ] plot [ #4 ] coordinates } \tzplot_check_token:n } \cs_new:Npn \tzplot_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzplot_sub_fn #1 } % { \tzplot_stop_action } \str_case:nnF { #1 } { { ( } { \tzplot_sub_fn #1 } { ; } { \tzplot_late_opt_fn } } { \tzplot_stop_action } } \NewDocumentCommand\tzplot_sub_fn{ r() +G{} O{} } { % collect coordinates only \bool_if:NTF \l_tzplot_shift_coor_bool { \tl_put_right:Nx \l_tzplot_coors_cmd_tl { ([shift = { (\l_tzplot_shift_coor_tl) } ]#1) } } { \tl_put_right:Nn \l_tzplot_coors_cmd_tl { (#1) } } % collect nodes information \bool_if:NTF \l_tzplot_shift_coor_bool { \tl_put_right:Nx \l_tzplot_nodes_cmd_tl { ([shift = { (\l_tzplot_shift_coor_tl) } ]#1) } } { \tl_put_right:Nn \l_tzplot_nodes_cmd_tl { (#1) } } \tl_put_right:Nx \l_tzplot_nodes_cmd_tl { node [ label = { \exp_not:n { #3 } \c_colon_str \exp_not:n { #2 } } ] {} } \tzplot_check_token:n } \NewDocumentCommand\tzplot_late_opt_fn { d() D<>{} } { \IfValueTF { #1 } { \edef\tztmpMarkSize { #1 } } { \edef\tztmpMarkSize { \tz@initial@mark@size } } \tl_put_right:Nn \l_tzplot_code_at_end_tl { #2 } \tzplot_stop_action } \NewDocumentCommand\tzplot_stop_action {} { \renewcommand\tzmarksize{ \tztmpMarkSize } % final action \exp_last_unbraced:Nf \draw \l_tzplot_opt_cmd_tl % [opt] plot coordinates { \l_tzplot_coors_cmd_tl } % { (coor-1)(coor-2)...(coor-n) } \l_tzplot_code_at_end_tl % should precede _nodes_cmd_tl \l_tzplot_nodes_cmd_tl % (coor-i) node [opt] {text}, for all i ; } %%% --- end of \tzplot %%% \tzplotcurve \bool_new:N \l_tzplotcurve_shift_coor_bool \NewDocumentCommand\tzplotcurve{ s O{} G{1} O{} d<> D""{} } { \IfBooleanT { #1 } {}{} % NOT USED! \tl_clear:N \l_tzplotcurve_opt_cmd_tl \tl_clear:N \l_tzplotcurve_cmd_tl \tl_clear:N \l_tzplotcurve_nodes_cmd_tl \tl_clear:N \l_tzplotcurve_coors_cmd_tl \tl_clear:N \l_tzplotcurve_code_at_end_tl \tl_put_right:Nn \l_tzplotcurve_opt_cmd_tl { [ name~path = #6 , tension = #3 , smooth , tzmark = \tzmarksize , } \IfBooleanT { #1 } { \tl_put_right:Nn \l_tzplotcurve_opt_cmd_tl { mark = * , } } \IfValueTF { #5 } { \tl_set:Nn \l_tzplotcurve_shift_coor_tl { #5 } \bool_set_true:N \l_tzplotcurve_shift_coor_bool } { \tl_clear:N \l_tzplotcurve_shift_coor_tl \bool_set_false:N \l_tzplotcurve_shift_coor_bool } \tl_put_right:Nn \l_tzplotcurve_opt_cmd_tl { #2 ] plot [ #4 ] coordinates } \tzplotcurve_check_token:n } \cs_new:Npn \tzplotcurve_check_token:n #1 { % \token_if_eq_charcode:NNTF #1 ( % { \tzplotcurve_sub_fn #1 } % { \tzplotcurve_stop_action } \str_case:nnF { #1 } { { ( } { \tzplotcurve_sub_fn #1 } { ; } { \tzplotcurve_late_opt_fn } } { \tzplotcurve_stop_action } } \NewDocumentCommand\tzplotcurve_sub_fn{ r() +G{} O{} } { % collect coordinates only \bool_if:NTF \l_tzplotcurve_shift_coor_bool { \tl_put_right:Nx \l_tzplotcurve_coors_cmd_tl { ([shift = { (\l_tzplotcurve_shift_coor_tl) } ]#1) } } { \tl_put_right:Nn \l_tzplotcurve_coors_cmd_tl { (#1) } } % collect nodes information \bool_if:NTF \l_tzplotcurve_shift_coor_bool { \tl_put_right:Nx \l_tzplotcurve_nodes_cmd_tl { ([shift = { (\l_tzplotcurve_shift_coor_tl) } ]#1) } } { \tl_put_right:Nn \l_tzplotcurve_nodes_cmd_tl { (#1) } } \tl_put_right:Nx \l_tzplotcurve_nodes_cmd_tl { node [ label = { \exp_not:n { #3 } \c_colon_str \exp_not:n { #2 } } ] {} } \tzplotcurve_check_token:n } \NewDocumentCommand\tzplotcurve_late_opt_fn { d() D<>{} } { \IfValueTF { #1 } { \edef\tztmpMarkSize { #1 } } { \edef\tztmpMarkSize { \tz@initial@mark@size } } \tl_put_right:Nn \l_tzplotcurve_code_at_end_tl { #2 } \tzplotcurve_stop_action } \NewDocumentCommand\tzplotcurve_stop_action {} { \renewcommand\tzmarksize{ \tztmpMarkSize } % final action \exp_last_unbraced:Nf \draw \l_tzplotcurve_opt_cmd_tl % [opt] plot [ smooth ] coordinates { \l_tzplotcurve_coors_cmd_tl } % { (coor-1)(coor-2)...(coor-n) } \l_tzplotcurve_code_at_end_tl % should precede _nodes_cmd_tl \l_tzplotcurve_nodes_cmd_tl % (coor-i) node [opt] {text}, for all i ; } %%% --- end of \tzplotcurve %%% \tzLFn -- plot Linear Function (LF) \bool_new:N \g_tzLFn_BEGIN_cmd_bool \bool_new:N \g_tzLFn_END_cmd_bool %% \tzLFnAtBegin \NewDocumentCommand\tzLFnAtBegin{ m } { \bool_gset_true:N \g_tzLFn_BEGIN_cmd_bool \tl_gset:No \g_tzLFn_BEGIN_cmd_tl { #1 } } %% \tzLFnAtEnd \NewDocumentCommand\tzLFnAtEnd{ m } { \bool_gset_true:N \g_tzLFn_END_cmd_bool \tl_gset:No \g_tzLFn_END_cmd_tl { #1 } } %%% \tzLFn %% \tzLFn : variable = \x (default) %% \tzLFn': variable = \y \NewDocumentCommand \tzLFn { t' o D<>{0,0} d"" } { \tl_clear:N \l_tzLFn_cmd_tl \IfBooleanTF { #1 } { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \IfValueTF { #3 } { \tl_set:Nn \l_tzLFn_shift_tl { shift = { (#3) } } } { \tl_clear:N \l_tzLFn_shift_tl } \IfValueTF { #2 } { \tl_set:Nn \l_tzLFn_opt_tl { #2 } } { \tl_clear:N \l_tzLFn_opt_tl } \IfValueTF { #4 } { \tl_set:Nn \l_tzLFn_namepath_tl { name~path = #4 } } { \tl_clear:N \l_tzLFn_namepath_tl } \tzLFn_check_token:n } \cs_new:Npn \tzLFn_check_token:n #1 { \str_if_eq:nnT { #1 } { ( } { \tzLFn_sub_fn ( } } \use:x{ \NewDocumentCommand \exp_not:N \tzLFn_sub_fn { r() d() G{1} >{ \SplitArgument {1} { \tl_to_str:n {:} } } r[] + G{} O{} D<>{} } } { \tzLFn_domain_process #4 \tl_put_right:Nx \l_tzLFn_cmd_tl { [ \l_tzLFn_namepath_tl , domain = \tzLFnFromVal \c_colon_str \tzLFnToVal , %%% [here?] % samples = 200 , \bool_if:NTF \l_tmpa_bool { variable = \exp_not:n { \y } } { variable = \exp_not:n { \x } } , \l_tzLFn_shift_tl , } \tl_put_right:No \l_tzLFn_cmd_tl { \l_tzLFn_opt_tl ] } \bool_if:NT \g_tzLFn_BEGIN_cmd_bool { \tl_put_right:No \l_tzLFn_cmd_tl { \g_tzLFn_BEGIN_cmd_tl } } % define LF \tzgetxyval(#1){\tzLFAval}{\tzLFBval} \IfNoValueTF { #2 } { \bool_if:NTF \l_tmpa_bool { \def\tzLFnDEF{#3*(\y-\tzLFBval)+\tzLFAval} } { \def\tzLFnDEF{#3*(\x-\tzLFAval)+\tzLFBval} } } { \tzgetxyval(#2){\tzLFAAval}{\tzLFBBval} \bool_if:NTF \l_tmpa_bool { \edef\tzLFSlope{(\tzLFAAval-\tzLFAval)/(\tzLFBBval-\tzLFBval)} \def\tzLFnDEF{\tzLFSlope*(\y-\tzLFBval)+\tzLFAval} } { \edef\tzLFSlope{(\tzLFBBval-\tzLFBval)/(\tzLFAAval-\tzLFAval)} \def\tzLFnDEF{\tzLFSlope*(\x-\tzLFAval)+\tzLFBval} } } \bool_if:NTF \l_tmpa_bool { \tl_put_right:Nn \l_tzLFn_cmd_tl { plot ( { \tzLFnDEF } , \y ) } % \y should not be expanded } { \tl_put_right:Nn \l_tzLFn_cmd_tl { plot ( \x , { \tzLFnDEF } ) } % \x should not be expanded } \bool_if:NT \g_tzLFn_END_cmd_bool { \tl_put_right:No \l_tzLFn_cmd_tl { \g_tzLFn_END_cmd_tl } } \tl_put_right:Nn \l_tzLFn_cmd_tl { node [ #6 ] { #5 } } % final action \exp_last_unbraced:Nf \draw \l_tzLFn_cmd_tl #7 ; \bool_gset_false:N \g_tzLFn_BEGIN_cmd_bool \bool_gset_false:N \g_tzLFn_END_cmd_bool } \NewDocumentCommand\tzLFn_domain_process{ m m } { \def\tzLFnFromVal{#1} \def\tzLFnToVal{#2} } %%% --- end of \tzLFn %% \tzfn (variable=\x -- default) \bool_new:N \g_tzfn_BEGIN_cmd_bool \bool_new:N \g_tzfn_END_cmd_bool %% \tzfnAtBegin \NewDocumentCommand\tzfnAtBegin{ m } { \bool_gset_true:N \g_tzfn_BEGIN_cmd_bool \tl_gset:No \g_tzfn_BEGIN_cmd_tl { #1 } } %% \tzfnAtEnd \NewDocumentCommand\tzfnAtEnd{ m } { \bool_gset_true:N \g_tzfn_END_cmd_bool \tl_gset:No \g_tzfn_END_cmd_tl { #1 } } %% \tzfn (variable=\x) %% \tzfn' (variable=\y) -- equivalent to \tzfnofy \use:x{ \NewDocumentCommand \exp_not:N \tzfn { t' O{} D<>{0,0} D""{} m >{ \SplitArgument {1} { \tl_to_str:n {:} } } r[] +G{} O{} D<>{} } } { \tl_clear:N \l_tzfn_cmd_tl \IfBooleanTF { #1 } { \bool_set_true:N \l_tmpa_bool } { \bool_set_false:N \l_tmpa_bool } \tzfn_domain_process #6 \tl_set:No \l_tmpa_tl { \tl_to_str:n { #5 } } \tl_set:No \l_tzfn_pathname_tl { \tl_tail:N \l_tmpa_tl } \tl_put_right:Nx \l_tzfn_cmd_tl { [ name~path = \tl_if_empty:nTF { #4 } { \l_tzfn_pathname_tl } { #4 } , domain = \tzfnFromVal \c_colon_str \tzfnToVal , samples = 200 , shift = { (#3) } , \bool_if:NTF \l_tmpa_bool { variable = \exp_not:n { \y } } { variable = \exp_not:n { \x } } , \exp_not:n { #2 } ] } \bool_if:NT \g_tzfn_BEGIN_cmd_bool { \tl_put_right:No \l_tzfn_cmd_tl { \g_tzfn_BEGIN_cmd_tl } } \bool_if:NTF { \l_tmpa_bool } { \tl_put_right:Nn \l_tzfn_cmd_tl { plot ( { #5 } , \y ) } % \y should not be expanded } { \tl_put_right:Nn \l_tzfn_cmd_tl { plot ( \x , { #5 } ) } % \x should not be expanded } \bool_if:NT \g_tzfn_END_cmd_bool { \tl_put_right:No \l_tzfn_cmd_tl { \g_tzfn_END_cmd_tl } } \tl_put_right:Nn \l_tzfn_cmd_tl { node [ #8 ] { #7 } } % final action \exp_last_unbraced:Nf \draw \l_tzfn_cmd_tl #9 ; \bool_gset_false:N \g_tzfn_BEGIN_cmd_bool \bool_gset_false:N \g_tzfn_END_cmd_bool } \NewDocumentCommand\tzfn_domain_process{ m m } { \def\tzfnFromVal{#1} \def\tzfnToVal{#2} } %%% --- end of \tzfn %% \tzvfnat \use:x{ \NewDocumentCommand \exp_not:N \tzvfnat { O{} D<>{0,0} D""{} m >{ \SplitArgument {1} { \tl_to_str:n {:} } } d[] +G{} O{} D<>{} } } { \tl_clear:N \l_tzvfnat_cmd_tl \IfValueT { #5 } { \tzvfnat_domain_process #5 } \tl_put_right:Nx \l_tzvfnat_cmd_tl { [ name~path = #3 , shift = { (#2) } , % samples = 200 , \exp_not:n { #1 } ] } \IfValueTF { #5 } { \tl_put_right:Nn \l_tzvfnat_cmd_tl { (#4,\tzvfnatFromVal) -- (#4,\tzvfnatToVal) } } { \tl_put_right:Nn \l_tzvfnat_cmd_tl { (#4,0 |- current~bounding~box.south) -- (#4,0 |- current~bounding~box.north) } } \tl_put_right:Nn \l_tzvfnat_cmd_tl { node [ #7 ] { #6 } } % final action \exp_last_unbraced:Nf \draw \l_tzvfnat_cmd_tl #8 ; } \NewDocumentCommand\tzvfnat_domain_process{ m m } { \def\tzvfnatFromVal{#1} \def\tzvfnatToVal{#2} } %%% --- end of \tzvfnat %%% \tzvfn (On) -- vertical line through (x,y) %%% \tzvfn \use:x{ \NewDocumentCommand \exp_not:N \tzvfn { O{} d<> D""{} r() >{ \SplitArgument {1} { \tl_to_str:n {:} } } d[] +G{} O{} D<>{} } } { \tl_clear:N \l_tzvfn_cmd_tl \IfValueT { #5 } { \tzvfn_domain_process #5 } \tl_put_right:Nx \l_tzvfn_cmd_tl { [ name~path = #3 , \exp_not:n { #1 } ] } \IfValueTF { #5 } { \IfValueTF { #2 } { \tl_put_right:Nn \l_tzvfn_cmd_tl { ([shift = { (#2) }]#4 |- 0,\tzvfnFromVal) -- ([shift = { (#2) }]#4 |- 0,\tzvfnToVal) } } { \tl_put_right:Nn \l_tzvfn_cmd_tl { (#4 |- 0,\tzvfnFromVal) -- (#4 |- 0,\tzvfnToVal) } } } { \IfValueTF { #2 } { \tl_put_right:Nn \l_tzvfn_cmd_tl { ([shift = { (#2) }]#4 |- current~bounding~box.south) -- ([shift = { (#2) }]#4 |- current~bounding~box.north) } } { \tl_put_right:Nn \l_tzvfn_cmd_tl { (#4 |- current~bounding~box.south) -- (#4 |- current~bounding~box.north) } } } \tl_put_right:Nn \l_tzvfn_cmd_tl { node [ #7 ] { #6 } } % final action \exp_last_unbraced:Nf \draw \l_tzvfn_cmd_tl #8 ; } \NewDocumentCommand\tzvfn_domain_process{ m m } { \def\tzvfnFromVal{#1} \def\tzvfnToVal{#2} } %%% --- end of \tzvfn %% \tzhfnat \use:x{ \NewDocumentCommand \exp_not:N \tzhfnat { O{} D<>{0,0} D""{} m >{ \SplitArgument {1} { \tl_to_str:n {:} } } d[] +G{} O{} D<>{} } } { \tl_clear:N \l_tzhfnat_cmd_tl \IfValueT { #5 } { \tzhfnat_domain_process #5 } \tl_put_right:Nx \l_tzhfnat_cmd_tl { [ name~path = #3 , shift = { (#2) } , variable = \exp_not:n { \x } , \exp_not:n { #1 } ] } \IfValueTF { #5 } { \tl_put_right:Nn \l_tzhfnat_cmd_tl { (\tzhfnatFromVal,#4) -- (\tzhfnatToVal,#4) } } { \tl_put_right:Nn \l_tzhfnat_cmd_tl { (0,#4 -| current~bounding~box.west) -- (0,#4 -| current~bounding~box.east) } } \tl_put_right:Nn \l_tzhfnat_cmd_tl { node [ #7 ] { #6 } } % final action \exp_last_unbraced:Nf \draw \l_tzhfnat_cmd_tl #8 ; } \NewDocumentCommand\tzhfnat_domain_process{ m m } { \def\tzhfnatFromVal{#1} \def\tzhfnatToVal{#2} } %%% --- end of \tzhfnat %%% \tzhfn (On) -- horizontal line through (x,y) %% \tzhfn \use:x{ \NewDocumentCommand \exp_not:N \tzhfn { O{} d<> D""{} r() >{ \SplitArgument {1} { \tl_to_str:n {:} } } d[] +G{} O{} D<>{} } } { \tl_clear:N \l_tzhfn_cmd_tl \IfValueT { #5 } { \tzhfn_domain_process #5 } \tl_put_right:Nx \l_tzhfn_cmd_tl { [ name~path = #3 , variable = \exp_not:n { \x } , \exp_not:n { #1 } ] } \IfValueTF { #5 } { \IfValueTF { #2 } { \tl_put_right:Nn \l_tzhfn_cmd_tl { ([shift = { (#2) }]\tzhfnFromVal,0 |- #4) -- ([shift = { (#2) }]\tzhfnToVal,0 |- #4) } } { \tl_put_right:Nn \l_tzhfn_cmd_tl { (\tzhfnFromVal,0 |- #4) -- (\tzhfnToVal,0 |- #4) } } } { \IfValueTF { #2 } { \tl_put_right:Nn \l_tzhfn_cmd_tl { ([shift = { (#2) }]#4 -| current~bounding~box.west) -- ([shift = { (#2) }]#4 -| current~bounding~box.east) } } { \tl_put_right:Nn \l_tzhfn_cmd_tl { (#4 -| current~bounding~box.west) -- (#4 -| current~bounding~box.east) } } } \tl_put_right:Nn \l_tzhfn_cmd_tl { node [ #7 ] { #6 } } % final action \exp_last_unbraced:Nf \draw \l_tzhfn_cmd_tl #8 ; } \NewDocumentCommand\tzhfn_domain_process{ m m } { \def\tzhfnFromVal{#1} \def\tzhfnToVal{#2} } %%% --- end of \tzhfn %%%%% Intersections %%% \tzXpoint -- intersection point of two paths \NewDocumentCommand\tzXpoint { s O{} m m D(){intersection} O{1} +G{} O{} D(){\tz@initial@dot@size} } { \tl_clear:N \l_tzXpoint_cmd_tl \path [ name~intersections = { of = #3 ~ and ~ #4 , name = #5 } ] ; \tl_put_right:Nn \l_tzXpoint_cmd_tl { (#5-#6) coordinate (#5) \IfBooleanTF {#1} { node [ tzdot , fill , minimum~size = #9 , } { node [ tzdot , draw = none , minimum~size = 0pt , } } \tl_put_right:Nx \l_tzXpoint_cmd_tl { label = { \exp_not:n { #8 } \c_colon_str \exp_not:n { #7 } } , } \tl_put_right:Nn \l_tzXpoint_cmd_tl { #2 ] {} } \exp_last_unbraced:Nf \path \l_tzXpoint_cmd_tl ; } %%% --- end of \tzXpoint %%% \tzvXpointat -- vertical intersection point at x %%% *[]{}()()[]{