% !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] (-\[email protected]*\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\[email protected]*\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,-\[email protected]*\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-\[email protected]*\cistercian@stroke) -- (0,\cistercian@height) -- (\cistercian@width,\cistercian@height-\[email protected]*\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,-\[email protected]*\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