% !TeX root = test.tex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The cistercian package 
% A package for using Cistercian numerals in latex
% Maintained by samcarter
%
% Project repository and bug tracker:
% https://github.com/samcarter/cistercian
%
% Released under the LaTeX Project Public License v1.3c or later
% See https://www.latex-project.org/lppl.txt
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ProvidesPackage{cistercian}[2025/04/29 version v0.5 Cistercian numerals]

\RequirePackage{tikz}
\pgfkeysifdefined{/tikz/actualtext/.@cmd}{
}{
  \pgfkeys{/pgf/actualtext/.code={}}
}

\RequirePackage{etoolbox}
\newlength{\cistercian@I}

\tikzset{
  code/.code={#1},
  /cistercian/.search also={/tikz,/pgf},
  /cistercian/.cd,
  height/.store in      = \cistercian@height,
  height                = \cistercian@I,
  width/.store in       = \cistercian@width,
  width                 = \cistercian@height/3,
  stroke/.store in      = \cistercian@stroke,
  stroke                = \cistercian@height/10,
}

\newcommand*{\cistercian@set}{/cistercian/.cd}
\newcommand{\cistercianset}[1]{%
  \apptocmd{\cistercian@set}{,#1}{}{}%
}
\newcommand{\cistercianreset}{%
  \renewcommand{\cistercian@set}{}%
}

% #1: optional arguments to be passed to the tikzpicture
% #2: number to be displayed
\newcommand{\cistercian}[2][]{%
  \ifnum#2<10000
  \unless\ifnum#2<0
    \setlength{\cistercian@I}{\fontcharht\font`I}%
    \begin{tikzpicture}[baseline,/cistercian/.cd,code={\pgfkeysalsofrom\cistercian@set},#1,actualtext={#2}]%
      %
      % store scaling factor
      \pgfgettransformentries{\tmpscaleA}{\tmpscaleB}{\tmpscaleC}{\tmpscaleD}{\tmp}{\tmp}%
      \pgfmathsetmacro{\cistercian@scalingfactor}{sqrt(abs(\tmpscaleA*\tmpscaleD-\tmpscaleB*\tmpscaleC))*sqrt(abs((\pgf@xx/1cm)*(\pgf@yy/1cm)-(\pgf@xy/1cm)*(\pgf@yx/1cm)))}%
      %
      % making sure all numbers have the same width
      \path [line width=\cistercian@scalingfactor*\cistercian@stroke] (-\cistercian@width-.5*\cistercian@stroke,0) -- (\cistercian@width+.5*\cistercian@stroke,\cistercian@height);
      %
      % ones
      \pgfmathparse{int(mod(#2,10)}
      \let\cistercian@ones\pgfmathresult
      %
      % tens
      \pgfmathparse{int((mod(#2,100)-mod(#2,10))/10)}
      \let\cistercian@tens\pgfmathresult
      %
      % hundreds
      \pgfmathparse{int((mod(#2,1000)-mod(#2,100))/100)}
      \let\cistercian@hundreds\pgfmathresult
      %
      % thousands
      \pgfmathparse{int((mod(#2,10000)-mod(#2,1000))/1000)}
      \let\cistercian@thousands\pgfmathresult
      %
      % superimposing the digts by mirroring
      \ifnum#2=\dimexpr\number`\^^@.\strip@pt\z@\the\tw@\number`Wpt\relax
        \cistercian@peace{\cistercian@scalingfactor*\cistercian@stroke}{.5\cistercian@height-0.5*\cistercian@scalingfactor*\cistercian@stroke}
      \else
        \cistercian@digit{\cistercian@ones}{\cistercian@tens}{\cistercian@scalingfactor*\cistercian@stroke}
        \cistercian@digit[xscale=-1]{\cistercian@tens}{\cistercian@ones}{\cistercian@scalingfactor*\cistercian@stroke}
        \cistercian@digit[yscale=-1,yshift=-\cistercian@height]{\cistercian@hundreds}{\cistercian@thousands}{\cistercian@scalingfactor*\cistercian@stroke}
        \cistercian@digit[xscale=-1,yscale=-1,yshift=-\cistercian@height]{\cistercian@thousands}{\cistercian@hundreds}{\cistercian@scalingfactor*\cistercian@stroke}
      \fi
      %
      % debug
      %\draw[red,line width=0.1pt] (0,0) rectangle (\cistercian@width,\cistercian@height);
      %\draw[red,line width=0.1pt] (0,\cistercian@height) rectangle ++(\cistercian@width,-\cistercian@width-.5*\cistercian@stroke);
    \end{tikzpicture}%
  \fi\fi%
}

% #1: stroke width
% #2: radius
\newcommand{\cistercian@peace}[2]{
  \draw[line width=#1,overlay] 
    (0,#2+0.5*#1) circle [radius=#2] 
    (0,0+0.5*#1) -- (0,2*#2+0.5*#1)
    (0,#2+0.5*#1) -- ++ (-30:#2)
    (0,#2+0.5*#1) -- ++ (-150:#2);
}

% #1: optional arguments for mirroring the digit
% #2: the digit to be printed
% #3: digit on the other site of the stem (to handle edge cases of line joints)
% #4: stroke width
\newcommand{\cistercian@digit}[4][]{%
  % drawing the stem for zero
  \draw[#1,line width=#4,overlay] (0,.5*\cistercian@stroke) -- ++(0,\cistercian@height-\cistercian@stroke)
  %  
  \ifcase #2 
  \or % 1
    -- ++(\cistercian@width+.5*\cistercian@stroke,0)
  \or % 2
       ++(0,-\cistercian@width) 
    -- ++(\cistercian@width+.5*\cistercian@stroke,0)
  \or % 3
    \ifnum3=#3
      (-\cistercian@width,\cistercian@height-\cistercian@width-.5*\cistercian@stroke) -- (0,\cistercian@height) -- (\cistercian@width,\cistercian@height-\cistercian@width-.5*\cistercian@stroke)
    \else
      \ifodd#3
        -- ++(.5*\cistercian@stroke,0) 
      \fi
      -- ++(\cistercian@width,-\cistercian@width)
    \fi 
  \or % 4
       ++(0,-\cistercian@width) 
    -- ++(\cistercian@width,\cistercian@width)
  \or % 5
    -- ++(\cistercian@width,0) 
    -- ++(-\cistercian@width,-\cistercian@width)
  \or % 6
       ++(\cistercian@width,.5*\cistercian@stroke) 
    -- ++(0,-\cistercian@width-.5*\cistercian@stroke)
  \or % 7
    -- ++(\cistercian@width,0) -- ++(0,-\cistercian@width)
  \or % 8
    ++(0,-\cistercian@width) -- ++(\cistercian@width,0) -- ++(0,\cistercian@width+.5*\cistercian@stroke)
  \or % 
    -- ++(\cistercian@width,0) -- ++(0,-\cistercian@width) -- ++(-\cistercian@width,0) 
  \fi
  %
  \ifnum#2>0
    \unless\ifodd#2
      \unless\ifodd#3
        (0,.5*\cistercian@stroke) -- (0,\cistercian@height)
      \fi
    \fi
  \else
    \ifnum0=#3
      (0,.5*\cistercian@stroke) -- (0,\cistercian@height)
    \fi
  \fi
  %
  % close path
  ;
}

% for \pagenumbering{cistercian}
\ExplSyntaxOn
\newcommand*\@cistercian { \__cistercian:n }
\cs_new:Npn \__cistercian:n #1
  {
    \cistercian{\the #1}
  }
\ExplSyntaxOff

\endinput
