summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/tzplot
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-03-01 22:36:39 +0000
committerKarl Berry <karl@freefriends.org>2021-03-01 22:36:39 +0000
commit5f1f54a9110f9c39663d8ea100d2405d1f2f2627 (patch)
treebdb78ca11335a955cc587cfdaf8e31fcd170961f /Master/texmf-dist/tex/latex/tzplot
parent7b272d39764ec7dafbce7e98d52d89725716b633 (diff)
tzplot (1mar21)
git-svn-id: svn://tug.org/texlive/trunk@58018 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/tzplot')
-rw-r--r--Master/texmf-dist/tex/latex/tzplot/tzplot.sty4590
1 files changed, 4590 insertions, 0 deletions
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 <ischo at ktug.org>
+%%
+%% 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]<shift>(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)
+%%% *[<opt>]<shift>(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
+
+%%% *[<opt>]<shift> (){}[] (){}[] 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]<radius> ()(){}[] ()(){}[] 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
+%%% *[<opt>]{<path>}(<coor>)(<coor name>)[<nth>]{<label>}[<[<opt>]angle>](<dotsize>)
+\NewDocumentCommand\tzvXpointat
+ { s O{} m m D(){intersection} O{1} +G{} O{} D(){\tz@initial@dot@size} }
+{
+ \tl_clear:N \l_tzvXpointat_cmd_tl
+
+ \tzvfnat[draw=none]"tzvXpoint-At" {#4} % depends on (current bounding box)
+
+ \path [ name~intersections = { of = tzvXpoint-At ~and~ #3 , name = #5 } ] ;
+
+ \tl_put_right:Nn \l_tzvXpointat_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_tzvXpointat_cmd_tl
+ {
+ label = { \exp_not:n { #8 } \c_colon_str \exp_not:n { #7 } } ,
+ }
+
+ \tl_put_right:Nn \l_tzvXpointat_cmd_tl
+ {
+ #2
+ ] {}
+ }
+
+ \exp_last_unbraced:Nf \path \l_tzvXpointat_cmd_tl ;
+ \tl_clear:N \tzvXpointat_cmd_tl
+}
+
+%%% --- end of \tzvXpointat
+
+
+%%% \tzvXpoint (On)
+%%% -- vertical intersection point at (x,y) of a path
+%%% *[<opt>]{<path>}(<coor>)(<coor name>)[<nth>]{<label>}[<[<opt>]angle>](<dotsize>)
+\NewDocumentCommand\tzvXpoint
+ { s O{} m r() D(){intersection} O{1} +G{} O{} D(){\tz@initial@dot@size} }
+{
+ \tl_clear:N \l_tzvXpoint_cmd_tl
+
+ \tzvfn[draw=none]"tzvXpoint-On"(#4) % depends on (current bounding box)
+
+ \path [ name~intersections = { of = tzvXpoint-On ~and~ #3 , name = #5 } ] ;
+ \tl_put_right:Nn \l_tzvXpoint_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_tzvXpoint_cmd_tl
+ {
+ label = { \exp_not:n { #8 } \c_colon_str \exp_not:n { #7 } } ,
+ }
+
+ \tl_put_right:Nn \l_tzvXpoint_cmd_tl
+ {
+ #2
+ ] {}
+ }
+
+ \exp_last_unbraced:Nf \path \l_tzvXpoint_cmd_tl ;
+ \tl_clear:N \l_tzvXpoint_cmd_tl
+}
+
+%%% --- end of \tzvXpoint
+
+
+
+%%% \tzhXpointat -- horizontal intersection point at y
+\NewDocumentCommand\tzhXpointat
+ { s O{} m m D(){intersection} O{1} +G{} O{} D(){\tz@initial@dot@size} }
+{
+ \tl_clear:N \l_tzhXpointat_cmd_tl
+
+ \tzhfnat[draw=none]"tzhXpoint-At"{#4} % depends on (current bounding box)
+
+ \path [ name~intersections = { of = tzhXpoint-At ~and~ #3 , name = #5 } ] ;
+ \tl_put_right:Nn \l_tzhXpointat_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_tzhXpointat_cmd_tl
+ {
+ label = { \exp_not:n { #8 } \c_colon_str \exp_not:n { #7 } } ,
+ }
+
+ \tl_put_right:Nn \l_tzhXpointat_cmd_tl
+ {
+ #2
+ ] {}
+ }
+
+ \exp_last_unbraced:Nf \path \l_tzhXpointat_cmd_tl ;
+ \tl_clear:N \l_tzhXpointat_cmd_tl
+}
+
+%%% --- end of \tzhXpointat
+
+
+%%% \tzhXpoint (On) -- horizontal intersection point at (x,y)
+\NewDocumentCommand\tzhXpoint
+ { s O{} m r() D(){intersection} O{1} +G{} O{} D(){\tz@initial@dot@size} }
+{
+ \tl_clear:N \l_tzhXpoint_cmd_tl
+
+ \tzhfn[draw=none]"tzhXpoint-On"(#4) % depends on (current bounding box)
+
+ \path [ name~intersections = { of = tzhXpoint-On ~and~ #3 , name = #5 } ] ;
+
+ \tl_put_right:Nn \l_tzhXpoint_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_tzhXpoint_cmd_tl
+ {
+ label = { \exp_not:n { #8 } \c_colon_str \exp_not:n { #7 } } ,
+ }
+
+ \tl_put_right:Nn \l_tzhXpoint_cmd_tl
+ {
+ #2
+ ] {}
+ }
+
+ \exp_last_unbraced:Nf \path \l_tzhXpoint_cmd_tl ;
+ \tl_clear:N \l_tzhXpoint_cmd_tl
+}
+
+%%% --- end of \tzhXpoint
+
+
+
+%%%%% Axes
+
+%%% \tzaxes
+
+\NewDocumentCommand\tzaxes{ s O{} D<>{0,0} r() d() +G{} O{} +G{} O{} }
+{
+ \IfNoValueTF { #5 }
+ {
+ \draw [ -> , #2 ]
+ ( 0,0 |- #3 ) -- ( #4 |- #3 ) node [ right , #7 ] { #6 } ;
+ \draw [ -> , #2 ]
+ ( #3 |- 0,0 ) -- ( #3 |- #4 ) node [ above , #9 ] { #8 } ;
+ }
+ {
+ \draw [ -> , #2 ]
+ ( #4 |- #3 ) -- ( #5 |- #3 ) node [ right , #7 ] { #6 } ;
+ \draw [ -> , #2 ]
+ ( #3 |- #4 ) -- ( #3 |- #5 ) node [ above , #9 ] { #8 } ;
+ }
+ \IfBooleanT { #1 }
+ {
+ \coordinate (bbxOpposite) at (current~bounding~box.north~east) ;
+ \coordinate (bbxOrigin) at (current~bounding~box.south~west) ;
+ \useasboundingbox (bbxOrigin) rectangle (bbxOpposite) ;
+ }
+}
+
+%%% \tzaxesL -- simpler version of \tzaxes
+
+\NewDocumentCommand\tzaxesL{ t' O{} d<> r() r() +G{} O{} +G{} O{} }
+{
+ \IfBooleanTF { #1 }
+ {
+ \draw [ #2 ]
+ \IfValueTF { #3 }
+ {
+ ( [shift={(#3)}]#5 ) -- ( [shift={(#3)}]#4 |- #5 )
+ }
+ {
+ ( #5 ) -- ( #4 |- #5 )
+ }
+ node [ left , #7 ] { #6 } ;
+ \draw [ #2 ]
+ \IfValueTF { #3 }
+ {
+ ( [shift={(#3)}]#5 ) -- ( [shift={(#3)}]#5 |- #4 )
+ }
+ {
+ ( #5 ) -- ( #5 |- #4 )
+ }
+ node [ below , #9 ] { #8 } ;
+ }
+ {
+ \draw [ #2 ]
+ \IfValueTF { #3 }
+ {
+ ( [shift={(#3)}]#4 ) -- ( [shift={(#3)}]#5 |- #4 )
+ }
+ {
+ ( #4 ) -- ( #5 |- #4 )
+ }
+ node [ right , #7 ] { #6 } ;
+ \draw [ #2 ]
+ \IfValueTF { #3 }
+ {
+ ( [shift={(#3)}]#4 ) -- ( [shift={(#3)}]#4 |- #5 )
+ }
+ {
+ ( #4 ) -- ( #4 |- #5 )
+ }
+ node [ above , #9 ] { #8 } ;
+ }
+}
+
+%%% -- end of \tzaxesL
+
+%%% \tzaxisx
+
+\NewDocumentCommand\tzaxisx{ s O{} D<>{0} m m G{} O{} }
+{
+ \draw [ -> , #2 ]
+ ( #4 , #3 ) -- ( #5 , #3 ) node [ right , #7 ] { #6 } ;
+}
+
+%%% \tzaxisy
+
+\NewDocumentCommand\tzaxisy{ s O{} D<>{0} m m G{} O{} }
+{
+ \draw [ -> , #2 ]
+ ( #3 , #4 ) -- ( #3 , #5 ) node [ above , #7 ] { #6 } ;
+}
+
+
+%%%%% Ticks
+
+%%% \tztikcs : (combine \tzticksx and \tzticksy)
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tzticks
+ { s O{} D<>{0,0}
+ >{ \SplitArgument {1} { \tl_to_str:n {:} } } d() m O{}
+ >{ \SplitArgument {1} { \tl_to_str:n {:} } } d() G{} O{}
+ }
+}
+{
+ \tzgetxyval(#3){\tzticksXshift}{\tzticksYshift}
+ \IfValueT { #4 } { \tzticks_Xlength_process #4 }
+ %% ------
+ \IfValueT { #7 } { \tzticks_Ylength_process #7 }
+
+ \IfBooleanTF { #1 }
+ {
+ \IfNoValueT { #4 }
+ {
+ \def\tzticksXFromVal{0pt}
+ \def\tzticksXToVal{3pt}
+ }
+ \foreach \xx / \tzXtext in { #5 }
+ \draw [ shift = {(0,\tzticksYshift)} , #2 ]
+ (\xx , \tzticksXFromVal)
+ -- (\xx , \tzticksXToVal) ; % ignores \txXtext
+ %% --------
+ \IfNoValueT { #7 }
+ {
+ \def\tzticksYFromVal{0pt}
+ \def\tzticksYToVal{3pt}
+ }
+ \foreach \yy/\tzYtext in { #8 }
+ \draw [ shift = {(\tzticksXshift,0)} , #2 ]
+ (\tzticksYFromVal , \yy)
+ -- (\tzticksYToVal , \yy) ; % ignores \txXtext
+ }
+ {
+ \IfNoValueT { #4 }
+ {
+ \def\tzticksXFromVal{0pt}
+ \def\tzticksXToVal{0pt}
+ }
+ \foreach \xx / \tzXtext in { #5 }
+ \draw [ shift = {(0,\tzticksYshift)} , #2 ]
+ (\xx ,\tzticksXFromVal)
+ -- (\xx , \tzticksXToVal)
+ (\xx , 0 ) node
+ [ text~height = 1.25ex ,
+ text~depth = .25ex ,
+ below , #6 ] {\tzXtext} ;
+ %% --------
+ \IfNoValueT { #7 }
+ {
+ \def\tzticksYFromVal{0pt}
+ \def\tzticksYToVal{0pt}
+ }
+ \foreach \yy / \tzYtext in { #8 }
+ \draw [ shift = {(\tzticksXshift,0)} , #2 ]
+ (\tzticksYFromVal , \yy)
+ -- (\tzticksYToVal , \yy)
+ (0 , \yy)
+ node [ left , #9 ] { \tzYtext } ;
+ }
+}
+
+\NewDocumentCommand\tzticks_Xlength_process { m m }
+{
+ \def\tzticksXFromVal{#1}
+ \def\tzticksXToVal{#2}
+}
+%% --------
+\NewDocumentCommand\tzticks_Ylength_process { m m }
+{
+ \def\tzticksYFromVal{#1}
+ \def\tzticksYToVal{#2}
+}
+
+%%% --- end of \tzticks
+
+
+%%% \tztikcsx -- ticks and labels along the x axis
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tzticksx
+ { s O{} D<>{0}
+ >{ \SplitArgument {1} { \tl_to_str:n {:} } } d() m O{}
+ }
+}
+{
+ \IfValueT { #4 } { \tzticksx_length_process #4 }
+
+ \IfBooleanTF { #1 }
+ {
+ \IfNoValueT { #4 }
+ {
+ \def\tzticksxFromVal{0pt}
+ \def\tzticksxToVal{3pt}
+ }
+ \foreach \xx / \tzxtext in { #5 }
+ \draw [ shift = {(0,#3)} , #2 ]
+ (\xx , \tzticksxFromVal)
+ -- (\xx , \tzticksxToVal) ;
+ }
+ {
+ \IfNoValueT { #4 }
+ {
+ \def\tzticksxFromVal{0pt}
+ \def\tzticksxToVal{0pt}
+ }
+ \foreach \xx / \tzxtext in { #5 }
+ \draw [ shift = {(0,#3)} , #2 ]
+ (\xx ,\tzticksxFromVal)
+ -- (\xx , \tzticksxToVal)
+ (\xx , 0 ) node
+ [ text~height = 1.25ex ,
+ text~depth = .25ex ,
+ below , #6 ] {\tzxtext} ;
+
+ }
+}
+
+\NewDocumentCommand\tzticksx_length_process { m m }
+{
+ \def\tzticksxFromVal{#1}
+ \def\tzticksxToVal{#2}
+}
+
+%%% --- end of \tzticksx
+
+
+%%% \tztikcsy -- ticks and labels along with the y axis
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tzticksy
+ { s O{} D<>{0}
+ >{ \SplitArgument {1} { \tl_to_str:n {:} } } d() m O{}
+ }
+}
+{
+
+ \IfValueT { #4 } { \tzticksy_length_process #4 }
+
+ \IfBooleanTF { #1 }
+ {
+ \IfNoValueT { #4 }
+ {
+ \def\tzticksyFromVal{0pt}
+ \def\tzticksyToVal{3pt}
+ }
+ \foreach \yy/\tzytext in { #5 }
+ \draw [ shift = {(#3,0)} , #2 ]
+ (\tzticksyFromVal , \yy)
+ -- (\tzticksyToVal , \yy) ;
+ }
+ {
+ \IfNoValueT { #4 }
+ {
+ \def\tzticksyFromVal{0pt}
+ \def\tzticksyToVal{0pt}
+ }
+ \foreach \yy / \tzytext in { #5 }
+ \draw [ shift = {(#3,0)} , #2 ]
+ (\tzticksyFromVal , \yy)
+ -- (\tzticksyToVal , \yy)
+ (0 , \yy)
+ node [ left , #6 ] { \tzytext } ;
+ }
+}
+
+\NewDocumentCommand\tzticksy_length_process { m m }
+{
+ \def\tzticksyFromVal{#1}
+ \def\tzticksyToVal{#2}
+}
+
+%%% --- end of \tzticksy
+
+
+%%%%% Projections
+%% lines and tick labels of projection onto x/y axis
+
+%%% \tzproj
+
+\NewDocumentCommand\tzproj
+ { s O{} d<> r() G{} O{} G{} O{} D(){\tz@initial@dot@size} }
+{
+ \IfValueTF { #3 }
+ { \coordinate (tzProj) at (#3) ; }
+ { \coordinate (tzProj) at (0,0) ; }
+ \draw [ dotted , #2 ]
+ (#4 |- tzProj)
+ node [ text~height = 1.25ex ,
+ text~depth = .25ex ,
+ below , #6 ] { #5 }
+ -- (#4) -- (tzProj |- #4)
+ node [ left , #8 ] {#7} ;
+ \IfBooleanT {#1} { \tzdot*(#4)(#9) }
+}
+
+%%% \tzprojx
+
+\NewDocumentCommand\tzprojx
+ { s O{} d<> r() G{} O{} D(){\tz@initial@dot@size} }
+{
+ \IfValueTF { #3 }
+ { \coordinate (tzProjx) at (#3) ; }
+ { \coordinate (tzProjx) at (0,0) ; }
+ \draw [ dotted , #2 ] (#4)
+ -- (#4 |- tzProjx)
+ node [ text~height = 1.25ex ,
+ text~depth = .25ex ,
+ below , #6 ] { #5 } ;
+ \IfBooleanT { #1 } { \tzdot*(#4)(#7) }
+}
+
+%%% \tzprojy
+
+\NewDocumentCommand\tzprojy
+ { s O{} d<> r() G{} O{} D(){\tz@initial@dot@size} }
+{
+ \IfValueTF { #3 }
+ { \coordinate (tzProjy) at (#3) ; }
+ { \coordinate (tzProjy) at (0,0) ; }
+ \draw [ dotted , #2 ] (#4)
+ -- (#4 -| tzProjy)
+ node [ left , #6 ] { #5 } ;
+ \IfBooleanT { #1 } { \tzdot*(#4)(#7) }
+}
+
+
+%%%%% Nodes
+
+%%% \tznode -- putting texts (and labels as option)
+
+\NewDocumentCommand\tznode{ s O{} d<> r() D(){tzNodeName} +G{} O{} }
+{
+ \IfBooleanTF { #1 }
+ {
+ \IfValueTF { #3 }
+ { \node [ draw , #2 ] (#5) at ([shift={(#3)}]#4) [ #7 ] { #6 } ; }
+ { \node [ draw , #2 ] (#5) at (#4) [ #7 ] { #6 } ; }
+ }
+ {
+ \IfValueTF { #3 }
+ { \node [ #2 ] (#5) at ([shift={(#3)}]#4) [ #7 ] { #6 } ; }
+ { \node [ #2 ] (#5) at (#4) [ #7 ] { #6 } ; }
+ }
+}
+
+
+%%% \tznodedot
+\NewDocumentCommand\tznodedot
+ { s O{} d<> r() D(){tzNodeName} +G{} O{} D(){\tz@initial@dot@size} }
+{
+ \tl_clear:N \l_tznodedot_cmd_tl
+
+ \renewcommand\tzdotsize{ #8 }
+
+ \IfValueTF { #3 }
+ {% if shift
+ \tl_put_right:Nn \l_tznodedot_cmd_tl
+ { ([shift={(#3)}]#4) node (#5) }
+ }
+ {% no shift (normal)
+ \tl_put_right:Nn \l_tznodedot_cmd_tl
+ { (#4) node (#5) }
+ }
+ \IfBooleanTF { #1 }
+ {
+ \tl_put_right:Nn \l_tznodedot_cmd_tl { [ tzdot , fill , }
+ }
+ {
+ \tl_put_right:Nn \l_tznodedot_cmd_tl { [ tzdot , }
+ }
+ \tl_put_right:Nx \l_tznodedot_cmd_tl
+ {
+ label = { \exp_not:n { #7 } \c_colon_str \exp_not:n { #6 } } ,
+ }
+ \tl_put_right:Nn \l_tznodedot_cmd_tl
+ {
+ minimum~size = \tzdotsize , #2 ] {}
+ }
+ \exp_last_unbraced:Nf \path \l_tznodedot_cmd_tl ;
+}
+
+%%% --- end of \tznodedot
+
+
+
+%%% \tznodeframe
+
+\NewDocumentCommand\tznodeframe
+ { s O{} d<> r() D(){tzNodeName} +G{} O{} G{\tz@initial@fill@opacity} }
+{
+ \renewcommand\tzfillopacity{#8}
+ \IfBooleanTF { #1 }
+ {
+ \node [
+ draw , rectangle ,
+ fill ,
+ fill~opacity = \tzfillopacity , text~opacity = 1 ,
+ #2
+ ]
+ (#5) at \IfValueTF { #3 } { ([shift={(#3)}]#4) } { (#4) }
+ [ draw = black , text = black , #7 ] { #6 } ;
+ }
+ {
+ \node [ draw , rectangle , #2 ]
+ (#5) at \IfValueTF { #3 } { ([shift={(#3)}]#4) } { (#4) }
+ [ text = black , #7 ] { #6 } ;
+ }
+}
+
+
+%%% \tznodebox \tznoderectangle
+\let\tznodebox\tznodeframe
+\let\tznoderectangle\tznodeframe
+
+
+%%% \tznodecircle
+
+\NewDocumentCommand\tznodecircle
+ { s O{} d<> r() D(){tzNodeName} +G{} O{} G{\tz@initial@fill@opacity} }
+{
+ \renewcommand\tzfillopacity{#8}
+ \IfBooleanTF { #1 }
+ {
+ \node [
+ draw , circle ,
+ fill ,
+ fill~opacity = \tzfillopacity , text~opacity = 1 ,
+ #2
+ ]
+ (#5) at \IfValueTF { #3 } { ([shift={(#3)}]#4) } { (#4) }
+ [ draw = black , text = black , #7 ] { #6 } ;
+ }
+ {
+ \node [ draw , circle , #2 ]
+ (#5) at \IfValueTF { #3 } { ([shift={(#3)}]#4) } { (#4) }
+ [ text = black , #7 ] { #6 } ;
+ }
+}
+
+%%% \tznodeellipse
+
+\NewDocumentCommand\tznodeellipse
+ { s O{} d<> r() D(){tzNodeName} +G{} O{} G{\tz@initial@fill@opacity} }
+{
+ \renewcommand\tzfillopacity{#8}
+ \IfBooleanTF { #1 }
+ {
+ \node [
+ draw , ellipse ,
+ fill ,
+ fill~opacity = \tzfillopacity , text~opacity = 1 ,
+ #2
+ ]
+ (#5) at \IfValueTF { #3 } { ([shift={(#3)}]#4) } { (#4) }
+ [ draw = black , text = black , #7 ] { #6 } ;
+ }
+ {
+ \node [ draw , ellipse , #2 ]
+ (#5) at \IfValueTF { #3 } { ([shift={(#3)}]#4) } { (#4) }
+ [ text = black , #7 ] { #6 } ;
+ }
+}
+
+%%% \tznodeoval
+\let\tznodeoval\tznodeellipse
+
+
+
+%%%%% Secant lines
+
+%% secant line
+
+%%% \tzsecantat
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tzsecantat
+ { s O{} d<> D""{} m m m
+ >{ \SplitArgument { 1 } { \tl_to_str:n {:} } } o
+ }
+}
+{
+ \tl_clear:N \l_tzsecantat_cmd_tl
+
+ \IfBooleanTF { #1 } % NOT USED!
+ { \bool_set_true:N \l_tmpa_bool }
+ { \bool_set_false:N \l_tmpa_bool }
+
+ % define two points
+ \tzvXpointat{#5}{#6}(LX-point) % vertical X point
+ \tzvXpointat{#5}{#7}(RX-point) % vertical X point
+
+ % collect cmd_tl
+
+ \IfNoValueTF { #8 }
+ {
+ \IfValueTF { #3 }
+ {% if shift
+ \tl_put_right:Nn \l_tzsecantat_cmd_tl
+ {
+ [ name~path = #4 , #2 ]
+ ([ shift = { (#3) } ]LX-point) -- ([ shift = { (#3) } ]RX-point)
+ }
+ }
+ {% no shift (normal)
+ \tl_put_right:Nn \l_tzsecantat_cmd_tl
+ {
+ [ name~path = #4 , #2 ]
+ (LX-point) -- (RX-point)
+ }
+ }
+ }
+ {
+ \tzsecantat_domain_process #8
+ \tzgetxyval(LX-point){\tzTANLLX}{\tzTANLLY}
+ \tzgetxyval(RX-point){\tzTANRRX}{\tzTANRRY}
+
+ \edef\tzTANSlope{(\tzTANRRY-\tzTANLLY)/(\tzTANRRX-\tzTANLLX)}
+ \def\tzsecantatLFn{\tzTANSlope*(\x-\tzTANLLX)+\tzTANLLY}
+
+ \IfValueTF { #3 }
+ {% shift
+ \tl_put_right:Nn \l_tzsecantat_cmd_tl
+ {
+ [ name~path = #4 ,
+ shift = { (#3) } ,
+ }
+ }
+ {% no shift (normal)
+ \tl_put_right:Nn \l_tzsecantat_cmd_tl
+ {
+ [ name~path = #4 ,
+ }
+ }
+
+ \tl_put_right:Nx \l_tzsecantat_cmd_tl
+ {
+ domain = \tzsecantatFromVal \c_colon_str \tzsecantatToVal ,
+ }
+ \tl_put_right:Nn \l_tzsecantat_cmd_tl
+ {
+ #2 ]
+ plot ( \x , { \tzsecantatLFn } ) % \x should not be expanded
+ }
+ }
+
+ \tzsecantat_sub_fn:n
+}
+
+\NewDocumentCommand\tzsecantat_domain_process{ m m }
+{
+ \def\tzsecantatFromVal{#1}
+ \def\tzsecantatToVal{#2}
+}
+
+\cs_new:Npn \tzsecantat_sub_fn:n
+{
+ \tzsecantat_final_actions
+}
+
+\NewDocumentCommand\tzsecantat_final_actions { +G{} O{} D<>{} }
+{
+ \begin{pgfonlayer}{\tzsecantlayer}
+ \exp_last_unbraced:Nf \draw \l_tzsecantat_cmd_tl node [ #2 ] { #1 } #3 ;
+ \end{pgfonlayer}
+ % to resolve TikZ issue: unknown path name with layer group
+ \exp_last_unbraced:Nf \path \l_tzsecantat_cmd_tl ;
+}
+
+%%% --- end of \tzsecantat
+
+
+%%% \tzsecant
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tzsecant
+ { s O{} d<> d"" m r() r()
+ >{ \SplitArgument { 1 } { \tl_to_str:n {:} } } o
+ }
+}
+{
+ \tl_clear:N \l_tzsecant_cmd_tl
+
+ \IfBooleanTF { #1 } % NOT USED!
+ { \bool_set_true:N \l_tmpa_bool }
+ { \bool_set_false:N \l_tmpa_bool }
+
+ % define two points
+ \tzvXpoint{#5}(#6)(LX-point) % vertical X point
+ \tzvXpoint{#5}(#7)(RX-point) % vertical X point
+
+ % collect cmd_tl
+ \IfNoValueTF { #8 }
+ {
+ \IfValueTF { #3 }
+ {% if shift
+ \tl_put_right:Nn \l_tzsecant_cmd_tl
+ {
+ [ name~path = #4 , #2 ]
+ ([ shift = { (#3) } ]LX-point) -- ([ shift = { (#3) } ]RX-point)
+ }
+ }
+ {% no shift (normal)
+ \tl_put_right:Nn \l_tzsecant_cmd_tl
+ {
+ [ name~path = #4 , #2 ]
+ (LX-point) -- (RX-point)
+ }
+ }
+ }
+ {
+ \tzsecant_domain_process #8
+ \tzgetxyval(LX-point){\tzTANLLX}{\tzTANLLY}
+ \tzgetxyval(RX-point){\tzTANRRX}{\tzTANRRY}
+
+ \edef\tzTANSlope{(\tzTANRRY-\tzTANLLY)/(\tzTANRRX-\tzTANLLX)}
+ \def\tzsecantLFn{\tzTANSlope*(\x-\tzTANLLX)+\tzTANLLY}
+
+ \IfValueTF { #3 }
+ {% shift
+ \tl_put_right:Nn \l_tzsecant_cmd_tl
+ {
+ [ name~path = #4 ,
+ shift = { (#3) } ,
+ }
+ }
+ {% no shift (normal)
+ \tl_put_right:Nn \l_tzsecant_cmd_tl
+ {
+ [ name~path = #4 ,
+ }
+ }
+
+ \tl_put_right:Nx \l_tzsecant_cmd_tl
+ {
+ domain = \tzsecantFromVal \c_colon_str \tzsecantToVal ,
+ }
+ \tl_put_right:Nn \l_tzsecant_cmd_tl
+ {
+ #2 ]
+ plot ( \x , { \tzsecantLFn } ) % \x should not be expanded
+ }
+ }
+
+ \tzsecant_sub_fn:n
+}
+
+\NewDocumentCommand\tzsecant_domain_process{ m m }
+{
+ \def\tzsecantFromVal{#1}
+ \def\tzsecantToVal{#2}
+}
+
+\cs_new:Npn \tzsecant_sub_fn:n
+{
+ \tzsecant_final_actions
+}
+
+\NewDocumentCommand\tzsecant_final_actions { +G{} O{} D<>{} }
+{
+ \begin{pgfonlayer}{\tzsecantlayer}
+ \exp_last_unbraced:Nf \draw \l_tzsecant_cmd_tl node [ #2 ] { #1 } #3 ;
+ \end{pgfonlayer}
+ % to resolve TikZ issue: unknown path name with layer group
+ \exp_last_unbraced:Nf \path \l_tzsecant_cmd_tl ;
+}
+
+%%% --- end of \tzsecant
+
+
+%%%%% Slope and Tangent
+
+%%% to **resolve** the discrepancy issue due to bounding box
+%%% for \tzslope(at) and \tztangent(at)
+%%% (ndh)
+
+\NewDocumentCommand \IfNodeDefined { m m m }
+{
+ \@ifundefined{pgf@sh@ns@#1}
+ {#3}
+ {#2}
+}
+
+\AddToHook{env/tikzpicture/before}{%
+ \@ifundefined{pgf@sh@ns@bbxBottom}
+ {}
+ { \cs_undefine:N \pgf@sh@ns@bbxBottom }
+ \def\TANCurve{} \def\TANWhere{}
+}
+%\AddToHook{env/tikzpicture/before}{%
+% \@ifundefined{pgf@sh@ns@bbxBottom}
+% {}
+% { \cs_undefine:N \pgf@sh@ns@bbxBottom }
+%}
+
+%%% Do not forget to declare, before final action,
+%%% \gdef\TANCurve{<#m>}\gdef\TANWhere{<#n>}
+
+
+%%%%% Tangent lines
+
+%%% ref. \settztangentepsilon
+
+\bool_new:N \l_tztangentat_bbox_bool
+
+%%% \tztangentat -- tangent to a path at x
+%%% [<opt>]<shift coor>"<path name>"{<path>}{<x>}(<epsilon1>,<epsilon2>)[<from>:<to>]{<text>}[<pos,opt>]<code.append>
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tztangentat
+ { s O{} d<> D""{} m m
+ >{ \SplitArgument { 1 } { , } } d()
+ >{ \SplitArgument { 1 } { \tl_to_str:n {:} } } r[] }
+ }
+{
+ \tl_clear:N \l_tztangentat_cmd_tl
+
+ \IfBooleanTF { #1 } % NOT USED!
+ { \bool_set_true:N \l_tmpa_bool }
+ { \bool_set_false:N \l_tmpa_bool }
+
+ % to resolve discrepancy (due to bounding box), when repeated
+ \bool_if:nTF
+ {
+ \str_if_eq_p:ee { \TANCurve } { #5 } &&
+ \str_if_eq_p:ee { \TANWhere } { #6 }
+ }
+ { \bool_set_true:N \l_tztangentat_bbox_bool }
+ { \bool_set_false:N \l_tztangentat_bbox_bool }
+
+ % for local change of epsilon_1 and _2
+ \IfValueT { #7 }
+ {
+ \tztangentat_epsilon_process #7
+ \renewcommand\tztangentepsilonL{\tztangentatEpsilonOne}
+ \renewcommand\tztangentepsilonR{\tztangentatEpsilonTwo}
+ }
+
+ \tztangentat_domain_process #8
+
+ % getting ready
+ \coordinate (LXcoor) at ($(#6,0)-(\tztangentepsilonL,0)$) ;
+ \coordinate (RXcoor) at ($(#6,0)+(\tztangentepsilonR,0)$) ;
+
+ \bool_if:NTF \l_tztangentat_bbox_bool
+ {
+ \IfNodeDefined{bbxBottom}{}
+ {
+ \coordinate (bbxTop) at (current~bounding~box.north) ;
+ \coordinate (bbxBottom) at (current~bounding~box.south) ;
+ }
+ }
+ {
+ \coordinate (bbxTop) at (current~bounding~box.north) ;
+ \coordinate (bbxBottom) at (current~bounding~box.south) ;
+ }
+
+ % find vertical X points
+ \path [ name~path = C-vline ] (#6,0 |- bbxBottom) -- (#6,0 |- bbxTop) ;
+ \path [ name~intersections = { of = #5 ~ and ~ C-vline , name = TANp } ] ;
+
+ \path [ name~path = L-vline ] (LXcoor |- bbxBottom) -- (LXcoor |- bbxTop) ;
+ \path [ name~intersections = { of = #5 ~ and ~ L-vline , name = LXcut } ] ;
+
+ \path [ name~path = R-vline ] (RXcoor |- bbxBottom) -- (RXcoor |- bbxTop) ;
+ \path [ name~intersections = { of = #5 ~ and ~ R-vline , name = RXcut } ] ;
+
+ % move to tangent point
+ \coordinate (tzXproj)
+ at ($(LXcut-1)!(TANp-1)!(RXcut-1)$); % projection
+ \coordinate (LLpoint)
+ at ($(LXcut-1)+(TANp-1)-(tzXproj)$); % move
+ \coordinate (RRpoint)
+ at ($(RXcut-1)+(TANp-1)-(tzXproj)$); % move
+
+ % determine final extended points
+ \tl_set:Nx \l_tmpa_tl
+ {
+ (RRpoint) -- (TANp-1) --
+ ([turn]0 \c_colon_str ~ -\tztangentatFromVal) coordinate (final-LL)
+ }
+ \tl_set:Nx \l_tmpb_tl
+ {
+ (LLpoint) -- (TANp-1) --
+ ([turn]0 \c_colon_str ~ \tztangentatToVal) coordinate (final-RR)
+ }
+
+ \exp_last_unbraced:Nf \path \l_tmpa_tl ;
+ \exp_last_unbraced:Nf \path \l_tmpb_tl ;
+
+ \tzgetxyval(LLpoint){\tzTANLLX}{\tzTANLLY}
+ \tzgetxyval(RRpoint){\tzTANRRX}{\tzTANRRY}
+
+ \edef\tzTANSlope{(\tzTANRRY-\tzTANLLY)/(\tzTANRRX-\tzTANLLX)}
+ \def\tztangentatLFn{\tzTANSlope*(\x-\tzTANLLX)+\tzTANLLY}
+
+ \IfValueTF { #3 }
+ {
+ \tl_put_right:Nn \l_tztangentat_cmd_tl
+ {
+ [ name~path = #4 ,
+ shift = { (#3) } ,
+ }
+ }
+ {
+ \tl_put_right:Nn \l_tztangentat_cmd_tl
+ {
+ [ name~path = #4 ,
+ }
+ }
+
+ \tl_put_right:Nx \l_tztangentat_cmd_tl
+ {
+ domain = \tztangentatFromVal \c_colon_str \tztangentatToVal ,
+ }
+
+ \tl_put_right:Nn \l_tztangentat_cmd_tl
+ {
+ #2 ]
+ plot ( \x , { \tztangentatLFn } ) % \x should not be expanded
+ }
+
+ \gdef\TANCurve{#5}\gdef\TANWhere{#6}
+
+ \tztangentat_sub_fn:n
+}
+
+\NewDocumentCommand\tztangentat_epsilon_process{ m m }
+{
+ \def\tztangentatEpsilonOne{#1}
+ \def\tztangentatEpsilonTwo{#2}
+}
+
+\NewDocumentCommand\tztangentat_domain_process{ m m }
+{
+ \def\tztangentatFromVal{#1}
+ \def\tztangentatToVal{#2}
+}
+
+\cs_new:Npn \tztangentat_sub_fn:n
+{
+ \tztangentat_final_actions
+}
+
+\NewDocumentCommand\tztangentat_final_actions { +G{} O{} D<>{} }
+{
+ \begin{pgfonlayer}{\tztangentlayer}
+ \exp_last_unbraced:Nf \draw \l_tztangentat_cmd_tl
+ node [ black , above~right , #2 ] { #1 } #3 ;
+ \end{pgfonlayer}
+ % to resolve TikZ issue: unknown path name with layer group
+ \exp_last_unbraced:Nf \path \l_tztangentat_cmd_tl ;
+}
+
+%%% --- end of \tztangentat
+
+
+\bool_new:N \l_tztangent_bbox_bool
+
+%%% \tztangent (On) -- tangent to a path at (x,y)
+%%% [<opt>]<shift coor>"<path name>"{<path>}(<coor>)(<epsilon1>,<epsilon2>)[<from>:<to>]{<text>}[<pos,opt>]<code.append>
+
+\use:x{
+ \NewDocumentCommand \exp_not:N \tztangent
+ { s O{} d<> D""{} m r()
+ >{ \SplitArgument { 1 } { , } } d()
+ >{ \SplitArgument { 1 } { \tl_to_str:n {:} } } r[] }
+ }
+{
+ \tl_clear:N \l_tztangent_cmd_tl
+
+ \IfBooleanTF { #1 } % NOT USED!
+ { \bool_set_true:N \l_tmpa_bool }
+ { \bool_set_false:N \l_tmpa_bool }
+
+ % to resolve discrepancy (due to bounding box), when repeated
+ \bool_if:nTF
+ {
+ \str_if_eq_p:ee { \TANCurve } { #5 } &&
+ \str_if_eq_p:ee { \TANWhere } { #6 }
+ }
+ { \bool_set_true:N \l_tztangent_bbox_bool }
+ { \bool_set_false:N \l_tztangent_bbox_bool }
+
+ % for local change of epsilon_1 and _2
+ \IfValueT { #7 }
+ {
+ \tztangent_epsilon_process #7
+ \renewcommand\tztangentepsilonL{\tztangentEpsilonOne}
+ \renewcommand\tztangentepsilonR{\tztangentEpsilonTwo}
+ }
+
+ \tztangent_domain_process #8
+
+ % getting ready
+ \coordinate (LXcoor) at ($(#6)-(\tztangentepsilonL,0)$) ;
+ \coordinate (RXcoor) at ($(#6)+(\tztangentepsilonR,0)$) ;
+
+ \bool_if:NTF \l_tztangent_bbox_bool
+ {
+ \IfNodeDefined{bbxBottom}{}
+ {
+ \coordinate (bbxTop) at (current~bounding~box.north) ;
+ \coordinate (bbxBottom) at (current~bounding~box.south) ;
+ }
+ }
+ {
+ \coordinate (bbxTop) at (current~bounding~box.north) ;
+ \coordinate (bbxBottom) at (current~bounding~box.south) ;
+ }
+
+ % find vertical X points
+ \path [ name~path = C-vline ] (#6 |- bbxBottom) -- (#6 |- bbxTop) ;
+ \path [ name~intersections = { of = #5 ~ and ~ C-vline , name = TANp } ] ;
+
+ \path [ name~path = L-vline ] (LXcoor |- bbxBottom) -- (LXcoor |- bbxTop) ;
+ \path [ name~intersections = { of = #5 ~ and ~ L-vline , name = LXcut } ] ;
+
+ \path [ name~path = R-vline ] (RXcoor |- bbxBottom) -- (RXcoor |- bbxTop) ;
+ \path [ name~intersections = { of = #5 ~ and ~ R-vline , name = RXcut } ] ;
+
+ % move to tangent point
+ \coordinate (tzXproj)
+ at ($(LXcut-1)!(TANp-1)!(RXcut-1)$); % projection
+ \coordinate (LLpoint)
+ at ($(LXcut-1)+(TANp-1)-(tzXproj)$); % move
+ \coordinate (RRpoint)
+ at ($(RXcut-1)+(TANp-1)-(tzXproj)$); % move
+
+ % determine final extended points
+ \tl_set:Nx \l_tmpa_tl
+ { (RRpoint) -- (TANp-1) --
+ ([turn]0 \c_colon_str ~ -\tztangentFromVal) coordinate (final-LL) }
+ \tl_set:Nx \l_tmpb_tl
+ { (LLpoint) -- (TANp-1) --
+ ([turn]0 \c_colon_str ~ \tztangentToVal) coordinate (final-RR) }
+
+ \exp_last_unbraced:Nf \path \l_tmpa_tl ;
+ \exp_last_unbraced:Nf \path \l_tmpb_tl ;
+
+ \tzgetxyval(LLpoint){\tzTANLLX}{\tzTANLLY}
+ \tzgetxyval(RRpoint){\tzTANRRX}{\tzTANRRY}
+
+ \edef\tzTANSlope{(\tzTANRRY-\tzTANLLY)/(\tzTANRRX-\tzTANLLX)}
+ \def\tztangentLFn{\tzTANSlope*(\x-\tzTANLLX)+\tzTANLLY}
+
+ \IfValueTF { #3 }
+ {
+ \tl_put_right:Nn \l_tztangent_cmd_tl
+ {
+ [ name~path = #4 ,
+ shift = { (#3) } ,
+ }
+ }
+ {
+ \tl_put_right:Nn \l_tztangent_cmd_tl
+ {
+ [ name~path = #4 ,
+ }
+ }
+
+ \tl_put_right:Nx \l_tztangent_cmd_tl
+ {
+ domain = \tztangentFromVal \c_colon_str \tztangentToVal ,
+ }
+
+ \tl_put_right:Nn \l_tztangent_cmd_tl
+ {
+ #2 ]
+ plot ( \x , { \tztangentLFn } ) % \x should not be expanded
+ }
+
+ \gdef\TANCurve{#5}\gdef\TANWhere{#6}
+
+ \tztangent_sub_fn:n
+}
+
+\NewDocumentCommand\tztangent_epsilon_process{ m m }
+{
+ \def\tztangentEpsilonOne{#1}
+ \def\tztangentEpsilonTwo{#2}
+}
+
+\NewDocumentCommand\tztangent_domain_process{ m m }
+{
+ \def\tztangentFromVal{#1}
+ \def\tztangentToVal{#2}
+}
+
+\cs_new:Npn \tztangent_sub_fn:n
+{
+ \tztangent_final_actions
+}
+
+\NewDocumentCommand\tztangent_final_actions { +G{} O{} D<>{} }
+{
+ \begin{pgfonlayer}{\tztangentlayer}
+ \exp_last_unbraced:Nf \draw \l_tztangent_cmd_tl
+ node [ black , above~right , #2 ] { #1 } #3 ;
+ \end{pgfonlayer}
+ % to resolve TikZ issue: unknown path name with layer group
+ \exp_last_unbraced:Nf \path \l_tztangent_cmd_tl ;
+}
+
+%%% --- end of \tztangent
+
+
+%%%%% \tzbrace
+
+%%% \tzbrace'[<opt>]{<raise>}[<brace opt>]
+%%% <shift coor>(<coor>)(<coor>){<text>}[<pos,opt>]
+\NewDocumentCommand\tzbrace{ t' O{} G{5pt} O{} d<> r() r() +G{} O{} }
+{
+ \IfBooleanTF { #1 }
+ {
+ \draw [ decorate , decoration =
+ { calligraphic~brace , mirror ,
+ amplitude = 5pt, raise = #3 , #4 } , #2
+ ]
+ }
+ {
+ \draw [ decorate , decoration =
+ { calligraphic~brace ,
+ amplitude = 5pt, raise = #3 , #4 } , #2
+ ]
+ }
+ \IfValueTF { #5 }
+ {
+ ([shift={(#5)}]#6) to node [ midway , #9 ] { #8 }
+ ([shift={(#5)}]#7) ;
+ }
+ {
+ (#6) to node [ midway , #9 ] { #8 } (#7) ;
+ }
+}
+
+%%% -- end of \tzbrace
+
+
+%=====================================================
+%=====================================================
+\ExplSyntaxOff
+%=====================================================
+%=====================================================
+
+
+\endinput
+