From 204a15684f2ee547b4b0816480b87b3c30d3ef6f Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 6 Jun 2020 21:11:51 +0000 Subject: commutative-diagrams (6jun20) git-svn-id: svn://tug.org/texlive/trunk@55438 c570f23f-e606-0410-a88d-b1316a301751 --- .../tikzlibrarycommutative-diagrams.bapto.code.tex | 56 ++++ .../tikzlibrarycommutative-diagrams.code.tex | 47 +++ ...zlibrarycommutative-diagrams.diorthono.code.tex | 78 +++++ ...ikzlibrarycommutative-diagrams.ektropi.code.tex | 66 +++++ ...zlibrarycommutative-diagrams.katharizo.code.tex | 136 +++++++++ ...tikzlibrarycommutative-diagrams.koinos.code.tex | 168 +++++++++++ ...ikzlibrarycommutative-diagrams.mandyas.code.tex | 319 +++++++++++++++++++++ .../tikzlibrarycommutative-diagrams.mitra.code.tex | 207 +++++++++++++ .../tikzlibrarycommutative-diagrams.ozos.code.tex | 58 ++++ .../tikzlibrarycommutative-diagrams.ramma.code.tex | 158 ++++++++++ .../tikzlibrarycommutative-diagrams.velos.code.tex | 280 ++++++++++++++++++ 11 files changed, 1573 insertions(+) create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.bapto.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.diorthono.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ektropi.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.katharizo.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.koinos.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mandyas.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mitra.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ozos.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ramma.code.tex create mode 100644 Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.velos.code.tex (limited to 'Master/texmf-dist/tex/generic/commutative-diagrams') diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.bapto.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.bapto.code.tex new file mode 100644 index 00000000000..e417dc7f08e --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.bapto.code.tex @@ -0,0 +1,56 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% βάπτω • (báptō) +% 1. I dip, submerge +% 2. I dye, colour +% 3. I baptise + +% Bapto is a node labeling mechanism. +% It allows non-invasive relabeling and preprocessing. + +% ,-- input input hook +% `-> controller --. the controller conditionally +% ,---[overwrite]--' (depending upon the given overwriting behaviour) +% `-> trigger -----. calls the trigger +% ,--- ??? <-------' either short the keys or do preprocessing here +% `-> dispatcher --. the dispatcher conditionally +% ,---[overwrite]--| (depending upon the given overwriting behaviour) +% `-> (name|alias) | assigns the label +% output <-----' output hook + +%==[ input ]==================================================================== + +\pgfqkeys{/bapto/input}{ + .forward to=/bapto/controller +} + +%==[ controller/dispatcher ]==================================================== + +\pgfqkeys{/bapto/overwrite}{.is choice, + false/.style={/bapto/controller/.code={\def\kDTmp{##1}\ifx\kDTmp\empty\else + \tikz@fig@name\ifx\tikz@fig@name\empty + \pgfqkeys{/bapto}{trigger={##1}}\fi\fi}, + /bapto/dispatcher/.code={\pgfqkeys{/tikz}{name=##1}% + \pgfqkeys{/bapto}{output=##1}}}, + alias/.style={/bapto/controller/.code={\def\kDTmp{##1}\ifx\kDTmp\empty\else + \pgfqkeys{/bapto}{trigger={##1}}\fi}, + /bapto/dispatcher/.code={\pgfqkeys{/tikz}{alias=##1}% + \pgfqkeys{/bapto}{output=##1}}}, + true/.style= {/bapto/controller/.code={\def\kDTmp{##1}\ifx\kDTmp\empty\else + \pgfqkeys{/bapto}{trigger={##1}}\fi}, + /bapto/dispatcher/.code={\pgfqkeys{/tikz}{name=##1}% + \pgfqkeys{/bapto}{output=##1}}}, + false, % default is no name overwriting and no aliasing +} + +%==[ output ]=================================================================== + +\pgfqkeys{/bapto/output}{ + .code={} +} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.code.tex new file mode 100644 index 00000000000..eabf14dd069 --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.code.tex @@ -0,0 +1,47 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +%==[ dependencies graph ]======================================================= + +% NOTE: arrow notation means targets require sources. +% TODO: does mandyas depend upon ramma? + +%====[ TikZ/pgf standard libraries ]===============% +% % +% calc ------------------------------------. % +% matrix -------------------------------. | % +% | | % +%====[ Volatile layer: TikZ bugfixes ]=======|==|==% +% | | % +% commutative-diagrams.diorthono | | % +% | | % +%====[ Inner layer: base infrastructure ]====|==|==% +% | | % +% ,-> commutative-diagrams.ektropi ------. | | % +% | commutative-diagrams.bapto --------| | | % +% | commutative-diagrams.katharizo ----| | | % +% `-- commutative-diagrams.koinos ----. | | | % +% ,---' | | | | % +%==|=[ Middle layer: custom parsers ]==|==|==|==|==% +% | | | | | % +% |-- commutative-diagrams.mitra <----+--|--' | % +% |-- commutative-diagrams.ozos <-----| | | % +% |-- commutative-diagrams.velos <----' | | % +% | | | % +%==|=[ Outer layer: user interface ]======|=====|==% +% | | | % +% `-> commutative-diagrams.ramma <-------' | % +% commutative-diagrams.mandyas <-----------' % +% % +%==================================================% + +% Given the graph above, these suffice to encompass the whole library: + +\usetikzlibrary[commutative-diagrams.diorthono] +\usetikzlibrary[commutative-diagrams.ramma] +\usetikzlibrary[commutative-diagrams.mandyas] diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.diorthono.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.diorthono.code.tex new file mode 100644 index 00000000000..4a79abdbccb --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.diorthono.code.tex @@ -0,0 +1,78 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% διορθώνω • (diorthóno) +% 1. I correct +% 2. I mend +% 3. I repair + +% Diorthono is a collection of bugfixes. + +% Save catcode of @ to restore it at EOF. +\edef\kDAct{\catcode`@=\the\catcode`@\relax} +\catcode`@=11\relax + +% The following code patches \pgfpathcurvebetweentime. +% See http://tex.stackexchange.com/a/271024/82186 for reference. +% Original fix by Mark Wibrow. +\def\pgf@@pathcurvebetweentime#1#2#3#4#5#6{% + \pgfmathparse{#1}% + \let\pgf@time@s=\pgfmathresult% + \pgfmathparse{#2}% + \let\pgf@time@t=\pgfmathresult% + \ifdim\pgf@time@s pt>\pgf@time@t pt\relax% + \pgfmathsetmacro\pgf@time@s{1-#1}% + \pgfmathsetmacro\pgf@time@t{1-#2}% + \pgf@@@pathcurvebetweentime{#6}{#5}{#4}{#3}% + \else% + \pgf@@@pathcurvebetweentime{#3}{#4}{#5}{#6}% + \fi% +} +\def\pgf@@@pathcurvebetweentime#1#2#3#4{% +\begingroup% + % Get the curve Q from curve P for time 0 to t + \pgfextract@process\Pa{#1}% + \pgfextract@process\Pb{#2}% + \pgfextract@process\Pc{#3}% + \pgfextract@process\Pd{#4}% + % Qa = Pa + \pgfextract@process\Qa{\Pa}% + % Qb = Pa + t*(Pb-Pa). + \pgfextract@process\Qb{% + \pgfpointadd{\Pa}{\pgfpointscale{\pgf@time@t}{\pgfpointdiff{\Pa}{\Pb}}}% + }% + % Qc = Qb + t*((Pb + t*(Pc-Pb)) - Qb) + \pgfextract@process\Qc{% + \pgfpointadd{\Qb}{\pgfpointscale{\pgf@time@t}{\pgfpointdiff{\Qb}{\pgfpointadd{\Pb}{\pgfpointscale{\pgf@time@t}{\pgfpointdiff{\Pb}{\Pc}}}}}}% + }% + % Qd = (1-t)^3*Pa + 3*t(1-t)^2*Pb + 3*t^2(1-t)*Pc + t^3*Pd. + \pgfextract@process\Qd{\pgfpointcurveattime{\pgf@time@t}{\Pa}{\Pb}{\Pc}{\Pd}}% + % + % Now get the curve R from the reversed curve Q for time 0 to 1-s/t + \pgfmathdivide@{\pgf@time@s}{\pgf@time@t}% + \pgfmathadd@{-\pgfmathresult}{1.0}% + \let\pgf@time@s=\pgfmathresult% + % Rd = Qd + \pgfextract@process\Rd{\Qd}% + % Rc = Qd + s*(Qc-Qd). + \pgfextract@process\Rc{% + \pgfpointadd{\Qd}{\pgfpointscale{\pgf@time@s}{\pgfpointdiff{\Qd}{\Qc}}}% + }% + % Rb = Rc + s*((Qc + s*(Qb-Qc)) - Rc) + \pgfextract@process\Rb{% + \pgfpointadd{\Rc}{\pgfpointscale{\pgf@time@s}{\pgfpointdiff{\Rc}{\pgfpointadd{\Qc}{\pgfpointscale{\pgf@time@s}{\pgfpointdiff{\Qc}{\Qb}}}}}}% + }% + % Ra = (1-s)^3*Qd + 3*s(1-s)^2*Qc + 3*s^2(1-s)*Qb + s^3*Qa. + \pgfextract@process\Ra{\pgfpointcurveattime{\pgf@time@s}{\Qd}{\Qc}{\Qb}{\Qa}}% + \ifpgf@ignoremoveto\else\pgfpathmoveto{\Ra}\fi% + \pgfpathcurveto{\Rb}{\Rc}{\Rd}% +\endgroup% +} + +% Restore catcode of @. +\kDAct diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ektropi.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ektropi.code.tex new file mode 100644 index 00000000000..3a698436c41 --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ektropi.code.tex @@ -0,0 +1,66 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% εκτροπή • (ektropí) +% 1. diversion +% 2. deflection +% 3. aberration + +% Ektropi is a mechanism to hijack the /tikz/.unknown handler. +% It allows the addition of maximum priority paths in the key finding algorithm. +% The diversions are globally scoped, cumulative and removable. + +\usetikzlibrary{commutative-diagrams.koinos} + +\kDStoreCatcodeOf @ +\catcode`@=11 + +%==[ handler restoring procedure ]============================================== + +% The default handler's code is backed up as a token list at load time. +% NOTE: this has strong implications on loading order! + +\newtoks\kDEktropiDefaultToksBackup + +\expandafter\expandafter +\expandafter\kDEktropiDefaultToksBackup +\expandafter\expandafter +\expandafter{\csname pgfk@/tikz/.unknown/.@body\endcsname} + +\def\kDEktropiRestore{ + % Restore handler body. + \def\kDAct{\pgfkeyssetvalue{/tikz/.unknown/.@body}} + \expandafter\kDAct\expandafter{\the\kDEktropiDefaultToksBackup} + % Restore handler macro. + % NOTE: #s are doubled since we're inside \kDAct helper. + \def\kDAct{\long\def\kDAct####1\pgfeov} + \expandafter\kDAct\expandafter{\the\kDEktropiDefaultToksBackup} + \pgfkeyslet{/tikz/.unknown/.@cmd}\kDAct +} + +% This key is the user interface. Self explanatory. +\pgfkeys{/ektropi/restore/.code={\kDEktropiRestore}} + +%==[ handler hacking procedure ]================================================ + +% This key is the user interface. It wraps the /tikz/.unknown handler code +% with a conditional that executes it only if the unknown key retrieval +% fails inside the path passed to /ektropi/add. +\pgfkeys{/ektropi/add/.style={ + /tikz/.unknown/.add code= + { + \let\tikz@key\pgfkeyscurrentname + \pgfkeys{#1/\tikz@key/.try={##1}} + \ifpgfkeyssuccess\else + }{ + \fi + } + } +} + +\kDRestoreCatcodeOf @ diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.katharizo.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.katharizo.code.tex new file mode 100644 index 00000000000..ef3c4ea0fcc --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.katharizo.code.tex @@ -0,0 +1,136 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% καθαρίζω • (katharízo) +% 1. clean, wash +% 2. peel, descale +% 3. (slang) kill + +% Katharizo is a detokenization/sanitation mechanism. +% It produces "safe" strings from tokens. + +% ,-- input input hook +% `-> expander ---. performs expansion according to +% ,---[expand]----' macro expansion configuration +% `-> expanded ---. pre-sanitation hook +% ,-- sanitizer <-' performs detokenization and sanitation according to +% `---[replace]---. character replacement configuration +% ,-- sanitized <-' pre-output hook +% `-> output output hook + +%==[ input stage ]============================================================== + +\pgfqkeys{/katharizo/input}{ + .forward to=/katharizo/expander +} + +%==[ expansion stage ]========================================================== + +\pgfqkeys{/katharizo/expand}{.is choice, + once/.style={/katharizo/expander/.style={/katharizo/expanded/.expand once={##1}}}, + full/.style={/katharizo/expander/.style={/katharizo/expanded/.expanded={##1}}}, + none/.style={/katharizo/expander/.style={/katharizo/expanded={##1}}}, + none % default is no expansion +} + +\pgfqkeys{/katharizo/expanded}{ + .forward to=/katharizo/sanitizer +} + +%==[ sanitation stage ]========================================================= + +\pgfqkeys{/katharizo}{ + replace charcode/.code args={#1 with #2}{% + % TODO: would a \string be of any use? or at least a stringification? + \pgfkeys{/katharizo/replacements/characters/#1/.initial={#2}}% + }, + remove charcode/.style={/katharizo/replace charcode={{#1} with {}}}, + remove charcodes/.style args={#1}{% + /katharizo/remove charcodes loop={#1 \kD}, + }, + remove charcodes loop/.code args={#1 #2\kD}{% + % \message{|||#1|#2|||} + \ifx\relax#1\else\pgfkeys{/katharizo/remove charcode={#1}}\fi + \ifx\relax#2\else\pgfkeys{/katharizo/remove charcodes loop={#2\kD}}\fi + }, + replace character/.code args={#1 with #2}{% + \edef\kDFoo{\number`#1}% TODO: can I inline this? + % TODO: would a \string be of any use? or at least a stringification? + \pgfkeys{/katharizo/replacements/characters/\kDFoo/.initial={#2}}% + }, + remove character/.style={/katharizo/replace character={{#1} with {}}}, + remove characters/.code args={#1#2}{% + \ifx\relax#1\else\pgfkeys{/katharizo/remove character={#1}}\fi + \ifx\relax#2\else\pgfkeys{/katharizo/remove characters={#2}}\fi + }, + remove characters={(),.:}, + remove charcode=92,% \ backslash +} + +\pgfqkeys{/katharizo}{ + sanitizer/.code={ + % TODO: token replacement routine? Would that be useful? + \kDKatharizoStringify#1\kD + \expandafter\kDKatharizoSanitize\the\kDKatharizoStringified\kD + \pgfkeysalso{/katharizo/sanitized/.expanded=\the\kDKatharizoSanitized} + % \message{^^J:::\the\kDKatharizoSanitized:::^^J} + } +} + +\pgfqkeys{/katharizo/sanitized}{ + .forward to=/katharizo/output +} + +%==[ output stage ]============================================================= + +% NOTE: this must be defined/hooked before calling input +\pgfqkeys{/katharizo/output}{ + .code={} +} + +\newtoks\kDKatharizoStringified + +\def\kDKatharizoStringify#1\kD{ + \def\kDFoo{#1} + \edef\kDFoo{\meaning\kDFoo} + \def\kDAct##1:->##2\kD{##2} + \edef\kDFoo{\expandafter\kDAct\kDFoo\kD} + \kDKatharizoStringified\expandafter{\kDFoo} +} + +\newtoks\kDKatharizoSanitized + +\def\kDKatharizoSanitize#1\kD{ + \pgfkeysifdefined{/katharizo/replacements/characters/32}% + {\edef\kDKatharizoSSpace{\pgfkeysvalueof{/katharizo/replacements/characters/32}}}% + {\edef\kDKatharizoSSpace{\space}}% + \def\kDKatharizoSAppendSpace + {\edef\kDAct{\noexpand\kDKatharizoSanitized={\the\kDKatharizoSanitized\kDKatharizoSSpace}}\kDAct} + \kDKatharizoSanitized={} + \kDKatharizoSString#1 \kD}% NOTE: the whitespace is a mandatory string terminator + +\def\kDKatharizoSString#1 #2\kD{% + \ifx\relax#1\else % if string head word is not empty + \kDKatharizoSWord#1\kD % parse string head word + \if#2\space\else % if string tail is not the space terminator + \ifx\relax#2\else % if string tail is not empty + \kDKatharizoSAppendSpace\fi\fi\fi % append space substitute to output + \ifx\relax#2\else % if string tail is not empty + \kDKatharizoSString#2\kD\fi} % recurse on string tail + +\def\kDKatharizoSWord#1#2\kD{% + \kDKatharizoSCharacter#1\kD % parse word head character + \ifx\relax#2\else % if word tail is not empty + \kDKatharizoSWord#2\kD\fi} % recurse on word tail + +\def\kDKatharizoSCharacter#1\kD{% + \pgfkeysifdefined{/katharizo/replacements/characters/\number`#1}% + {\edef\kDFoo{\pgfkeysvalueof{/katharizo/replacements/characters/\number`#1}}}% + {\edef\kDFoo{#1}}% + \edef\kDAct{\noexpand\kDKatharizoSanitized={\the\kDKatharizoSanitized\kDFoo}}% + \kDAct} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.koinos.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.koinos.code.tex new file mode 100644 index 00000000000..c2b378f38a2 --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.koinos.code.tex @@ -0,0 +1,168 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% κοινός • (koinós) +% 1. shared +% 2. common +% 3. public + +% Koinos implements or aliases commonplace macros. + +%==[ catcode manipulation ]===================================================== + +\newcount\kDEscapecharCounter + +\def\kDEscapecharDisable{\kDEscapecharCounter\escapechar \escapechar=-1} +\def\kDEscapecharEnable{\escapechar\kDEscapecharCounter} + +\def\kDStoreCatcodeOf#1% + {\kDEscapecharDisable + \expandafter\edef\csname kDRestoreCatcodeOf\string#1\endcsname{\catcode`\string#1=\the\catcode\expandafter`\string#1}% + % NOTE: setting a default catcode is disabled; might come in handy someday, though. + % \catcode\expandafter`\string#1=12\relax + \kDEscapecharEnable} + +\def\kDRestoreCatcodeOf#1% + {\kDEscapecharDisable + \csname kDRestoreCatcodeOf\string#1\endcsname + \kDEscapecharEnable} + +%==[ forward checks and gobbling ]============================================== + +% This macro is the blank space token. +\bgroup +\def\:{\global\let\kDBlankSpace= }\: +\egroup + +% Save catcode of @ to restore it later. +\kDStoreCatcodeOf @ +\catcode`@=11\relax + +% The next two macros both implement token gobbling. + +% This "hard" version gobbles any token, ignoring whitespace. +\let\kDGobbleHardTok\pgfutil@gobble + +% This "soft" version gobbles only whitespace. +% NOTE: this is just the identity macro. Fun fact. +\def\kDGobbleSoftTok#1{#1} + +% The next two macros both implement the following logical condition: +% if next token is #1 then #2 else #3 + +% This "hard" version ignores whitespace. +\let\kDIfNextHardCh\pgfutil@ifnextchar + +% This "soft" version does not ignore whitespace. +\long\def\kDIfNextSoftCh#1#2#3{% + \let\kDINCToken= #1% <- MEMO: this space is crucial + \def\kDINCTrue{#2}\def\kDINCFalse{#3}% + \futurelet\kDINCTok\kDINC} + +\def\kDINC{\ifx\kDINCTok\kDINCToken\let\kDINCFalse\kDINCTrue\fi\kDINCFalse} + +% Restore catcode of @. +\kDRestoreCatcodeOf @ + +%==[ token lists parsing and manipulation ]===================================== + +% This macro appends token list #1 to token list #2. +\def\kDAppend#1#2{\edef\kDAct{\noexpand#2={\the#2\the#1}}\kDAct} + +% This macro tokenizes the stream into \kDOptTok +% until a group preceeding a ';' character is found; +% then it puts the group into \kDGrpTok and gobbles the ';'. +\def\kDFetchOptAndGrpThen#1% + {\kDOptTok={}\kDGrpTok={}\kDFetchTilGrpThen{#1}} + +\newtoks\kDOptTok +\newtoks\kDGrpTok + +\def\kDFetchGrpThen#1#2{% + \def\kDExit{#1}% + \def\kDLoop{\kDFetchTilGrpThen{#1}}% + \kDTmpTok={{#2}}% + \kDIfNextHardCh; + {\kDGrpTok\the\kDTmpTok\expandafter\kDExit\kDGobbleHardTok} + {\kDAppend\kDTmpTok\kDOptTok\kDLoop}} + +\newtoks\kDTmpTok + +\def\kDFetchTilGrpThen#1#2#{% + \kDTmpTok={#2}% + \kDAppend\kDTmpTok\kDOptTok + \kDFetchGrpThen{#1}} + +% This macro removes trailing whitespace from token list #1. +\def\kDTrimTrailingSpace#1{% + \kDDetectTrailingSpace#1 + \ifkDDTSHasTrail + \def\kDRTS##1 \kD{#1={##1}}% + \edef\kDRTSAct{\noexpand\kDRTS\the#1\noexpand\kD} + \kDRTSAct + \fi} + +\def\kDDetectTrailingSpace#1{% + \kDDTSPrevSpacefalse + \edef\kDAct{\noexpand\kDDTSGob\the#1\noexpand\kD}% + \kDAct} + +\newif\ifkDDTSHasTrail + +\def\kDDTSGob% + {\kDIfNextSoftCh\kD + {\message{A}\ifkDDTSPrevSpace\kDDTSHasTrailtrue\else\kDDTSHasTrailfalse\fi\kDGobbleHardTok} + {\message{B}\kDIfNextSoftCh\kDBlankSpace + {\message{Y}\kDDTSPrevSpacetrue\expandafter\kDDTSGob\kDGobbleSoftTok} + {\message{N}\kDDTSPrevSpacefalse\expandafter\kDDTSGob\kDGobbleHardTok}}} + +\newif\ifkDDTSPrevSpace + +% This macro removes leading whitespace from token list #1. +\def\kDTrimLeadingSpace#1{% + \def\kDAct##1\kD{#1={##1}}% + \expandafter\kDGobbleSpaceThen + \expandafter\kDAct\the#1\kD} + +\def\kDGobbleSpaceThen#1% + {\kDIfNextHardCh\bgroup + {\kDGSGroupThen#1} + {\kDGSOtherThen#1}} + +\def\kDGSGroupThen#1#2{#1{#2}} + +\def\kDGSOtherThen#1#2{#1#2} + +%==[ environment checks ]======================================================= + +\newif\ifConTeXt +% Trick stolen from iftex. The second line is expanded inside the group so +% the global scope isn't polluted by \csname defining the token. +\begingroup\expandafter\expandafter\expandafter\endgroup\expandafter + \ifx\csname starttext\endcsname\relax\ConTeXtfalse\else\ConTeXttrue\fi + +%==[ dumping, debugging and testing ]=========================================== + +% macros for dumping, debugging and testing +% TODO: not sure I want to depend on these being in the sourcecode instead of +% some external package integrated with a TeX unit testing suite. +% I'll work in that direction. + +\newif\ifkDDumping +\kDDumpingfalse + +\newwrite\kDDumpFile + +\def\kDDumpOpen% +{\ifkDDumping\immediate\openout\kDDumpFile=\jobname.yml\fi} + +\def\kDDump#1% +{\ifkDDumping\immediate\write\kDDumpFile{#1}\fi} + +\def\kDDumpClose% +{\ifkDDumping\closeout\kDDumpFile\fi} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mandyas.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mandyas.code.tex new file mode 100644 index 00000000000..2d43ef5d556 --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mandyas.code.tex @@ -0,0 +1,319 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% μανδύας • (mandýas) +% 1. cloak +% 2. mantle +% 3. dolman + +% Mandias defines the aesthetics aspect of the user level functionality, +% together with some baseline configuration. + +\usetikzlibrary[calc] + +% \usetikzlibrary[decorations.pathreplacing] +% \usetikzlibrary{decorations.pathmorphing} +% \usetikzlibrary[decorations.markings] +% \usetikzlibrary[arrows.meta] + +\pgfqkeys{/codi}{ +%==[ universal styles ]========================================================= + every diagram/.append style={}, + every layout/.append style={ + /codi/every object/.append style={shape=codi baseline centered rectangle}, + square, + }, + every object/.append style={}, + every arrow/.append style={ + >=stealth, + }, + every label/.append style={ + auto, + inner sep=0.5ex, + font=\everymath\expandafter{\the\everymath\scriptstyle} + }, +%==[ arrow styles ]============================================================= + /codi/arrows/.cd, + crossing over/clearance/.initial=0.5ex, + crossing over/color/.initial=white, + crossing over/.style={ + /tikz/preaction={ + -, + draw=\pgfkeysvalueof{/codi/arrows/crossing over/color}, + line width=\pgfkeysvalueof{/codi/arrows/crossing over/clearance}, + }, + }, + shove/.style={ + /tikz/transform canvas={ + /tikz/shift={($(\tikztostart)!#1!-90:(\tikztotarget)-(\tikztostart)$)} + } + }, + slide/.style={ + /tikz/transform canvas={ + /tikz/shift={($(\tikztostart)!#1!0:(\tikztotarget)-(\tikztostart)$)} + } + }, +%==[ label styles ]============================================================= + /codi/labels/.cd, + mid/.style={ + /tikz/fill=white, + /tikz/shape=circle, + /tikz/anchor=center, + /tikz/inner sep=.25ex + }, +%=[ objects styles ]============================================================ + /codi/objects/.cd, + % TODO: reflect on these styles + % tetragonal/.style 2 args={ + % /tikz/node distance=#2 and #1 + % }, + % square/.style={ + % /codi/objects/rectangular={#1}{#1} + % }, + % golden/.style={ + % /codi/objects/rectangular={#1}{0.618*#1} + % }, + % % comb/.style={ + % % /codi/objects/rectangular={#1}{sqrt(3/4)*#1}, + % % }, + % % comb/.default=4em, + % square/.default=4em, + % golden/.default=4em, +%=[ lattice styles ]============================================================ + /codi/layouts/.cd, + hexagonal/.code args={#1side #2 angle #3}{ + \pgfkeys{/codi/layouts/#1hexagonal=side {#2} angle {#3}}, + }, + horizontal hexagonal/.style args={side #1 angle #2}{ + /codi/layouts/tetragonal=base {#1} height {tan(#2)*#1*0.5}, + /tikz/every odd row/.append style={/tikz/xshift=(#1)*0.5}, + }, + vertical hexagonal/.style args={side #1 angle #2}{ + /codi/layouts/tetragonal=base {tan(#2)*#1*0.5} height {#1}, + /tikz/every odd column/.append style={/tikz/yshift=-1*(#1)*0.5}, + }, + hexagonal/.default=horizontal side 4.5em angle 60, + % + tetragonal/.style args={base #1 height #2}{ + /tikz/column sep={{#1},between origins}, + /tikz/row sep={{#2},between origins}, + }, + tetragonal/.default=base 4.5em height 2.8em, + % + square/.style={ + /codi/layouts/tetragonal=base {#1} height {#1}, + }, + golden/.style={ + /codi/layouts/tetragonal=base {#1} height {0.618*#1}, + }, + square/.default=4.5em, + golden/.default=4.5em, +%=[ diagram styles ]============================================================ + /codi/diagrams/.cd, + grid/.style 2 args={ + /tikz/x={#1}, + /tikz/y={#2}, + /tikz/on grid, + }, + metric/.style 2 args={ + % NOTE: {1 and 1}{1} is infty-norm, unit circle is unit square + % NOTE: {2}{0.5} is 1-norm, circle of radius 2 is rhombus circumscribing base hexagon + /tikz/node distance={#1}, + % TODO: implement control to allow for explicit units on single factor specs + /tikz/above left/.code={\tikz@lib@place@handle@{##1}{south east}{-1}{1}{north west}{#2}}, + /tikz/above right/.code={\tikz@lib@place@handle@{##1}{south west}{1}{1}{north east}{#2}}, + /tikz/below left/.code={\tikz@lib@place@handle@{##1}{north east}{-1}{-1}{south west}{#2}}, + /tikz/below right/.code={\tikz@lib@place@handle@{##1}{north west}{1}{-1}{south east}{#2}}, + }, + % + hexagonal/.code args={#1side #2 angle #3}{ + \pgfkeys{/codi/diagrams/#1hexagonal=side #2 angle #3} + }, + horizontal hexagonal/.style args={side #1 angle #2}{ + /codi/every layout/.append style={/codi/layouts/hexagonal=horizontal side {#1} angle {#2}}, + /codi/diagrams/grid={#1*0.5}{#1*tan(#2)*0.5}, + /codi/diagrams/metric={2}{0.5}, + }, + vertical hexagonal/.style args={side #1 angle #2}{ + /codi/every layout/.append style={/codi/layouts/hexagonal=vertical side {#1} angle {#2}}, + /codi/diagrams/grid={#1*tan(#2)*0.5}{#1*0.5}, + /codi/diagrams/metric={2}{0.5}, + }, + hexagonal/.default=horizontal side 4.5em angle 60, + % + tetragonal/.style args={base #1 height #2}{ + /codi/every layout/.append style={/codi/layouts/tetragonal=base {#1} height {#2}}, + /codi/diagrams/grid={#1}{#2}, + /codi/diagrams/metric={1 and 1}{1}, + }, + tetragonal/.default=base 4.5em height 2.8em, + % + square/.style={ + /codi/every layout/.append style={/codi/layouts/square=#1}, + /codi/diagrams/tetragonal=base {#1} height {#1}, + }, + golden/.style={ + /codi/every layout/.append style={/codi/layouts/golden=#1}, + /codi/diagrams/tetragonal=base {#1} height {0.618*#1}, + }, + square/.default=4.5em, + golden/.default=4.5em, +} + +%==[ baseline centered rectangle shape ]======================================== + +% The math formula axis height is recovered and stored as a pgf function. + +% NOTE: the LuaTeX version is needed just by ConTeXt +\pgfutil@ifluatex + \directlua{tex.enableprimitives('kD', {'Umathaxis'})} + \pgfmathdeclarefunction{kD_math_formula_axis_height}{0}{% + \begingroup% + $\relax$% update fontdimens + % See TeX by Topic §23.5 for details. + \pgfmathreturn\the\kDUmathaxis\textstyle% + \endgroup} +\else% if using (pdf)tex + \pgfmathdeclarefunction{kD_math_formula_axis_height}{0}{% + \begingroup% + $\relax$% update fontdimens + % See TeX by Topic §23.5 for details. + \pgfmathreturn\the\fontdimen22\textfont2% + \endgroup} +\fi + +\pgfqkeys{/codi/baseline centered rectangle}{ + center raise/.initial=kD_math_formula_axis_height +} + +% Then the shape is defined by inheritance. + +\pgfdeclareshape{codi baseline centered rectangle} { + % Inherit the rectangle shape. + \inheritsavedanchors[from={rectangle}] + \inheritanchor[from={rectangle}]{base} + \inheritanchor[from={rectangle}]{north} + \inheritanchor[from={rectangle}]{south} + \inheritanchor[from={rectangle}]{base west} + \inheritanchor[from={rectangle}]{north west} + \inheritanchor[from={rectangle}]{south west} + \inheritanchor[from={rectangle}]{base east} + \inheritanchor[from={rectangle}]{north east} + \inheritanchor[from={rectangle}]{south east} + \inheritanchor[from={rectangle}]{mid} + \inheritanchor[from={rectangle}]{mid west} + \inheritanchor[from={rectangle}]{mid east} + \inheritbackgroundpath[from={rectangle}] + % Redefine west, center and east anchors + % setting their y coordinates to center raise. + \anchor{center}{\pgf@anchor@rectangle@center\pgfmathsetlength\pgf@y% + {\pgfkeysvalueof{/codi/baseline centered rectangle/center raise}}} + \anchor{west}{\pgf@anchor@rectangle@west\pgfmathsetlength\pgf@y% + {\pgfkeysvalueof{/codi/baseline centered rectangle/center raise}}} + \anchor{east}{\pgf@anchor@rectangle@east\pgfmathsetlength\pgf@y% + {\pgfkeysvalueof{/codi/baseline centered rectangle/center raise}}} + % Save the original anchors as alternate "real" versions. + \anchor{real center}{\pgf@anchor@rectangle@center} + \anchor{real west}{\pgf@anchor@rectangle@west} + \anchor{real east}{\pgf@anchor@rectangle@east} + % Redefine the border anchor calculation. + \anchorborder{% + % (x,y) = target + % let tempdima = center raise + \pgfmathsetlength\pgfutil@tempdima% + {\pgfkeysvalueof{/codi/baseline centered rectangle/center raise}}% + % let b = (x,y) = target + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + % let (x,y) = south west + \southwest% + % let a = (x,y) = south west + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + % let (x,y) = north east + \northeast% + % let (x,y) = (x,y) - a = north east - south west = (width, height) + \advance\pgf@x by-\pgf@xa% + \advance\pgf@y by-\pgf@ya% + % let c = (x,y)/2 = (width, height)/2 = (width/2, height/2) + \pgf@xc=.5\pgf@x% + \pgf@yc=.5\pgf@y% + % let a = a + c = south west + (width/2, height/2) = center + \advance\pgf@xa by\pgf@xc% + \advance\pgf@ya by\pgf@yc% + % if by = target y > 0 + \ifdim\pgf@yb>0pt% + % let (x,y) = north east + \northeast% + % let cy = y = north east y + \pgf@yc=\pgf@y% + % let cy = cy - center raise = north east y - center raise + \advance\pgf@yc by-\pgfutil@tempdima% + \else% + % let (x,y) = south west + \southwest% + % let cy = y = - south west y + \pgf@yc=-\pgf@y% + % let cy = cy + center raise = - south west y + center raise + \advance\pgf@yc by\pgfutil@tempdima% + \fi + \edef\pgf@marshal{% + % calculate the intersection of the half line from the origin + \noexpand\pgfpointborderrectangle + % passing through target + {\noexpand\pgfqpoint{\the\pgf@xb}{\the\pgf@yb}} + % and the rectangle centered on the origin + % whose upper right corner is + % (width/2, +north east y - center raise) if target y > 0 + % (width/2, -south west y + center raise) if target y < 0 + {\noexpand\pgfqpoint{\the\pgf@xc}{\the\pgf@yc}}% + }% + % let (x,y) = the intersection + \pgf@process{\pgf@marshal}% + % let x = x + ax = width/2 + center x + \advance\pgf@x by\pgf@xa% + % let y = y + tempdima = ±(ne/sw y - center raise) + center raise + \advance\pgf@y by\pgfutil@tempdima% + % that is, y = + north east y if target y > 0 + % y = - south west y + 2 * center raise if target y < 0 + % + % NOTE: in essence, we're just compensating for the redefinition + % of ne/sw anchors that shifted them by cr below the real center. + % ┏━━━━━━┯━━━━━━┓ ╮╮ + % ┃ │ ┃ ││ + ney - cr + % ╭╭ ┠──────┼──────┨ ╮│╯ y > 0 + % - swy + cr │╰╭ ┣━━━━━━┿━━━━━━┫ ╯╯ ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ + % ╰ ╰ ┗━━━━━━┷━━━━━━┛ y < 0 + }% +}% + +%==[ prompter ]================================================================= + +% This key is meant for visual assistance with the node labeling automation. + +\pgfqkeys{/codi}{ + prompter label/.style={ + /tikz/.cd, + inner sep=0sp, + font=\ttfamily\bfseries\tiny, + line width=1pt, + draw=violet, + fill=violet, + text=white, + overlay, + label anchor/.style={tikz@label@post/.append style={anchor=##1}}, + label anchor=north east, + label position=south east + }, + prompter pinner/.style={ + /tikz/draw=violet, + /tikz/line width=1sp, + /tikz/label={[/codi/prompter label]:#1}, + }, + prompter/.style={/bapto/output/.forward to=/codi/prompter pinner} +} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mitra.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mitra.code.tex new file mode 100644 index 00000000000..211ade2f4c8 --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.mitra.code.tex @@ -0,0 +1,207 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% μήτρα • (mítra) +% 1. womb +% 2. matrix +% 3. mold + +% Mitra is an alternative parsing mechanism for TiKz matrices of nodes. +% It couples with ozos to ensure the node contents always pass through the TikZ key. + +\usetikzlibrary{matrix} +\usetikzlibrary{commutative-diagrams.koinos} + +%==[ TikZ/pgf layer ]=========================================================== + +\pgfkeys{ + /mitra/every node/.style={}, + /mitra/every matrix/.style={ + /tikz/matrix, + /tikz/cells={ + /tikz/anchor=base + } + }, + % NOTE: the alias key *cannot* be put along with global node styles + % because of execution order. + /mitra/matrix coordinates alias/.style={ + /tikz/alias=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn + } +} + +%==[ main macro ]=============================================================== + +\def\kDMitra + {\kDMitraFetchMatrixThen + {\kDMitraParseMatrixTableThen + \kDMitraOutput}} + +% General purpose scratch register. +\newtoks\kDMitraTmpTok + +%==[ fetching routine ]========================================================= + +% I use the general one implemented by koinos. +\let\kDMitraFetchMatrixThen\kDFetchOptAndGrpThen + +%==[ parsing routine: /table ]================================================== + +\newtoks\kDMitraMatOutTok + +\def\kDMitraParseMatrixTableThen#1{% + \kDMitraMatOutTok={}% + \expandafter\kDMitraParseTable\the\kDGrpTok\kD + #1} + +\def\kDMitraParseTable + {\kDMitraParseAllRowsThen\relax} + +\def\kDMitraParseAllRowsThen#1{% + \def\kDExit{#1}% + \kDIfNextHardCh\kD + {\expandafter\kDExit\kDGobbleHardTok}% + {\kDMitraParseOneRowThen{\kDMitraParseAllRowsThen{#1}}}} + +%==[ parsing routine: /table/row ]============================================== + +\def\kDMitraParseOneRowThen#1% + {\kDMitraMarkRowEndBefore + {\kDMitraParseAllColsThen + {\kDMitraParseRowEndThen + {#1}}}} + +\kDStoreCatcodeOf & +\ifConTeXt\catcode`&=12\else\catcode`&=4\fi +\def\kDMitraMarkRowEndBefore#1#2\\{#1#2&\kD\\} +\kDRestoreCatcodeOf & + +\def\kDMitraParseAllColsThen#1{% + \def\kDExit{#1}% + \kDIfNextHardCh\kD + {\expandafter\kDExit\kDGobbleHardTok}% + {\kDMitraParseOneColThen{\kDMitraParseAllColsThen{#1}}}} + +\def\kDMitraParseRowEndThen#1% + {\kDMitraFetchRowEndThen + {\kDMitraPrintRowEndThen + {#1}}} + +\def\kDMitraFetchRowEndThen#1\\{\kDMitraMaybeFetchRowOptionsThen{#1}} + +\newtoks\kDMitraRowOptTok + +\def\kDMitraPrintRowEndThen#1{% + \edef\kDAct{\noexpand\kDMitraTmpTok={\noexpand\\\the\kDMitraRowOptTok}}% + \kDAct + \kDAppend\kDMitraTmpTok\kDMitraMatOutTok + #1} + +\def\kDMitraMaybeFetchRowOptionsThen#1{% + \kDMitraRowOptTok={}% + \kDIfNextHardCh[% + {\kDMitraFetchRowOptionsThen{#1}}% + {#1}} + +\def\kDMitraFetchRowOptionsThen#1[#2]{\kDMitraRowOptTok={[#2]}#1} + +%==[ parsing routine: /table/row/column ]======================================= + +\def\kDMitraParseOneColThen#1% + {\kDMitraParseCellThen + {\kDMitraParseColEndThen + {#1}}} + +\def\kDMitraParseColEndThen#1% + {\kDMitraMaybeFetchColOptionsThen + {\kDMitraMaybePrintColEndThen + {#1}}} + +\newtoks\kDMitraColOptTok + +\def\kDMitraMaybeFetchColOptionsThen#1{% + \kDMitraColOptTok={}% + \kDIfNextHardCh[% + {\kDMitraFetchColOptionsThen{#1}}% + {#1}} + +\def\kDMitraFetchColOptionsThen#1[#2]{\kDMitraColOptTok={[#2]}#1} + +\def\kDMitraMaybePrintColEndThen#1{% + \kDIfNextHardCh\kD + {#1}% + {% NOTE: we use \pgfmatrixnextcell instead of & to avoid catcode juggling + \edef\kDAct{\noexpand\kDMitraTmpTok={\noexpand\pgfmatrixnextcell\the\kDMitraColOptTok}}% + \kDAct + \kDAppend\kDMitraTmpTok\kDMitraMatOutTok + #1% + }} + +%==[ parsing routine: /table/row/column/cell ]================================== + +\def\kDMitraParseCellThen#1% + {\kDMitraMaybeFetchCellOptionsThen + {\kDMitraFetchCellContentThen + {\kDMitraPrintCellThen + {#1}}}} + +\newtoks\kDMitraCelOptTok + +\def\kDMitraMaybeFetchCellOptionsThen#1{% + \kDMitraCelOptTok={}% + \kDIfNextHardCh|% + {\kDMitraFetchCellOptionsThen{#1}} + {#1}} + +\def\kDMitraFetchCellOptionsThen#1|#2|{\kDMitraCelOptTok={#2}#1} + +\newtoks\kDMitraCelCntTok + +\kDStoreCatcodeOf & +\ifConTeXt\catcode`&=12\else\catcode`&=4\fi +\def\kDMitraFetchCellContentThen#1#2&{% + \kDMitraCelCntTok={#2}% + \kDTrimLeadingSpace\kDMitraCelCntTok + \kDTrimTrailingSpace\kDMitraCelCntTok + #1} +\kDRestoreCatcodeOf & + +\def\kDMitraMaybeDoCellThen#1{% + \kDIfNextHardCh\kD + {#1}% + {\kDMitraParseOneColThen{#1}}} + +\def\kDMitraPrintCellThen#1{% + \edef\kDAct{% + \noexpand\kDMitraTmpTok={% + \noexpand\node + [/mitra/every node] + \the\kDMitraCelOptTok + [node contents={\the\kDMitraCelCntTok},/mitra/matrix coordinates alias]; + \kDMitraMaybeDumpCell}}% + \kDAct + \kDAppend\kDMitraTmpTok\kDMitraMatOutTok + #1} + +%==[ dumping routine ]========================================================== + +\def\kDMitraMaybeDumpCell{\noexpand\pgfextra{% + \noexpand\kDDump{'\noexpand\the\noexpand\pgfmatrixcurrentrow-\noexpand\the\noexpand\pgfmatrixcurrentcolumn':}% + \noexpand\kDDump{\space\space options: '\the\kDMitraCelOptTok'}% + \noexpand\kDDump{\space\space content: '\the\kDMitraCelCntTok'}}} + +%==[ output routine ]=========================================================== + +\def\kDMitraOutput{% + \edef\kDAct{% + \noexpand\kDMitraTmpTok={% + \noexpand\matrix + [/mitra/every matrix]% + \the\kDOptTok + {\the\kDMitraMatOutTok};}}% + \kDAct + \the\kDMitraTmpTok} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ozos.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ozos.code.tex new file mode 100644 index 00000000000..07d375cc434 --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ozos.code.tex @@ -0,0 +1,58 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% όζος • (ózos) +% 1. node +% 2. nodule +% 3. gnarl + +% Ozos is an alternative parsing mechanism for TiKz nodes. +% It implements the following transformation +% \kDOzos ... {CONTENTS}; ---> \node ... [node contents={CONTENTS}]; +% to ensure the node contents always pass through the TikZ key. + +\usetikzlibrary{commutative-diagrams.koinos} + +%==[ TikZ/pgf layer ]=========================================================== + +\pgfkeys{/ozos/every node/.style={}} + +%==[ main macro ]=============================================================== + +\def\kDOzos% + {\kDOzosFetchThen + {\kDOzosMaybeDumpThen + \kDOzosOutput}} + +%==[ fetching routine ]========================================================= + +% I use the general one implemented by koinos. +\let\kDOzosFetchThen\kDFetchOptAndGrpThen + +%==[ parsing routine ]========================================================== + +% Trivially solved by fetching. + +%==[ dumping routine ]========================================================== + +\def\kDOzosMaybeDumpThen#1{% + \kDDump{options: '\the\kDOptTok'}% + \kDDump{content: '\the\kDGrpTok'}% + #1} + +%==[ output routine ]=========================================================== + +\def\kDOzosOutput{ + \edef\kDAct{ + \noexpand\node + [/ozos/every node] + \the\kDOptTok + [/tikz/node contents={\the\kDGrpTok}]; + } + \kDAct +} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ramma.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ramma.code.tex new file mode 100644 index 00000000000..1854abb67ec --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.ramma.code.tex @@ -0,0 +1,158 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% ράμμα • (rámma) +% 1. suture +% 2. catgut +% 3. stitch + +% Ramma ties together the lower level libraries to define +% the user level functionality. NOTE: strictly no aesthetics, see mandyas. + +\usetikzlibrary[commutative-diagrams.bapto] +\usetikzlibrary[commutative-diagrams.ektropi] +\usetikzlibrary[commutative-diagrams.katharizo] +\usetikzlibrary[commutative-diagrams.koinos] +\usetikzlibrary[commutative-diagrams.ozos] +\usetikzlibrary[commutative-diagrams.mitra] +\usetikzlibrary[commutative-diagrams.velos] + +%==[ core concept ]============================================================= + +\pgfqkeys{/codi}{% TODO: is this the best scope to put the key into? + self naming/.style={ + /tikz/node contents/.forward to=/bapto/input, + /bapto/trigger/.forward to=/katharizo/input, + /katharizo/output/.forward to=/bapto/dispatcher + } +} + +%==[ baseline setup ]=========================================================== + +% Some mischief with handlers and baseline math/labeling functionality. + +\pgfqkeys{/codi}{ + .search also=/bapto, + .search also=/katharizo, + every thing/.style={ + /ektropi/restore, + /ektropi/add=/codi, + /ektropi/add=/bapto, + /ektropi/add=/katharizo + }, + every diagram/.style={% NOTE: restore hopefully unnecessary + /codi/every thing, + /ektropi/add=/codi/diagrams + }, + every layout/.style={% NOTE: restore actually unnecessary + /codi/every thing, + /ektropi/add=/codi/layouts, + /mitra/every node/.append style={/codi/every object} + }, + every object/.style={% NOTE: needed when inside matrices + /codi/every thing, + /ektropi/add=/codi/objects, + execute at begin node=$,% + execute at end node=$,% + /codi/self naming + }, + every arrow/.style={% NOTE: restore unnecessary + /codi/every thing, + /ektropi/add=/codi/arrows + }, + every label/.style={% NOTE: restore needed because inside edge + /codi/every thing, + /ektropi/add=/codi/labels, + execute at begin node=$,% + execute at end node=$,% + /codi/self naming + } +} + +% The user level keys are bound to the underlying parsers. + +\pgfkeys{ + /mitra/every matrix/.append style=/codi/every layout, + /ozos/every node/.append style=/codi/every object, + /velos/every path/.append style={ + /tikz/every edge/.append style=/codi/every arrow, + /tikz/every edge quotes/.append style=/codi/every label + } +} + +% I merge the macro syntax for objects and matrices. Convenient! + +\newif\ifkDRammaObjIsMatrix + +\def\kDRammaObjDecideWhetherIsMatrixThen#1{% + \def\kDRammaObjDWIM{\kDRammaObjDWIMSightThen{\kDRammaObjDWIMGobThen{#1}}}% + \expandafter\kDRammaObjDWIM\the\kDGrpTok\\\kD} + +\def\kDRammaObjDWIMSightThen#1#2\\% + {\kDIfNextHardCh\kD + {\kDRammaObjIsMatrixfalse#1}% + {\kDRammaObjIsMatrixtrue#1}} + +\def\kDRammaObjDWIMGobThen#1#2\kD{#1} + +\def\kDRammaObjOutput + {\ifkDRammaObjIsMatrix + \kDMitraParseMatrixTableThen\kDMitraOutput\else + \kDOzosOutput\fi} + +\def\kDRammaObj + {\kDFetchOptAndGrpThen + {\kDRammaObjDecideWhetherIsMatrixThen + \kDRammaObjOutput}} + +% Just an identity. +\let\kDRammaMor\kDVelos + +%==[ TikZ/pgf layer ]=========================================================== + +% I envelope the CoDi main macros in a simple key for maximal flexibility. + +\tikzset{ + codi/.code={% + \ifConTeXt\catcode`\|=12\fi% TODO: is it sufficient? investigate + \let\obj\kDRammaObj + \let\mor\kDRammaMor + }, + codi/.append style={/codi/every diagram} +} + +%==[ main macro ]=============================================================== + +\def\kDRamma + {\kDRammaMaybeFetchOptionsThen + \kDRammaOutput} + +\let\kDRammaOpen\kDRamma +\let\kDRammaShut\endtikzpicture + +%==[ fetching routine ]========================================================= + +\newtoks\kDRammaOptTok +\newtoks\kDRammaTmpTok + +\def\kDRammaMaybeFetchOptionsThen#1{% + \kDRammaOptTok={}% + \kDIfNextHardCh[% + {\kDRammaFetchOptionsThen{#1}}% + {#1}} + +\def\kDRammaFetchOptionsThen#1[#2]{\kDRammaOptTok={#2}#1} + +%==[ output routine ]=========================================================== + +\def\kDRammaOutput{% + \edef\kDAct{% + \noexpand\kDRammaTmpTok={% + \noexpand\tikzpicture[codi, \the\kDRammaOptTok]}}% + \kDAct + \the\kDRammaTmpTok} diff --git a/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.velos.code.tex b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.velos.code.tex new file mode 100644 index 00000000000..5072b97d7cc --- /dev/null +++ b/Master/texmf-dist/tex/generic/commutative-diagrams/tikzlibrarycommutative-diagrams.velos.code.tex @@ -0,0 +1,280 @@ +% +% CoDi: Commutative Diagrams for TeX +% Copyright (c) 2015-2020 Paolo Brasolin +% SPDX-License-Identifier: MIT +% +% This file is part of CoDi 1.0.0, released on 2020/06/06 under MIT license. +% + +% βέλος • (vélos) +% 1. arrow +% 2. dart +% 3. shaft + +% Velos is a parsing mechanism for arrow chains. + +\usetikzlibrary{commutative-diagrams.koinos} + +%==[ TikZ/pgf layer ]=========================================================== + +\pgfkeys{ + % NOTE: there might be some way to work w/ quotes library, but it's safer and + % easier to just have a custom handler mounted in the maximally local scope + % and avoid any conflict a priori. + /velos/install quote handler/.style={ + /handlers/first char syntax=true, + /handlers/first char syntax/the character "/.initial=\kDVelosQuoteHandler + % node quotes mean={node contents={#1}}, + % edge quotes mean={node contents={#1}} + }, + /velos/every path/.style={ + /velos/install quote handler + } +} + +\def\kDVelosQuoteHandler#1% + {\pgfkeysalso{/tikz/node contents/.expand once={\kDVelosUnquote#1}}} + +\def\kDVelosUnquote"#1"{#1} + +%==[ global options ]=========================================================== + +\newtoks\kDVelosTemp + +\newtoks\kDVelosGlobalLabelOptions +\newtoks\kDVelosGlobalEdgeOptions + +\newif\ifkDVelosGOAfterColon + +\def\kDVelosFetchGlobalOptionsThen#1{% + \kDVelosGOAfterColonfalse + \kDVelosGlobalLabelOptions={}% + \kDVelosGlobalEdgeOptions={}% + \kDVelosGOMaybeFetchThen{\kDVelosGOThinkThen{#1}}} + +\def\kDVelosGOMaybeFetchThen#1{% + \kDVelosTemp={}% + \kDIfNextHardCh[% + {\kDVelosGOFetchThen{#1}}% + {#1}} + +\def\kDVelosGOFetchThen#1[#2]{% + \kDVelosTemp={#2}% + #1} + +\def\kDVelosGOThinkThen#1{% + \def\kDVelosGOLoop{\kDVelosGOThinkThen{#1}}% + \def\kDVelosGOBreak{#1}% + \kDIfNextHardCh:% + {% + \kDVelosGOAfterColontrue + \kDVelosGlobalLabelOptions\expandafter{\the\kDVelosTemp}% + \expandafter\kDVelosGOMaybeFetchThen\expandafter\kDVelosGOLoop\kDGobbleHardTok + }{% + \ifkDVelosGOAfterColon + \kDVelosGlobalEdgeOptions\expandafter{\the\kDVelosTemp}\else + \kDVelosGlobalLabelOptions\expandafter{\the\kDVelosTemp}\fi + \kDVelosGOBreak + }} + +%==[ first edge ]=============================================================== + +\def\kDVelosDoFirstEdgeThen#1% + {\kDVelosFetchFirstSourceThen + {\kDVelosFetchFirstEdgeThen + {\kDVelosDrawFetchedEdgeThen + {#1}}}} + +\newtoks\kDVelosSource +\newtoks\kDVelosCurFstSrc +\newtoks\kDVelosPrvFstSrc + +\def\kDVelosFetchFirstSourceThen#1% + {\kDIfNextHardCh(% + {\kDVelosFFSBracketsThen{#1}}% + {\kDVelosFFSTillOverThen{#1}}} + +\def\kDVelosFFSBracketsThen#1(#2){% + \kDVelosSource={#2}% + \kDVelosCurFstSrc={#2}% + #1} + +\def\kDVelosFFSTillOverThen#1#2 {% <- mind the space! + \kDVelosSource={#2}% + \kDVelosCurFstSrc={#2}% + #1} + +\def\kDVelosFetchFirstEdgeThen#1% + {\kDVelosFetchEdgeThen + {\kDVelosFetchTargetThen + {#1}}} + +%==[ chained edges ]============================================================ + +\newtoks\kDVelosEdge + +\def\kDVelosFetchEdgeThen#1{% + \kDVelosEdge={}% + \kDVelosFEThen{\kDVelosFEThinkThen{#1}}} + +\def\kDVelosFEThen#1% + {\kDIfNextHardCh[% + {\kDVelosFEKeysListThen{#1}}% + {\kDIfNextHardCh"% + {\kDVelosFEEnquotedThen{#1}}% + {\kDVelosFETillOverThen{#1}}}} + +\newif\ifkDVelosTempIsKeysList + +\def\kDVelosFEEnquotedThen#1"#2"{% + \kDVelosTempIsKeysListfalse + \kDVelosTemp={#2}% + #1} + +\def\kDVelosFEKeysListThen#1[#2]{% + \kDVelosTempIsKeysListtrue + \kDVelosTemp={#2}% + #1} + +\def\kDVelosFETillOverThen#1{% + \kDVelosTempIsKeysListfalse + \kDVelosTemp={}% + \kDVelosFETOThen{#1}} + +\def\kDVelosFETOThen#1% + {\kDIfNextSoftCh\kDBlankSpace + {#1}% + {\kDIfNextHardCh:% + {#1} + {\kDVelosFEAppendThen{\kDVelosFETOThen{#1}}}}} + +\def\kDVelosFEAppendThen#1#2{% + \kDVelosTemp=\expandafter{\the\kDVelosTemp#2}% + #1} + +\def\kDVelosFEEdgePrepend#1{% + \edef\Act{\noexpand\kDVelosEdge={#1,\the\kDVelosEdge}}% + \Act} + +\def\kDVelosFEEdgePrependNode#1% + {\kDVelosFEEdgePrepend{edge node={node[every edge quotes][/velos/install quote handler,#1]}}} + +\def\kDVelosFEThinkThen#1{% + \def\kDVelosFELoop{\kDVelosFEThinkThen{#1}}% + \def\kDVelosFEBreak{#1}% + \kDIfNextHardCh[% + {% + \kDVelosFEEdgePrependNode{\the\kDVelosTemp}% + \kDVelosFEThen\kDVelosFELoop + }{% + \kDIfNextHardCh:% + {% + \ifkDVelosTempIsKeysList + \kDVelosFEEdgePrependNode{\the\kDVelosTemp}\else + \kDVelosFEEdgePrependNode{"\the\kDVelosTemp"}\fi + \expandafter\kDVelosFEThen\expandafter\kDVelosFELoop\kDGobbleHardTok + }{% + \kDVelosFEEdgePrepend{\the\kDVelosTemp}% + \kDVelosFEBreak + }% + }} + +%==[ target ]=================================================================== + +\newtoks\kDVelosTarget +\newtoks\kDVelosCurLstTar +\newtoks\kDVelosPrvLstTar + +\def\kDVelosFetchTargetThen#1% + {\kDIfNextHardCh(% + {\kDVelosFTBracketsThen{#1}}% + {\kDVelosFTTillOverThen{#1}}} + +\def\kDVelosFTBracketsThen#1(#2){% + \kDVelosTarget={#2}% + \kDVelosCurLstTar={#2}% + #1} + +\def\kDVelosFTTillOverThen#1{% + \kDVelosTarget={}% + \kDVelosFTTOThen{#1}} + +\def\kDVelosFTTOThen#1{% + \def\kDVelosFTTOLoop% + {\kDVelosFTTOThen{#1}}% + \def\kDVelosFTTOExit{% + \kDVelosCurLstTar\expandafter{\the\kDVelosTarget}% + #1}% + \kDIfNextSoftCh\kDBlankSpace + {\kDVelosFTTOExit}% + {\kDIfNextHardCh;% + {\kDVelosFTTOExit}% + {\kDVelosFTAppendThen\kDVelosFTTOLoop}}} + +\def\kDVelosFTAppendThen#1#2{% + \kDVelosTarget=\expandafter{\the\kDVelosTarget#2}% + #1} + +%==[ rendering/dereferencing ]================================================== + +\def\kDVelosAlias{*} +\def\kDVelosSaila{+} + +\newtoks\kDVelosDerefSrc +\newtoks\kDVelosDerefTar + +\def\kDVelosDrawFetchedEdgeThen#1{ + \edef\cS{\the\kDVelosSource}% + \kDVelosDerefSrc\expandafter{\the\kDVelosSource}% + \ifx\cS\kDVelosAlias\kDVelosDerefSrc\expandafter{\the\kDVelosPrvFstSrc}\fi + \ifx\cS\kDVelosSaila\kDVelosDerefSrc\expandafter{\the\kDVelosPrvLstTar}\fi + \edef\cT{\the\kDVelosTarget}% + \kDVelosDerefTar\expandafter{\the\kDVelosTarget}% + \ifx\cT\kDVelosAlias\kDVelosDerefTar\expandafter{\the\kDVelosPrvLstTar}\fi + \ifx\cT\kDVelosSaila\kDVelosDerefTar\expandafter{\the\kDVelosPrvFstSrc}\fi + \edef\Act{% + \noexpand\path + [/velos/every path]% + [% + /tikz/every edge/.append style=% + {\the\kDVelosGlobalEdgeOptions},% + /tikz/every edge quotes/.append style=% + {auto,\the\kDVelosGlobalLabelOptions},% + ]% + (\the\kDVelosDerefSrc)% + edge[\the\kDVelosEdge]% + (\the\kDVelosDerefTar);}% + \Act% + #1} + +%==[ high level ]=============================================================== + +\def\kDVelos% + {\kDVelosFetchGlobalOptionsThen + {\kDVelosDoFirstEdgeThen + \kDVelosMaybeChainEdge}} + +\def\kDVelosMaybeChainEdge{% + \kDIfNextHardCh;% + {% + \edef\cS{\the\kDVelosCurFstSrc}% + \ifx\cS\kDVelosAlias + \kDVelosCurFstSrc\expandafter{\the\kDVelosPrvFstSrc}% + \else\ifx\cS\kDVelosSaila + \kDVelosCurFstSrc\expandafter{\the\kDVelosPrvLstTar}% + \fi\fi + \edef\cT{\the\kDVelosCurLstTar}% + \ifx\cT\kDVelosAlias + \kDVelosCurLstTar\expandafter{\the\kDVelosPrvLstTar}% + \else\ifx\cT\kDVelosSaila + \kDVelosCurLstTar\expandafter{\the\kDVelosPrvFstSrc}% + \fi\fi + \kDVelosPrvFstSrc\expandafter{\the\kDVelosCurFstSrc}% + \kDVelosPrvLstTar\expandafter{\the\kDVelosCurLstTar}% + }{% + \kDVelosSource\expandafter{\the\kDVelosTarget} + \kDVelosFetchEdgeThen + {\kDVelosFetchTargetThen + {\kDVelosDrawFetchedEdgeThen + \kDVelosMaybeChainEdge}}% + }} -- cgit v1.2.3