From 5f1f54a9110f9c39663d8ea100d2405d1f2f2627 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 1 Mar 2021 22:36:39 +0000 Subject: tzplot (1mar21) git-svn-id: svn://tug.org/texlive/trunk@58018 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/tzplot/tzplot.sty | 4590 +++++++++++++++++++++++++ 1 file changed, 4590 insertions(+) create mode 100644 Master/texmf-dist/tex/latex/tzplot/tzplot.sty (limited to 'Master/texmf-dist/tex/latex/tzplot') diff --git a/Master/texmf-dist/tex/latex/tzplot/tzplot.sty b/Master/texmf-dist/tex/latex/tzplot/tzplot.sty new file mode 100644 index 00000000000..593659b03f9 --- /dev/null +++ b/Master/texmf-dist/tex/latex/tzplot/tzplot.sty @@ -0,0 +1,4590 @@ +%% 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 +%%% *[]{}()()[]{