%
% CoDi: Commutative Diagrams for TeX
% Copyright (c) 2015-2020 Paolo Brasolin <paolo.brasolin@gmail.com>
% SPDX-License-Identifier: MIT
%
% This file is part of CoDi 1.0.1, released on 2020/06/11 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}
