%%% 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}
\ProvidesExplPackage
  {modernruler}
  {2026/02/07}{Version 2.1.6}{ `modernruler` provides enhanced ruler commands}

%%% parameters
\cs_if_exist:NF \zw
   {
      \dim_new:N \zw
      \dim_set:Nn \zw { 1em }
   }

\cs_if_exist:NF \ltjgetparameter
   {
      \cs_new:Npn \ltjgetparameter #1 { 4 }
   }
%%%


%%% basical settings
\RequirePackage{kvoptions, pgfkeys} 
\RequirePackage{varwidth, zref-savepos}
\RequirePackage[most]{tcolorbox}
%%%


%%% keyval package options for \undernote
\SetupKeyvalOptions{%
  family=undernote,%
  prefix=undernote@%
}
\DeclareStringOption[\footnotesize]{notesize}
\DeclareStringOption[3mm]{notepos}
\DeclareStringOption[4mm]{noteshift}
\DeclareStringOption[.07\zw]{noterulethickness}
\DeclareStringOption[1.5mm]{noterulehshift}
\DeclareStringOption[1.5mm]{noterulehsize}
\DeclareStringOption[0em]{notesep}
\DeclareStringOption[5em]{noteoverhang}
\DeclareStringOption[0]{noteparstyle}
\DeclareStringOption[black]{notelinecolor}
\ProcessKeyvalOptions*

\def\notesize@internal@undernote{\undernote@notesize}                     
   % 注釈部分の文字サイズ
\def\notepos@internal@undernote{\undernote@notepos}                        
   % 注釈へと伸ばす縦線の長さの最小値
\def\noteshift@internal@undernote{\undernote@noteshift}                    
   % 注釈を下にずらす場合の1段階分の移動量
\def\noterulethickness@internal@undernote{\undernote@noterulethickness}    
   % 注釈線の太さ
\def\noterulehshift@internal@undernote{\undernote@noterulehshift}          
   % 注釈へと伸ばす縦線の位置
   % （注釈をつける語句につけた下線の左端から\noterulehshift@internal@undernote だけ右にずれた位置に縦線を置く）
\def\noterulehsize@internal@undernote{\undernote@noterulehsize}           
   % 注釈へと伸ばす横線の長さ
\def\notesep@internal@undernote{\undernote@notesep}                        
   % 前にある注釈が次の注釈の縦線から \notesep@internal@undernote 以内に近づくようなら、
   % その値だけ前にある注釈を下にずらす
\def\noteoverhang@internal@undernote{\undernote@noteoverhang}                                 
   % どの程度後ろに注釈部分を張り出させるか
\def\noteparstyle@internal@undernote{\undernote@noteparstyle}      
\msg_new:nnn { modernruler } { invalid-number } 
   { 
      The ~ input ~ is ~ an ~ invalid ~ number. ~ `noteparstyle` ~ must ~ be ~ `0`, ~ `1`, ~ or ~ `2`.
   }                               
   % 注釈部分を 
   % -- 1と2以外: 囲みなし 
   % -- 1: 実線で囲う 
   % -- 2:点線で囲う
\def\notelinecolor@internal@undernote{\undernote@notelinecolor}   
   % 注釈線の色の指定
%%%


