%%% License %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This package is licensed under the terms of the MIT License.

% Copyright (c) 2025-2026 Kosei Kawaguchi

% Permission is hereby granted, free of charge, 
% to any person obtaining a copy of this software and associated documentation files 
% (the "Software"), to deal in the Software without restriction, 
% including without limitation the rights to use, copy, modify, merge, publish, 
% distribute, sublicense, and/or sell copies of the Software, 
% and to permit persons to whom the Software is furnished to do so, 
% subject to the following conditions:

% The above copyright notice and this permission notice 
% shall be included in all copies or substantial portions of the Software.

% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
% IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
% DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
% ARISING FROM, 
% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{keisennote}[2026/02/02, v1.2.1]

%%% basical settings
\RequirePackage[dvipsnames, svgnames, x11names]{xcolor}
\RequirePackage{zref, zref-savepos, fp}
\RequirePackage{tikz}
\RequirePackage{kvoptions, pgfkeys} 
%%%


%%% keyval package options
\SetupKeyvalOptions{
  family=kn,
  prefix=kn@
}
\DeclareStringOption[.5truept]{linewidth}
  % 線の太さ
\DeclareStringOption[.7truept]{radius}
  % ドットの大きさ
\DeclareStringOption[6truemm]{distance}
  % ドットの間隔
\DeclareStringOption[.7truept]{triangle}
  % 三角形の大きさ
\ProcessKeyvalOptions* 

\newdimen\noteLineWidth@kn
\newdimen\noteDotsRadius@kn
\newdimen\noteLineDistance@kn
\newdimen\noteTriangle@mag@kn
\setlength{\noteLineWidth@kn}{\kn@linewidth}
\setlength{\noteDotsRadius@kn}{\kn@radius}
\setlength{\noteLineDistance@kn}{\kn@distance}
\setlength{\noteTriangle@mag@kn}{\kn@triangle}
%%%


