% % CoDi: Commutative Diagrams for TeX % Copyright (c) 2015-2024 Paolo Brasolin % SPDX-License-Identifier: MIT % % This file is part of CoDi 1.1.2, released on 2024/04/22 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\path\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}