%%% setting commands for \undernote
\pgfkeys{
  /KKTeX/unote/.is~family,
  /KKTeX/unote,
  notesize/.store~in          = \notesize@internal@undernote,
  notepos/.store~in           = \notepos@internal@undernote,
  noteshift/.store~in         = \noteshift@internal@undernote,
  noterulethickness/.store~in = \noterulethickness@internal@undernote,
  noterulehshift/.store~in    = \noterulehshift@internal@undernote,
  noterulehsize/.store~in     = \noterulehsize@internal@undernote,
  notesep/.store~in           = \notesep@internal@undernote,
  noteoverhang/.store~in      = \noteoverhang@internal@undernote,
  notelinecolor/.store~in     = \notelinecolor@internal@undernote,
  noteparstyle/.code          = {
      \def\noteparstyle@internal@undernote{#1}
      \ifnum#1=1\relax%
         \let\wrap@undernote\wrap@undernote@styleA
         \let\wrap@undernote@par\wrap@undernote@par@styleA
         \def\hline@undernote@par{%
            \mruleth[height=\noterulethickness@internal@undernote, width=\undernote@textlen@tempo, color=\notelinecolor@internal@undernote]
         }
         \def\vlines@undernote@par{%
            \mruletv[
               height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt, 
               color=\notelinecolor@internal@undernote
            ]%
            \mruleth[
               height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, 
               color=\notelinecolor@internal@undernote
            ]%
         }
      \else\ifnum#1=2\relax%
         \let\wrap@undernote\wrap@undernote@styleB
         \let\wrap@undernote@par\wrap@undernote@par@styleB
         \def\hline@undernote@par{%
            \mruleth[height=\noterulethickness@internal@undernote, width=\undernote@textlen@tempo, dash=true, color=\notelinecolor@internal@undernote]%
         }
         \def\vlines@undernote@par{%
            \mruletv[
               height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt, dash=true, 
               color=\notelinecolor@internal@undernote
            ]%
            \mruleth[
               height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, dash=true, 
               color=\notelinecolor@internal@undernote
            ]%
         }
      \else\ifnum#1=0\relax%
         \let\wrap@undernote\wrap@undernote@styleC
         \let\wrap@undernote@par\wrap@undernote@par@styleC
         \def\hline@undernote@par{%
            \mruleth[height=\noterulethickness@internal@undernote, width=\undernote@textlen@tempo, color=\notelinecolor@internal@undernote]%
         }
         \def\vlines@undernote@par{%
            \mruletv[
               height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt,
               color=\notelinecolor@internal@undernote
            ]%
            \mruleth[
               height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, 
               color=\notelinecolor@internal@undernote
            ]%
         }
      \else\relax%
         \msg_warning:nn { modernruler } { invalid-number }
      \fi\fi\fi
  }
}

\NewDocumentCommand{\SetUNote}{ O{} }{%
  \pgfkeys{/KKTeX/unote, #1}%
}
%%%


%%% modern rule commands

% 変数の宣言
\dim_new:N  \l_mrule_width_dim
\dim_new:N  \l_mrule_height_dim
\dim_new:N  \l_mrule_depth_dim
\dim_new:N  \l_mrule_dash_len_dim
\dim_new:N  \l_mrule_gap_len_dim
\dim_new:N  \l_mrule_total_width_dim 
\tl_new:N   \l_mrule_color_tl
\bool_new:N \l_mrule_dash_bool
\tl_new:N \l_mrule_leader_cmd_tl
\dim_new:N \l__mrule_tmp_remaining_dim

% キーの定義
\keys_define:nn { modernrule }
{
   width    .dim_set:N = \l_mrule_width_dim,
   height   .dim_set:N = \l_mrule_height_dim,
   depth    .dim_set:N = \l_mrule_depth_dim,
   color    .tl_set:N  = \l_mrule_color_tl,
   dash     .bool_set:N = \l_mrule_dash_bool,
   dash-len .dim_set:N  = \l_mrule_dash_len_dim,
   gap-len  .dim_set:N  = \l_mrule_gap_len_dim,
   gap-color .tl_set:N = \l_mrule_gap_color_tl,

   % デフォルト値
   width    .initial:n = 0pt,
   height   .initial:n = 0pt,
   depth    .initial:n = 0pt,
   color    .initial:n = black,
   dash     .initial:n = false,
   dash-len .initial:n = 3pt,
   gap-len  .initial:n = 2.5pt,
   gap-color .initial:n = white,
}

% 水平方向：2色点線
\NewDocumentCommand{\mruleth}{ O{} }
{
   \group_begin:
   \keys_set:nn { modernrule } { #1 }
   \ifvmode \nointerlineskip \fi

   \bool_if:NTF \l_mrule_dash_bool
   {
      % dash=true: 2色交互の点線描画
      \hbox_to_wd:nn { \l_mrule_width_dim }
         {
         \dim_set:Nn \l__mrule_tmp_remaining_dim { \l_mrule_width_dim }
         \dim_while_do:nNnn { \l__mrule_tmp_remaining_dim } > { 0pt }
            {
               \dim_compare:nNnTF { \l__mrule_tmp_remaining_dim } > { \l_mrule_dash_len_dim }
               {
                  % メイン色
                  {\color{\l_mrule_color_tl} \vrule width \l_mrule_dash_len_dim height \l_mrule_height_dim depth \l_mrule_depth_dim}
                  \dim_sub:Nn \l__mrule_tmp_remaining_dim { \l_mrule_dash_len_dim }
                  
                  % ギャップ色
                  \dim_compare:nNnTF { \l__mrule_tmp_remaining_dim } > { \l_mrule_gap_len_dim }
                     {
                     {\color{\l_mrule_gap_color_tl} \vrule width \l_mrule_gap_len_dim height \l_mrule_height_dim depth \l_mrule_depth_dim}
                     \dim_sub:Nn \l__mrule_tmp_remaining_dim { \l_mrule_gap_len_dim }
                     }
                     {
                     {\color{\l_mrule_gap_color_tl} \vrule width \l__mrule_tmp_remaining_dim height \l_mrule_height_dim depth \l_mrule_depth_dim}
                     \dim_set:Nn \l__mrule_tmp_remaining_dim { 0pt }
                     }
               }
               {
                  {\color{\l_mrule_color_tl} \vrule width \l__mrule_tmp_remaining_dim height \l_mrule_height_dim depth \l_mrule_depth_dim}
                  \dim_set:Nn \l__mrule_tmp_remaining_dim { 0pt }
               }
            }
         \hss
         }
   }
   {
      \hbox_to_wd:nn { \l_mrule_width_dim } {{
         \color{\l_mrule_color_tl}
         \vrule width \l_mrule_width_dim height \l_mrule_height_dim depth \l_mrule_depth_dim
      }}
   }

   \ifvmode \nointerlineskip \fi
   \group_end:
}

% 垂直方向：2色点線
\NewDocumentCommand{\mruletv}{ O{} }
{
   \group_begin:
   \keys_set:nn { modernrule } { #1 }

   \bool_if:NTF \l_mrule_dash_bool
   {
      % dash=true: 2色交互の垂直点線
      \dim_set:Nn \l__mrule_tmp_remaining_dim { \l_mrule_height_dim }
      \vbox:n
         {
         \dim_while_do:nNnn { \l__mrule_tmp_remaining_dim } > { 0pt }
            {
               \dim_compare:nNnTF { \l__mrule_tmp_remaining_dim } > { \l_mrule_dash_len_dim }
               {
                  % メイン色
                  {\color{\l_mrule_color_tl} \hrule width \l_mrule_width_dim height \l_mrule_dash_len_dim}
                  \dim_sub:Nn \l__mrule_tmp_remaining_dim { \l_mrule_dash_len_dim }
                  
                  % ギャップ色
                  \dim_compare:nNnTF { \l__mrule_tmp_remaining_dim } > { \l_mrule_gap_len_dim }
                     {
                     {\color{\l_mrule_gap_color_tl} \hrule width \l_mrule_width_dim height \l_mrule_gap_len_dim}
                     \dim_sub:Nn \l__mrule_tmp_remaining_dim { \l_mrule_gap_len_dim }
                     }
                     {
                     {\color{\l_mrule_gap_color_tl} \hrule width \l_mrule_width_dim height \l__mrule_tmp_remaining_dim}
                     \dim_set:Nn \l__mrule_tmp_remaining_dim { 0pt }
                     }
               }
               {
                  {\color{\l_mrule_color_tl} \hrule width \l_mrule_width_dim height \l__mrule_tmp_remaining_dim}
                  \dim_set:Nn \l__mrule_tmp_remaining_dim { 0pt }
               }
            }
         }
   }
   {
      \vbox:n { {\color{\l_mrule_color_tl} \hrule width \l_mrule_width_dim height \l_mrule_height_dim} }
   }
   \group_end:
}
%%%

%%% undernote
\DeclareTotalTCBox{\FramedBox@undernote}{ O{} +m }{%
  on~line, arc=0pt,
  sharp~corners, boxsep=-.5mm+.25\zw,
  left=.3mm, right=.3mm, top=.3mm, bottom=.3mm,
  colback=white, colframe=white, boxrule=0pt,
  enhanced, before={\hspace*{.25\zw}\hspace{-.5mm}},
  borderline={\noterulethickness@internal@undernote}{-.25\zw+.5mm}{solid, \notelinecolor@internal@undernote},
  #1
}{#2}
\DeclareTotalTCBox{\DashedBox@undernote}{ O{} +m }{%
  on~line, arc=0pt,
  sharp~corners, boxsep=-.5mm+.25\zw,
  left=.3mm, right=.3mm, top=.3mm, bottom=.3mm,
  colback=white, colframe=white, boxrule=0pt,
  enhanced, before={\hspace*{.25\zw}\hspace{-.5mm}},
  borderline={\noterulethickness@internal@undernote}{-.25\zw+.5mm}{dashed, \notelinecolor@internal@undernote},
  #1
}{#2}
\DeclareTotalTCBox{\NoframeBox@undernote}{ O{} +m }{%
  on~line, arc=0pt,
  sharp~corners, boxsep=-.5mm,
  left=.8mm, right=.8mm, top=0.3mm, bottom=0.3mm,
  colback=white, colframe=white, boxrule=0pt,
  enhanced, before={\hspace*{-.172\zw}},
  #1
}{#2}

\newlength{\undernote@textlen@tempo}\newlength{\undernote@textdepth@tempo}

\NewDocumentCommand{\wrap@undernote@par@styleA}{ +m }{%
{%
   \FramedBox@undernote{%
      \parbox[t]{\dimexpr\undernote@textlen@tempo - \noterulehsize@internal@undernote - \noterulehshift@internal@undernote + \noteoverhang@internal@undernote\relax}%
      {\setlength{\baselineskip}{.215\zw}#1}}%
}}
\NewDocumentCommand{\wrap@undernote@par@styleB}{ +m }{%
{%
   \DashedBox@undernote{%
      \parbox[t]{\dimexpr\undernote@textlen@tempo - \noterulehsize@internal@undernote - \noterulehshift@internal@undernote + \noteoverhang@internal@undernote\relax}%
      {\setlength{\baselineskip}{.215\zw}#1}}%
}}
\NewDocumentCommand{\wrap@undernote@par@styleC}{ +m }{%
{%
   \NoframeBox@undernote{%
      \parbox[t]{\dimexpr\undernote@textlen@tempo - \noterulehsize@internal@undernote - \noterulehshift@internal@undernote + \noteoverhang@internal@undernote\relax}%
      {\setlength{\baselineskip}{.215\zw}#1}}%
}}
\NewDocumentCommand{\wrap@undernote@styleA}{ +m }{{\FramedBox@undernote{#1}}}
\NewDocumentCommand{\wrap@undernote@styleB}{ +m }{{\DashedBox@undernote{#1}}}
\NewDocumentCommand{\wrap@undernote@styleC}{ +m }{{\NoframeBox@undernote{#1}}}
\NewDocumentCommand{\wrap@undernote}{ +m }{{#1}}
\NewDocumentCommand{\wrap@undernote@par}{ +m }{{\wrap@undernote@styleC{#1}}}
\ifnum\noteparstyle@internal@undernote=1\relax%
   \let\wrap@undernote\wrap@undernote@styleA
   \let\wrap@undernote@par\wrap@undernote@par@styleA
   \def\hline@undernote@par{%
      \mruleth[height=\noterulethickness@internal@undernote, width=\undernote@textlen@tempo, color=\notelinecolor@internal@undernote]%
   }%
   \def\vlines@undernote@par{%
      \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt, color=\notelinecolor@internal@undernote]%
      \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, color=\notelinecolor@internal@undernote]%
   }
\else\ifnum\noteparstyle@internal@undernote=2\relax%
   \let\wrap@undernote\wrap@undernote@styleB
   \let\wrap@undernote@par\wrap@undernote@par@styleB
   \def\hline@undernote@par{%
      \mruleth[height=\noterulethickness@internal@undernote, width=\undernote@textlen@tempo, dash=true, color=\notelinecolor@internal@undernote]%
   }%
   \def\vlines@undernote@par{%
      \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt ,dash=true, color=\notelinecolor@internal@undernote]%
      \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, dash=true, color=\notelinecolor@internal@undernote]%
   }
\else\ifnum\noteparstyle@internal@undernote=0\relax%
   \let\wrap@undernote\wrap@undernote@styleC
   \let\wrap@undernote@par\wrap@undernote@par@styleC
   \def\hline@undernote@par{%
      \mruleth[height=\noterulethickness@internal@undernote, width=\undernote@textlen@tempo, color=\notelinecolor@internal@undernote]%
   }%
   \def\vlines@undernote@par{%
      \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt, color=\notelinecolor@internal@undernote]%
      \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, color=\notelinecolor@internal@undernote]%
   }
\else\relax%
   \msg_warning:nn { modernruler } { invalid-number }
\fi\fi\fi

\newbox\@undernote@maintext
\newbox\@undernote@subtext
\newcounter{undernote@id} \setcounter{undernote@id}{0}
\DeclareDocumentCommand{\undernote}{ s O{} m +m }{%
      %%% #1（star）注釈をparboxに包む
      %%% #2 (optinal): 注釈を下にずらす「行数」（与えない場合自動設定）
      %%% #3: 注釈をつける語句
      %%% #4: 注釈
   \begingroup%
   \stepcounter{undernote@id}%
   \ifmmode%
      \@note@save@conters%
      \zsavepos{unote-\the\c@undernote@id}%
      \expandafter\@math@undernote%
   \else%
      \settowidth{\undernote@textlen@tempo}{#3}%
      \leavevmode%
      \zsavepos{unote-\the\c@undernote@id}%
      \expandafter\@text@undernote%
   \fi%
   {#2}{#3}{%
      \ifnum\ltjgetparameter{direction}=4%
         \begin{varwidth}[t]{\maxdimen}%
            \IfBooleanTF{#1}{\wrap@undernote@par{#4}}{\wrap@undernote{#4}}%
         \end{varwidth}%
      \else%
         \raisebox{.38\zw}{%
            \begin{varwidth}[t]{\maxdimen}%
               \IfBooleanTF{#1}{\wrap@undernote@par{#4}}{\wrap@undernote{#4}}%
            \end{varwidth}%
         }%
      \fi%
   }%
   \endgroup%
}

% 名称カウンタ
\def\@note@save@conters{
   \group_begin:
      \cs_set:Npn \@elt ##1 {
         \str_if_eq:nnF { ##1 } { page }
         { 
            \int_gset:cn { c@ ##1 } { \int_use:c { c@ ##1 } } 
         }
      }
      \tl_set:Nx \l_tmpa_tl { \cl@@ckpt }
   \exp_args:NNNV \group_end: \tl_set:Nn \l_tmpa_tl \l_tmpa_tl
      % グループ外への持ち出し
  
  \cs_gset_eq:NN \@note@restore@counters \l_tmpa_tl
}

% 数式モードの場合への対応
\def\@math@undernote#1#2#3{%
   \mathchoice{%
      \settowidth{\undernote@textlen@tempo}{\m@th$\displaystyle #2$}%
      \@note@restore@counters\@text@undernote{#1}{\m@th$\displaystyle #2$}{#3}%
   }{%
      \settowidth{\undernote@textlen@tempo}{\m@th$\textstyle #2$}%
      \@note@restore@counters\@text@undernote{#1}{\m@th$\textstyle #2$}{#3}%
   }{%
      \settowidth{\undernote@textlen@tempo}{\m@th$\scriptstyle #2$}%
      \@note@restore@counters\@text@undernote{#1}{\m@th$\scriptstyle #2$}{#3}%
   }{%
      \settowidth{\undernote@textlen@tempo}{\m@th$\scriptscriptstyle #2$}%
      \@note@restore@counters\@text@undernote{#1}{\m@th$\scriptscriptstyle #2$}{#3}%
   }%
}

% 注釈の内部実装
\prg_new_conditional:Nnn \__modernruler_if_file_write: { p, T, F, TF }
  {
    \legacy_if:nTF { @filesw }
      { \prg_return_true: }
      { \prg_return_false: }
  }

\long\def\@text@undernote#1#2#3{%
   \hbox{%
      \def\@UNDATA@vsize{#1}% 
         % \undernoteの第2引数
         % 指定ありor無しで処理を分岐させる
      \tl_if_empty:cT { @UNDATA@vsize } 
         {
            \cs_if_eq:cNTF
               { @UNDATAS@\the\c@undernote@id } \relax 
               { 
                  \def\@UNDATA@vsize{1}
               }
               { 
                  \edef\@UNDATA@vsize{\csname @UNDATAS@\the\c@undernote@id\endcsname}
               }
         }
      \hbox_set:Nn \@undernote@maintext { #2\mruletv[height=.8\zw, width=0pt, color=\notelinecolor@internal@undernote] }
         % \undernoteの第３引数
      \hbox_set:Nn \@undernote@subtext { \notesize@internal@undernote #3 }
         % \undernoteの第４引数
      \vtop{%
         \box_use:N \@undernote@maintext% 
         \group_begin:
            \notesize@internal@undernote% 
            \__modernruler_if_file_write:TF 
               {
                  \dim_set:Nn \dimen@ {\box_wd:N \@undernote@subtext + \notesep@internal@undernote}
                  \cs_set:Npx \l_tmpa_tl 
                     {
                        \write\@auxout{%
                           \string\undernotedata@internal{\the\c@undernote@id}%
                              {\noexpand\zposx{unote-\the\c@undernote@id}}{\noexpand\zposy{unote-\the\c@undernote@id}}
                              {\number\dimen@}{\number\ht\@undernote@subtext}{\number\dp\@undernote@subtext}%
                              {\noexpand\the\c@page}{\number\dp\@undernote@maintext}%
                                 % これで.auxに
                                 % \undernotedata@internal
                                 %   {<id>}{<xpos>}{<ypos>}{<width of the note>}{<height of the note>}
                                 %   {<depth of the note>}{<page>}{<depth of the maintext>}
                                 % が書き込まれる
                        }
                     }
                  \l_tmpa_tl 
               }
               {
                  \iow_term:n { }
               }
         \group_end:
         \skip_vertical:n { 1pt }
         \hline@undernote@par% 
            %アンダーライン
         \hbox{\notesize@internal@undernote% 
               % サイズ指定
            \skip_horizontal:n { \noterulehshift@internal@undernote }
               % 横に少しずらす
            \int_set:Nn \count@ { \@UNDATA@vsize - 1 }
               % \count@ = 現在の段 - 1 
            \dim_set:Nn \dimen@ { \noteshift@internal@undernote * \count@ + \notepos@internal@undernote }
               % \count@*\dimen@ i.e. ノートの縦幅だけ下へ
               % 縦線の長さの分さらに下へ
            \vlines@undernote@par%
               % 縦線を出力
            \box_move_down:nn { 0.38 \zw } { \hbox_to_zero:n { \box_use:N \@undernote@subtext \hss } }
         }%
         \skip_vertical:n { .3\zw }
      }%
   }%
}

\int_new:N \@UNDATA@min
\int_new:N \@UNDATA@max
\int_gset:Nn \@UNDATA@max { -10000 }
\tl_gclear:N \@UNDATA@idlist
\cs_set_eq:NN \@UNDATA@elt \relax
\msg_new:nnn { modernruler } { multiple-labels } { There ~ were ~ multiply-defined ~ labels }

\def\undernotedata@internal#1#2#3#4#5#6#7#8{%
   \cs_if_exist:cTF { @UNDATA@ #1 }
      {
         \msg_warning:nn { modernruler } { multiple-labels }
      }
      {
         \int_set:Nn \@tempcnta { \@UNDATA@max + 1 }

         \int_compare:nNnTF { \@tempcnta } = { #1 }
         {
            \int_gset:Nn \@UNDATA@max { \@tempcnta }
         }
         {
            \int_compare:nNnF { \@UNDATA@max } < { 0 }
            {
               \tl_gput_right:Nx \@UNDATA@idlist
                  {
                     \exp_not:N \@UNDATA@elt
                     { \int_use:N \@UNDATA@min }
                     { \int_use:N \@UNDATA@max }
                  }
            }
            \int_gset:Nn \@UNDATA@min { #1 }
            \int_gset:Nn \@UNDATA@max { \@UNDATA@min }
         }
      }
   \cs_gset:cpn { @UNDATA@ #1 } { {#2}{#3}{#4}{#5}{#6}{#7}{#8} }
      % データを.aux用に格納
}

\cs_set:Npn \@undernotedata #1#2#3#4#5#6#7#8
   {
      \str_if_eq:eeTF 
         { \cs_if_exist_use:c { @UNDATA@ #1 } } 
         { {#2}{#3}{#4}{#5}{#6}{#7}{#8} }
         { }
         {
            \legacy_if_set_true:n { @tempswa }
         }
   }

\cs_set:Npn \checkundernotedata
   {
      \int_compare:nNnF { \@UNDATA@max } < { 0 }
         {
            \tl_gput_right:Nx \@UNDATA@idlist
               {
                  \exp_not:N \@UNDATA@elt
                  { \int_use:N \@UNDATA@min }
                  { \int_use:N \@UNDATA@max }
               }
            
            \group_begin:
               \cs_set_eq:NN \@UNDATA@elt \@check@undernotedata
               \@UNDATA@idlist
            \group_end:
         }
   }

\def\@check@undernotedata#1#2{%  
   %%% RESET
   \tl_set:Nn \@currpage { -10000 }
   \int_set:Nn \@tempcnta { 0 }
   \int_set:Nn \@tempcntb { 0 }
   \dim_set:Nn \@tempdima { -1pt }
   \dim_set:Nn \@tempdimb { -1pt }
   \tl_clear:N \@linelist
   \cs_set_eq:NN \@elt \relax
   %%%

   \int_set:Nn \count@ { #1 - 1 }
   \int_while_do:nNnn { \count@ } < { #2 }
      {
         \int_add:Nn \count@ { 1 }

         \@check@undernotedata@split\count@%

         \bool_set_false:N \l_tmpa_bool

         \int_compare:nNnTF { \@currpage } = { \@thispage }
            {
               \dim_compare:nNnTF { \@thisy sp } < { \@tempdima }
                  { \bool_set_false:N \l_tmpa_bool } % 範囲外（下）
                  {
                     \dim_compare:nNnTF { \@thisy sp } > { \@tempdimb }
                        { \bool_set_false:N \l_tmpa_bool } % 範囲外（上）
                        { \bool_set_true:N \l_tmpa_bool }  % 範囲内
                  }
            }
            { \bool_set_false:N \l_tmpa_bool } % ページが違う

         % 判定結果に基づいた処理
         \bool_if:NTF \l_tmpa_bool
            {
               % T のとき：範囲内なので継続（\@tempcntb を更新）
               % \@tempcntb \count@
               \int_set_eq:NN \@tempcntb \count@
            }
            {
               % F のとき：範囲外なのでリストを書き出してリセット
               \int_compare:nNnT { \@tempcnta } > { 0 }
                  {
                     \tl_put_right:Nx \@linelist { \@elt { \int_use:N \@tempcnta } { \int_use:N \@tempcntb } }
                  }
               \int_set_eq:NN \@tempcnta \count@ 
               \int_set_eq:NN \@tempcntb \count@
               \cs_set_eq:NN \@currpage \@thispage
               \dim_set:Nn \@tempdima { \@thisy sp }
               \dim_set_eq:NN \@tempdimb \@tempdima
               \dim_sub:Nn \@tempdima { \@UNDATA@yfuzz }
               \dim_add:Nn \@tempdimb { \@UNDATA@yfuzz }
            }
      }
   \tl_put_right:Nx \@linelist { \@elt { \the\@tempcnta } { \the\@tempcntb } }
   \cs_set_eq:NN \@elt \@check@undernotedata@elt
   \@linelist%
}

\cs_set:cpn { @UNDATA@yfuzz } { 3pt }

\def\@check@undernotedata@split#1{
   % \undernotedata@internal で作ったデータを分割
   \expandafter\expandafter\expandafter\@check@undernotedata@split@\csname @UNDATA@\number#1\endcsname 0000000\@nnil%
      % なんらかの理由でデータ数が不足した場合：
      % -- 0が\@check@undernotedata@split@の引数に取り込まれる。
      % -- 個数が足りている場合は全部第8引数に吸い込まれる。
}
\def\@check@undernotedata@split@#1#2#3#4#5#6#7#8\@nnil{
   \tl_set:Nn \@thisx { #1 }
   \tl_set:Nn \@thisy { #2 }
   \tl_set:Nn \@thiswd { #3 }
   \tl_set:Nn \@thisht { #4 }
   \tl_set:Nn \@thisdp { #5 }
   \tl_set:Nn \@thispage { #6 }
   \tl_set:Nn \@thismaindp { #7 }
}

\def\@check@undernotedata@elt#1#2{%
   % 重複判定本体
   \int_set:Nn \count@ { #2 }
   \int_add:Nn \count@ { 1 }

   \int_while_do:nNnn { \count@ } > { #1 }
      {
         \int_sub:Nn \count@ { 1 }
         \@check@undernotedata@split\count@
         \dim_set:Nn \dimen@ 
            { 
               % 注釈の右端の物理的限界位置
               \@thisx sp + \@thiswd sp 
               + \noterulehsize@internal@undernote
            }
         \cs_set_eq:NN \@currht \@thisht
         \int_set:Nn \@tempcntb { 1 }
         \int_set:Nn \@tempcnta { \count@ }
         \int_while_do:nNnn { \@tempcnta } < { #2 }
            {
               \int_add:Nn \@tempcnta { 1 }
               \@check@undernotedata@split\@tempcnta%
               \dim_compare:nNnT { \@thisx sp } < { \dimen@ }
                  {
                     \dim_set_eq:NN \@tempdima \noteshift@internal@undernote
                     \dim_set:Nn \@tempdimb 
                        { 
                           \@thisdp sp + \@currht sp + 
                           \lineskip +
                           % メインテキストの深さを考慮
                           \@thismaindp sp 
                        }
                     \int_set:Nn \l_tmpa_int 
                        {  
                           % 段数に比率で変換
                           % ただし重なりがあった場合には必ず1段以上下げる
                           \fp_eval:n { floor( \dim_to_fp:n { \@tempdimb } / \dim_to_fp:n { \@tempdima } ) } + 1
                        }
                     \int_add:Nn \l_tmpa_int { \use:c { @UNDATAS@ \the \@tempcnta } }
                     \int_set:Nn \@tempcntb { \int_max:nn { \@tempcntb } { \l_tmpa_int } }
                  }
            }
         \cs_gset:cpx { @UNDATAS@ \the\count@ } { \int_use:N \@tempcntb }
      }
}

\AtEndDocument{%
   \legacy_if:nT { @filesw }
      {
         \write\@auxout{\string\checkundernotedata}
         \let\checkundernotedata\relax
         \def\undernotedata@internal{\@undernotedata}
      }
}
%%%

\endinput