%%% setting commands
\pgfkeys{
  /KKTeX/keisen/.is family,
  /KKTeX/keisen,
  linewidth/.code = {\setlength{\noteLineWidth@kn}{#1}},
  radius/.code    = {\setlength{\noteDotsRadius@kn}{#1}},
  distance/.code  = {\setlength{\noteLineDistance@kn}{#1}},
  triangle/.code  = {\setlength{\noteTriangle@mag@kn}{#1}},
}

\NewDocumentCommand{\SetKeisenNote}{O{}}{%
  \pgfkeys{/KKTeX/keisen, #1}%
}
%%%


%%% internal parameter
\newdimen\VDNT@currentXPos
\newdimen\VDNT@currentYPos
\newdimen\VDNT@Xinterval
\newdimen\VDNT@Yinterval
\newdimen\VDNT@notegoal

\def\VDNT@xscaler{.996}

\def\VDNT@pkgname{vodnote}
\global\newcount\VDNT@uniqe
%%%


%%% 以下keisennoteのメイン

% 行間算出
\newcount\kn@linecount@internal
\newcommand{\cal@kn@internal}{%
  \FPeval\VDNT@dotsNum{round(round(((\the)\@tempcnta/(\the)\@tempcntb)/2:0)*2:0)}%
  \VDNT@Xinterval\dimexpr(\linewidth)/\VDNT@dotsNum\relax%
  \VDNT@Yinterval\VDNT@Xinterval%
}

% \notefill 
\newcommand{\savepos@kn@internal@notefill}{%
  \zsaveposy{\VDNT@pkgname.\the\VDNT@uniqe.TopPos}% 
    % 上端の座標取得
  \leavevmode\vfill\leavevmode% 
    % 下まで移動→座標記憶
  \zsaveposy{\VDNT@pkgname.\the\VDNT@uniqe.BottomPos}% 
    % 下端の座標取得
}
\newcommand{\cal@kn@internal@notefill}{%
  \VDNT@notegoal=\dimexpr
    \zposy{\VDNT@pkgname.\the\VDNT@uniqe.TopPos}sp
    -\zposy{\VDNT@pkgname.\the\VDNT@uniqe.BottomPos}sp
  \relax%
}
\newif\ifVDNT@shownumber
\pgfkeys{
  /VDNT/.is family, /VDNT,
  color/.estore in = \VDNT@color,
  step/.estore in = \VDNT@step,
  show number/.is if = VDNT@shownumber,
  default/.style = {color=white!70!black, step=5}
}

\NewDocumentCommand{\notefill}{ O{} }{%
  \par\bgroup%
  \pgfkeys{/VDNT, default, #1}%
  \parindent\z@%
  \@tempcnta\linewidth% 
    % 総横幅
  \@tempcntb\noteLineDistance@kn% 
    % 単位横幅
  \cal@kn@internal%
  \savepos@kn@internal@notefill%
  \cal@kn@internal@notefill%
  \pgfmathtruncatemacro{\VDNT@totalLines}{floor(\VDNT@notegoal / \VDNT@Yinterval)}%
    % 行間算出 
  \noindent\smash{%
    \begin{tikzpicture}[xscale=\VDNT@xscaler]
      \VDNT@currentYPos\z@
      % --
      \kn@linecount@internal=\VDNT@totalLines\relax% 
      \advance\kn@linecount@internal by \@ne\relax%
      % --
      \coordinate (TopMarkerTip) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@currentYPos+\noteTriangle@mag@kn*4pt);
      \fill[\VDNT@color] (TopMarkerTip) -- ++(\noteTriangle@mag@kn*3pt,-\noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt,0) -- cycle;
      \@whiledim\VDNT@currentYPos<\VDNT@notegoal\do{%
        \coordinate (L) at (0, \VDNT@currentYPos);
        \coordinate (R) at (\linewidth, \VDNT@currentYPos);
        \ifVDNT@shownumber
          \pgfmathtruncatemacro{\rem@notefill}{mod(\kn@linecount@internal,\VDNT@step)}
          \ifnum\rem@notefill=0
            \node[anchor=east, font=\scriptsize, text=\VDNT@color, overlay] at ([xshift=-\f@size/2pt]L) {\the\kn@linecount@internal};
          \fi
        \fi
        \draw[\VDNT@color, line width=\noteLineWidth@kn] (L) -- (R);
        \foreach \k in{0,1,...,\VDNT@dotsNum}{%
          \pgfmathtruncatemacro{\VDNT@halfNum}{\VDNT@dotsNum/2}%
          \def\do@draw@dot{1}% 
          \ifdim\VDNT@currentYPos=0pt\relax 
            \ifnum\k=\VDNT@halfNum \def\do@draw@dot{0}\fi
          \fi
          \VDNT@currentXPos=\dimexpr\VDNT@currentYPos+\VDNT@Yinterval\relax
          \ifdim\VDNT@currentXPos<\VDNT@notegoal\else
            \ifnum\k=\VDNT@halfNum \def\do@draw@dot{0}\fi
          \fi
          \ifnum\do@draw@dot=1\relax
            \coordinate (Dot) at (\the\dimexpr\VDNT@Xinterval*\k\relax, \VDNT@currentYPos);
            \fill[\VDNT@color] (Dot) circle [radius=\noteDotsRadius@kn];
          \fi
        }
        \advance\VDNT@currentYPos\VDNT@Yinterval\relax
        \advance\kn@linecount@internal by -\@ne\relax 
      }
      \coordinate (BottomMarkerTip) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@currentYPos-\VDNT@Yinterval-\noteTriangle@mag@kn*4pt);
      \fill[\VDNT@color] (BottomMarkerTip) -- ++(\noteTriangle@mag@kn*3pt,\noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt,0) -- cycle;
    \end{tikzpicture}%
  }%
  \egroup%
  \global\advance\VDNT@uniqe\@ne%
  \par%
}

\NewDocumentCommand{\masumefill}{ s O{} }{%
  \par\bgroup%
  \pgfkeys{/VDNT, default, #2}%
  \parindent\z@%
  \@tempcnta\linewidth%
  \@tempcntb\noteLineDistance@kn%
  \cal@kn@internal%
  \savepos@kn@internal@notefill%
  \cal@kn@internal@notefill%
  \pgfmathtruncatemacro{\VDNT@totalLines}{floor(\VDNT@notegoal / \VDNT@Yinterval)}%
  \noindent\smash{%
    \begin{tikzpicture}[xscale=\VDNT@xscaler]
      \VDNT@currentYPos\z@
      \kn@linecount@internal=\VDNT@totalLines\relax%
      \advance\kn@linecount@internal by \@ne\relax%
      \coordinate (TopMarkerTip) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@currentYPos+\noteTriangle@mag@kn*4pt);
      \fill[\VDNT@color] (TopMarkerTip) -- ++(\noteTriangle@mag@kn*3pt,-\noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt,0) -- cycle;
      \@whiledim\VDNT@currentYPos<\VDNT@notegoal\do{%
        \coordinate (L) at (0, \VDNT@currentYPos);
        \coordinate (R) at (\linewidth, \VDNT@currentYPos);
        \ifVDNT@shownumber
          \pgfmathtruncatemacro{\rem@notefill}{mod(\kn@linecount@internal,\VDNT@step)}
          \ifnum\rem@notefill=0
            \node[anchor=east, font=\scriptsize, text=\VDNT@color, overlay] at ([xshift=-\f@size/2pt]L) {\the\kn@linecount@internal};
          \fi
        \fi
        \draw[\VDNT@color, line width=\noteLineWidth@kn] (L) -- (R);
        \foreach \k in{0,1,...,\VDNT@dotsNum}{%
          \pgfmathtruncatemacro{\VDNT@halfNum}{\VDNT@dotsNum/2}%
          \def\do@draw@dot{1}% 
          \ifdim\VDNT@currentYPos=0pt\relax 
            \ifnum\k=\VDNT@halfNum \def\do@draw@dot{0}\fi
          \fi
          \VDNT@currentXPos=\dimexpr\VDNT@currentYPos+\VDNT@Yinterval\relax
          \ifdim\VDNT@currentXPos<\VDNT@notegoal\else
            \ifnum\k=\VDNT@halfNum \def\do@draw@dot{0}\fi
          \fi
          % ------------------
          \coordinate (VBottom) at (\the\dimexpr\VDNT@Xinterval*\k\relax, \VDNT@currentYPos);
          \VDNT@currentXPos=\dimexpr\VDNT@currentYPos+\VDNT@Yinterval\relax
          \ifdim\VDNT@currentXPos<\VDNT@notegoal\relax
            \draw[\VDNT@color, line width=\noteLineWidth@kn] (VBottom) -- ++(0, \VDNT@Yinterval);
          \fi
          % ------------------
          \ifnum\do@draw@dot=1\relax
            \coordinate (Dot) at (\the\dimexpr\VDNT@Xinterval*\k\relax, \VDNT@currentYPos);
            \fill[\VDNT@color] (Dot) circle [radius=\noteDotsRadius@kn];
          \fi
        }
        \advance\VDNT@currentYPos\VDNT@Yinterval\relax
        \advance\kn@linecount@internal by -\@ne\relax 
      }
      \IfBooleanT{#1}{%
        \draw[\VDNT@color, line width=\noteLineWidth@kn*2.5] (0,0) rectangle (\linewidth, \the\dimexpr\VDNT@currentYPos-\VDNT@Yinterval\relax);
      }%
      \coordinate (BottomMarkerTip) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@currentYPos-\VDNT@Yinterval-\noteTriangle@mag@kn*4pt);
      \fill[\VDNT@color] (BottomMarkerTip) -- ++(\noteTriangle@mag@kn*3pt,\noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt,0) -- cycle;
    \end{tikzpicture}%
  }%
  \egroup%
  \global\advance\VDNT@uniqe\@ne%
  \par%
}


% \note の定義（２以上の整数を引数に）
\NewDocumentCommand{\note}{ m O{} }{%
  \par\bgroup%
  \pgfkeys{/VDNT, default, #2}%
  \@tempcnta\linewidth%
  \@tempcntb\noteLineDistance@kn%
  \cal@kn@internal%
  \noindent%
  \begin{tikzpicture}[xscale=\VDNT@xscaler]
    \VDNT@currentYPos\z@
    \coordinate (TopMarker) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@Yinterval+\noteTriangle@mag@kn*4pt);
    \fill[\VDNT@color] (TopMarker) -- ++(\noteTriangle@mag@kn*3pt, -\noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt, 0) -- cycle;
    \foreach \i in {1, 2, ..., #1} {%
      \xdef\tempY{\the\dimexpr\VDNT@Yinterval*\i\relax}
      \coordinate (LineL) at (0, \tempY);
      \coordinate (LineR) at (\linewidth, \tempY);
      \ifVDNT@shownumber
        \pgfmathtruncatemacro{\VDNT@currentnum}{#1 - \i + 1 }
        \pgfmathtruncatemacro{\rem@notefill}{mod(\VDNT@currentnum,\VDNT@step)}
        \ifnum\rem@notefill=0
          \node[anchor=east, font=\scriptsize, text=\VDNT@color, overlay] at ([xshift=-\f@size/2pt]LineL) {\VDNT@currentnum};
        \fi
      \fi
      \draw[\VDNT@color, line width=\noteLineWidth@kn] (LineL) -- (LineR);
      \foreach \k in {0, 1, ..., \VDNT@dotsNum} {%
        \pgfmathtruncatemacro{\VDNT@halfNum}{\VDNT@dotsNum/2}%
        \def\skipdot{0}%
        \ifnum\i=1 \ifnum\k=\VDNT@halfNum \def\skipdot{1}\fi\fi
        \ifnum\i=#1 \ifnum\k=\VDNT@halfNum \def\skipdot{1}\fi\fi
        \ifnum\skipdot=0
          \coordinate (DotPos) at (\the\dimexpr\VDNT@Xinterval*\k\relax, \tempY);
          \fill[\VDNT@color] (DotPos) circle [radius=\noteDotsRadius@kn];
        \fi
      }%
      \ifnum\i=#1 \global\VDNT@currentYPos=\tempY\relax \fi
    }%
    \coordinate (BottomMarker) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@currentYPos-\noteTriangle@mag@kn*4pt);
    \fill[\VDNT@color] (BottomMarker) -- ++(\noteTriangle@mag@kn*3pt, \noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt, 0) -- cycle;
  \end{tikzpicture}%
  \egroup%
  \par%
}

\NewDocumentCommand{\masume}{ s m O{} }{%
  \par\bgroup%
  \pgfkeys{/VDNT, default, #3}%
  \@tempcnta\linewidth%
  \@tempcntb\noteLineDistance@kn%
  \cal@kn@internal%
  \noindent%
  \begin{tikzpicture}[xscale=\VDNT@xscaler]
    \VDNT@currentYPos\z@
    \coordinate (TopMarker) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@Yinterval+\noteTriangle@mag@kn*4pt);
    \fill[\VDNT@color] (TopMarker) -- ++(\noteTriangle@mag@kn*3pt, -\noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt, 0) -- cycle;
    \foreach \i in {1, 2, ..., #2} {%
      \xdef\tempY{\the\dimexpr\VDNT@Yinterval*\i\relax}
      \coordinate (LineL) at (0, \tempY);
      \coordinate (LineR) at (\linewidth, \tempY);
      \ifVDNT@shownumber
        \pgfmathtruncatemacro{\VDNT@currentnum}{#2 - \i + 1 }
        \pgfmathtruncatemacro{\rem@notefill}{mod(\VDNT@currentnum,\VDNT@step)}
        \ifnum\rem@notefill=0
          \node[anchor=east, font=\scriptsize, text=\VDNT@color, overlay] at ([xshift=-\f@size/2pt]LineL) {\VDNT@currentnum};
        \fi
      \fi
      \draw[\VDNT@color, line width=\noteLineWidth@kn] (LineL) -- (LineR);
      \foreach \k in {0, 1, ..., \VDNT@dotsNum} {%
        \pgfmathtruncatemacro{\VDNT@halfNum}{\VDNT@dotsNum/2}%
        \def\skipdot{0}%
        \ifnum\i=1 \ifnum\k=\VDNT@halfNum \def\skipdot{1}\fi\fi
        \ifnum\i=#2 \ifnum\k=\VDNT@halfNum \def\skipdot{1}\fi\fi
        % ------------------
        \ifnum\i<#2\relax
          \draw[\VDNT@color, line width=\noteLineWidth@kn] (\the\dimexpr\VDNT@Xinterval*\k\relax, \tempY) -- ++(0, \VDNT@Yinterval);
        \fi
        % ------------------
        \ifnum\skipdot=0
          \coordinate (DotPos) at (\the\dimexpr\VDNT@Xinterval*\k\relax, \tempY);
          \fill[\VDNT@color] (DotPos) circle [radius=\noteDotsRadius@kn];
        \fi
      }%
      \ifnum\i=#2 \global\VDNT@currentYPos=\tempY\relax \fi
    }%
    \IfBooleanT{#1}{%
      \draw[\VDNT@color, line width=\noteLineWidth@kn*2.5] (0, \the\VDNT@Yinterval) rectangle (\linewidth, \VDNT@currentYPos);
    }%
    \coordinate (BottomMarker) at (\VDNT@Xinterval*\VDNT@dotsNum/2, \VDNT@currentYPos-\noteTriangle@mag@kn*4pt);
    \fill[\VDNT@color] (BottomMarker) -- ++(\noteTriangle@mag@kn*3pt, \noteTriangle@mag@kn*4pt) -- ++(-\noteTriangle@mag@kn*6pt, 0) -- cycle;
  \end{tikzpicture}%
  \egroup%
  \par%
}
%%%

\endinput