\documentclass[luatex,fontsize=8pt,paper=b5,twoside]{jlreq}%
\usepackage{amsmath,amssymb}
\usepackage{booktabs,caption}
\usepackage{luwa-ul}
\usepackage[most]{tcolorbox}
\usepackage{luatexja-ruby,lltjext}
\usepackage[noteoverhang=7em]{modernruler}

\usepackage{listings}
\lstset{
    basicstyle=\ttfamily\small,
    keywordstyle=\color{blue},
    commentstyle=\color{gray},
    stringstyle=\color{red},
    breaklines=true,
    breakatwhitespace=false,  
    columns=flexible           
}

% You can omit these font settings.
\makeatletter
\RequirePackage[no-math]{fontspec}
\RequirePackage[no-math,match,scale=1]{luatexja-fontspec}
\RequirePackage[hiragino-pro,deluxe,expert]{luatexja-preset}
\setmainfont{HiraMinPro-W3}[BoldFont=HiraMinPro-W6]
\setmainjfont{HiraMinPro-W3}[BoldFont=HiraMinPro-W6]
\newfontfamily{\sfhira@pre}{HiraKakuPro-W3}[BoldFont=HiraKakuPro-W6]
\newjfontfamily{\sfhiraj@pre}{HiraKakuPro-W3}[BoldFont=HiraKakuPro-W6]
\newfontfamily{\mchira@pre}{HiraMinPro-W3}[BoldFont=HiraMinPro-W6]
\newjfontfamily{\mchiraj@pre}{HiraMinPro-W3}[BoldFont=HiraMinPro-W6]
\newfontfamily{\gthira@pre}{HiraKakuPro-W3}[BoldFont=HiraKakuPro-W6,FontFace={eb}{\shapedefault}{HiraKakuStd-W8}]
\newjfontfamily{\gthiraj@pre}{HiraKakuPro-W3}[BoldFont=HiraKakuPro-W6,FontFace={eb}{\shapedefault}{HiraKakuStd-W8}]
\newfontfamily{\mghira@pre}{HiraMaruPro-W4}
\newjfontfamily{\mghiraj@pre}{HiraMaruPro-W4}
\renewcommand{\sffamily}{\sfhira@pre\sfhiraj@pre}
\renewcommand{\mcfamily}{\mchira@pre\mchiraj@pre}
\renewcommand{\gtfamily}{\gthira@pre\gthiraj@pre}
\renewcommand{\mgfamily}{\mghira@pre\mghiraj@pre}
\makeatother
%%%


\usepackage{hyperref} 
\hypersetup{
  luatex, pdfencoding=auto, 
  colorlinks=true,
  linkcolor=black,     
  citecolor=black,     
  urlcolor=DeepSkyBlue3,      
  pdfborder={0 0 0}, 
}

\colorlet{grayLight}{white!80!black} 

\NewTCBListing{SourceCode}{ m m !o !O{DeepSkyBlue3} }{%
  enhanced, colback=black!70, colframe=Snow4,
  toptitle=-1mm, bottomtitle=-1mm,
  righttitle=-1mm, lefttitle=-1mm,
  arc=.5mm, 
  title={\tcbox[on line, arc=.5mm, boxsep=0pt, boxrule=0pt, top=1mm, bottom=0.8mm, left=2mm, right=2.2mm, colback=gray!80, coltext=white]{\raisebox{-0.1ex}{\vphantom{羅}\vphantom{j}#1}}},fonttitle=\gtfamily\footnotesize,boxrule=0.8pt,
  breakable,before upper={\color{white}},top=-0.5mm,bottom=-0.5mm,
  after title=\IfNoValueTF{#3}{}{{\hfill\tcbox[on line, arc=.5mm, boxsep=0pt, boxrule=0pt, top=1mm, bottom=0.8mm, left=2mm, right=2.2mm, colback=white!80!black, coltext=#4]{\raisebox{-0.1ex}{\vphantom{羅}\vphantom{j}#3}}}},
  listing only,
  listing options={
    language={#2},
    basicstyle=\ttfamily,
    keywordstyle=\ttfamily\color{white},
    stringstyle=\itshape\color{white},
    commentstyle=\small\gtfamily\color{DeepSkyBlue2},
    showspaces=false,showtabs=false,
    breaklines=true,breakindent=0pt,
    showstringspaces=false,
    columns=fullflexible,
    tabsize=2,
    numbers=left,numbersep=1.5pt,
    numberstyle=\scriptsize\gtfamily\color{gray},
  }
}

\NewTColorBox{OutPut}{ m !o !O{DeepSkyBlue3} }{%
  enhanced, colframe=Snow4,
  toptitle=-1mm, bottomtitle=-1mm,
  righttitle=-1mm, lefttitle=-1mm,
  arc=.5mm, colback=white, 
  title={\tcbox[on line, arc=.5mm, boxsep=0pt, boxrule=0pt, top=1mm, bottom=0.8mm, left=2mm, right=2.2mm, colback=gray!40, coltext=DeepSkyBlue3]{\raisebox{-0.1ex}{\vphantom{羅}\vphantom{j}#1}}},fonttitle=\gtfamily\footnotesize,boxrule=0.8pt,
  breakable,top=-0.5mm,bottom=-0.5mm,
  after title=\IfNoValueTF{#2}{}{{\hfill\tcbox[on line, arc=.5mm, boxsep=0pt, boxrule=0pt, top=1mm, bottom=0.8mm, left=2mm, right=2.2mm, colback=white!80!black, coltext=#3]{\raisebox{-0.1ex}{\vphantom{羅}\vphantom{j}#2}}}}, bottom=2mm, top=2mm, 
}


\title{\texttt{modernruler} Package Documentation}
\author{Kosei Kawaguchi a.k.a. KKTeX}
\date{Version 1.3.1 (2025/01/26)}

\begin{document}
\begin{titlepage}
  \maketitle
\end{titlepage}
\newpage
\tableofcontents
\newpage

\section{Outline}
This package provides modern hrule (\verb|\mruleth|), vrule (\verb|\mruletv|), and \verb|\undernote| internally uses the two commands.

\begin{SourceCode}{Intput}{TeX}
  % normal rule
  \mruleth[height=1pt, width=5cm, color=blue]

  % dashed rule
  \mruleth[height=2pt, width=8cm, color=red, dash=true, dash-len=5pt, gap-len=3pt]

  % inline rule
  This is \mruletv[height=\zw, depth=1.5\zw, width=1pt, color=green] a modern vrule.

  % inline dashed rule
  This is \mruletv[height=2\zw, width=1.5pt, color=orange, dash=true, dash-len=2pt, gap-len=1pt] a dashed modern vrule.

  % undernote
  This is under note. This uses \undernote{these commands}{\texttt{\textbackslash mruleh} and \texttt{\textbackslash mrulev}} internally and enables make flexible outputs.
\end{SourceCode}
\begin{OutPut}{Output}
  % normal rule
  \mruleth[height=1pt, width=5cm, color=blue]

  % dashed rule
  \mruleth[height=2pt, width=8cm, color=red, dash=true, dash-len=5pt, gap-len=3pt]

  % inline rule
  This is \mruletv[height=\zw, depth=1.5\zw, width=1pt, color=green] a modern vrule.

  % inline dashed rule
  This is \mruletv[height=2\zw, width=1.5pt, color=orange, dash=true, dash-len=2pt, gap-len=1pt] a dashed modern vrule.

  % undernote
  This is under note. This uses \undernote{these commands}{\texttt{\textbackslash mruleh} and \texttt{\textbackslash mrulev}} internally and enables make flexible outputs.
\end{OutPut}

\section{Acknowledgements / Credits}
This package was inspired by discussions on TeX Forum concerning
undernote-like constructions using rules.

An improved approach was later presented by Mr.~Yusuke~Terada,
which clarified several implementation details.

The present package is a complete reimplementation and extension,
introducing a generalized rule-based engine, redesigned control flow,
and additional features such as modern ruler integration and
\texttt{tcolorbox}-based abstractions.

Any remaining errors or design decisions are entirely the
responsibility of the author.

\section{Note}
\textbf{This package only supports LuaLaTeX.}

In this package, a unit \verb|\zw| is used in many parts. It is Japanese standard unit, but it's not normal outside of Japan. When you encounter \verb|\zw| in documemntations, please understand it as \verb|1em|. In detail, \verb|\zw| and \verb|1em| is differnt when you use Japanese characters. But only when you use alphabetic characters and numbers, the difference doesn't matter. 

\section{Installation}
\begin{SourceCode}{Intput}{TeX}
  \usepackage[<options>]{modernruler}
\end{SourceCode}

Detailed information regarding the options will be provided in a later section, specifically during the explanation of the \verb|\undernote| command.

\section{Commands}
\subsection{\texttt{\textbackslash mruleth, \textbackslash mruletv}}
\subsubsection{Basic Usage}
In the first place, \verb|\mruleth| and \verb|mruletv| are extended \verb|\hrule| and \verb|\vrule|. You can use them like this:

\begin{SourceCode}{Intput}{TeX}
  \mruleth[<keyvaloptions>]
  \mruletv[<keyvaloptions>]
\end{SourceCode}

These commands share the same keys.\bigskip

\begin{center}
  \begin{tabular}{llll}
    \toprule
    \textbf{Key} & \textbf{Type} & \textbf{Default} & \textbf{Description} \\ \midrule
    width & dim & 0pt & Width of the rule \\
    height & dim & 0pt & Height above the baseline \\
    depth & dim & 0pt & Depth below the baseline \\
    color & tl & black & Color of the rule \\
    gap-color & tl & white & Color of the gap segments \\
    dash & bool & false & Enables dashed line if true \\
    dash-len & dim & 3pt & Length of the dash segment \\
    gap-len & dim & 2.5pt & Length of the gap between dashes \\
    \bottomrule
  \end{tabular}
\end{center}\bigskip

The outputs are as follows:

\begin{SourceCode}{Intput}{TeX}
  \fboxsep=0pt\fboxrule=.1pt%

  % horizontal rule
  \fbox{\mruleth[height=1pt, width=55pt, color=blue]}
  \fbox{\mruleth[height=1pt, width=55pt, color=blue, dash=true]}
  \fbox{\mruleth[height=1pt, width=57pt, color=blue, dash=true]}
  \fbox{\mruleth[height=1pt, width=59pt, color=blue, dash=true]}

  % vertical rule
  \fbox{\mruletv[width=1pt, height=55pt, color=blue]}
  \fbox{\mruletv[width=1pt, height=55pt, color=blue, dash=true]}
  \fbox{\mruletv[width=1pt, height=57pt, color=blue, dash=true]}
  \fbox{\mruletv[width=1pt, height=59pt, color=blue, dash=true]}\bigskip

  % Horizontal: Alternating Black and Cyan segments
  \mruleth[width=120pt, height=2pt, dash=true, dash-len=6pt, gap-len=6pt, color=black, gap-color=cyan]\bigskip

  % Vertical: Warning Pattern (Yellow and Black)
  \mruletv[width=3pt, height=50pt, dash=true, dash-len=8pt, gap-len=4pt, color=yellow, gap-color=black]
\end{SourceCode}

\begin{OutPut}{Output}
  \fboxsep=0pt\fboxrule=.1pt%
  
  \fbox{\mruleth[height=1pt, width=55pt, color=blue]}
  \fbox{\mruleth[height=1pt, width=55pt, color=blue, dash=true]}
  \fbox{\mruleth[height=1pt, width=57pt, color=blue, dash=true]}
  \fbox{\mruleth[height=1pt, width=59pt, color=blue, dash=true]}

  \fbox{\mruletv[width=1pt, height=55pt, color=blue]}
  \fbox{\mruletv[width=1pt, height=55pt, color=blue, dash=true]}
  \fbox{\mruletv[width=1pt, height=57pt, color=blue, dash=true]}
  \fbox{\mruletv[width=1pt, height=59pt, color=blue, dash=true]}

  \bigskip

  % Horizontal: Alternating Black and Cyan segments
  \mruleth[width=120pt, height=2pt, dash=true, dash-len=6pt, gap-len=6pt, color=black, gap-color=cyan]

  \bigskip

  % Vertical: Warning Pattern (Yellow and Black)
  \mruletv[width=3pt, height=50pt, dash=true, dash-len=8pt, gap-len=4pt, color=yellow, gap-color=black]
\end{OutPut}

\subsubsection{Advanced usage: Use Like Phantom}
By setting the width to zero, these commands can be used as "phantoms" that provide arbitrary height and depth. 
In a traditional way to set a phantom, you use \verb|\vphantom| or \verb|\hphantom|. How ever, the total-height or width depends on the argument. So, I recommend you to use the modern-rulers as a flexible phantom.

\begin{SourceCode}{Intput}{TeX}
  % To visualize
  \fboxrule=.1pt\fboxsep=0pt 

  % modern-vphantom
  abc\fbox{\mruleth[height=2em, depth=.5em, width=0pt]def}ghi

  % modern-hphantom
  jkl\fbox{\mruletv[height=0pt, width=2em]mno\mruletv[height=0pt, width=1em]}pqr
\end{SourceCode}

\begin{OutPut}{Output}
  % To visualize
  \fboxrule=.1pt\fboxsep=0pt 

  % modern-vphantom
  abc\fbox{\mruleth[height=2em, depth=.5em, width=0pt]def}ghi

  % modern-hphantom
  jkl\fbox{\mruletv[height=0pt, width=2em]mno\mruletv[height=0pt, width=1em]}pqr
\end{OutPut}

\subsection{\texttt{\textbackslash undernote}}
\subsubsection{Basic Usage}
This commands provides underlined \undernote{annotation}{Like this.}. There is some optional parameters which adjust the position of the annotation text.

\begin{SourceCode}{Intput}{TeX}
  % grammar
  \undernote<star option>[<number of lines to shift the note downward>]{<the target phrase>}{<annotation>}[<style>]

  % example
  In this single paragraph, we deliberately place many annotated terms to
  stress-test the undernote mechanism, starting with a
  \undernote{concept}{A brief explanation of the main concept}
  that appears early in the line, followed closely by another\\
  \undernote{idea}{A slightly longer explanatory note that is expected to
  interact with nearby notes} to encourage horizontal overlap detection.
  As the sentence continues, we insert a fixed-level annotation such as
  \undernote[2]{method}{This note is forced onto the second vertical level}
  to verify that manual level assignment overrides automatic stacking,
  and later a short
  \undernote{term}{Short note}
  next to a much longer
  \undernote*{expression}{This is a considerably longer explanatory note
  designed to increase the occupied width and push subsequent notes
  downward in the vertical stacking algorithm}.
  Near the end of the paragraph, we add one more fixed example,
  \undernote[3]{result}{A third-level note used to confirm deep stacking},
  followed immediately by an automatic one,
  \undernote*{observation}{This final note should be placed at a safe
  vertical distance determined by the collision analysis performed
  during the previous compilation run}.
\end{SourceCode}

\begin{OutPut}{Output}
  In this single paragraph, we deliberately place many annotated terms to
  stress-test the undernote mechanism, starting with a
  \undernote{concept}{A brief explanation of the main concept}
  that appears early in the line, followed closely by another\\
  \undernote{idea}{A slightly longer explanatory note that is expected to
  interact with nearby notes} to encourage horizontal overlap detection.
  As the sentence continues, we insert a fixed-level annotation such as
  \undernote{method}{This note is forced onto the second vertical level}
  to verify that manual level assignment overrides automatic stacking,
  and later a short
  \undernote[2]{term}{Short note}
  next to a much longer
  \undernote*{expression}{This is a considerably longer explanatory note
  designed to increase the occupied width and push subsequent notes
  downward in the vertical stacking algorithm}.
  Near the end of the paragraph, we add one more fixed example,
  \undernote*{result}{A third-level note used to confirm deep stacking},
  followed immediately by an automatic one,
  \undernote*{observation}{This final note should be placed at a safe
  vertical distance determined by the collision analysis performed
  during the previous compilation run}.
\end{OutPut}

As the example above shows, the star option puts the annotation text in a parabox. So when you include a long description in the fourth argument of the \verb|\undernote|, the option is the best way to avoid overflow.

Regarding the second argument, ``number of lines to shift the note downward'' is always determined automatically if you don't specify it. I recommend using this option only when annotations are too close to each other.

Of course, this package provides some package options for adjustments.\bigskip

\begin{center}
  \begin{tabular}{llll}
    \toprule
    \textbf{Key} & \textbf{Type} & \textbf{Default} & \textbf{Description} \\ \midrule
    notesize          & tl   & \verb|\footnotesize|& Font size of the note text \\
    notepos           & dim  & 3mm           & Minimum vertical length of the line to the note \\
    noteshift         & dim  & 1mm           & Vertical shift amount per level for overlapping notes \\
    noterulethickness & dim  & .4pt          & Thickness of the rule used in the note \\
    noterulehshift    & dim  & 1.5mm         & Horizontal offset of the vertical line from the underline start \\
    noterulehsize     & dim  & 1.5mm         & Length of the horizontal line extending to the note \\
    notesep           & dim  & 2em           & Minimum horizontal distance to prevent note overlap \\
    noteoverhang      & dim  & 3em           & Extension length of the note parbox (starred version) \\
    parstyle          & int  & 0             & Border style (0: none, 1: solid, 2: dashed) \\
    \bottomrule
  \end{tabular}
\end{center}\bigskip

When you want to change some settings in the middle of the document, you can use the following commands:

\begin{center}
  \begin{tabular}{llll}
    \toprule
    \textbf{Key (Command)} & \textbf{Type} & \textbf{Default} & \textbf{Description} \\ \midrule
    \verb|\SetUNoteSize|          & tl   & \verb|\footnotesize| & Sets the font size of the note \\
    \verb|\SetUNoteRuleThickness| & dim  & .4pt                 & Sets the thickness of the note rules \\
    \verb|\SetUNoteRuleHShift|    & dim  & 1.5mm                & Sets the horizontal offset of the vertical rule \\
    \verb|\SetUNoteRuleHSize|     & dim  & 1.5mm                & Sets the length of the horizontal rule \\
    \verb|\SetUNotePos|           & dim  & 3mm                  & Sets the minimum vertical line length \\
    \verb|\SetUNoteShift|         & dim  & 1mm                  & Sets the vertical shift amount per level \\
    \verb|\SetUNoteSep|           & dim  & 2em                  & Sets the minimum horizontal separation between notes \\
    \verb|\SetUNoteOverHang|      & dim  & 3em                  & Sets the overhang length for parbox notes \\
    \verb|\SetUNoteParstyle|      & int  & 0                    & Updates the border style and drawing logic \\
    \bottomrule
  \end{tabular}
\end{center}\bigskip

\subsubsection{Additional Description}
You can use the command in mathmode.

\begin{SourceCode}{Intput}{TeX}
  \[\undernote{x + y}{In the equation envriomnemt.} = \undernote{\frac{a}{b}}{No problem.}\]
\end{SourceCode}

\begin{OutPut}{Output}
  \[\undernote{x + y}{In the equation envriomnemt.} = \undernote{\frac{a}{b}}{No problem.}\]
\end{OutPut}

\section{License}
Released under the MIT License.

\section{Version History}
\begin{itemize}
  \item \textbf{v1.0.0} --- Initial public release.
  \item \textbf{v1.1.0} --- Add a fallback for \verb|\zw| and \verb|\ltjgetparameter|.
  \item \textbf{v1.3.0} --- Fixed a bug which occurs when \verb|\undernote| command is used in mathmode. The bug was caused my misreplacement of \verb|\@elt|.
\end{itemize}

\section{Source Code}
\begin{lstlisting}
  \NeedsTeXFormat{LaTeX2e}
  \ProvidesPackage{modernruler}[2026/01/26, Version 1.3.1]

  %%% parameters
  \unless\ifdefined\zw
    \newdimen\zw
    \zw=1em
  \fi
  \unless\ifdefined\ltjgetparameter
    \newcommand{\ltjgetparameter}[1]{4}
  \fi

  %%% basical settings
  \RequirePackage{kvoptions} 
  \RequirePackage{varwidth}
  \RequirePackage[most]{tcolorbox}

  %%% kv（undernoteの方）
  \SetupKeyvalOptions{%
    family=undernote,%
    prefix=undernote@%
  }
  \DeclareStringOption[\footnotesize]{notesize}
  \DeclareStringOption[3mm]{notepos}
  \DeclareStringOption[1mm]{noteshift}
  \DeclareStringOption[.4pt]{noterulethickness}
  \DeclareStringOption[1.5mm]{noterulehshift}
  \DeclareStringOption[1.5mm]{noterulehsize}
  \DeclareStringOption[2em]{notesep}
  \DeclareStringOption[3em]{noteoverhang}
  \DeclareStringOption[0]{parstyle}
  \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}    
    %%% \note で用いる罫線の太さ
  \def\noterulehshift@internal@undernote{\undernote@noterulehshift}          
    %%% 注釈へと伸ばす縦線の位置（注釈をつける語句につけた下線の左端から
    %%% \noterulehshift@internal@undernote だけ右にずれた位置に縦線を置く）
  \def\noterulehsize@internal@undernote{\undernote@noterulehsize}           
    %%% 注釈へと伸ばす横線の長さ
  \def\notesep@internal@undernote{\undernote@notesep}                        
    %%% 前にある注釈が次の注釈の縦線から \notesep@internal@undernote 以内に近づくようなら，
    %%% 前にある注釈を下にずらす（「2em」のように文字サイズに依存する
    %%% 指定をした場合は，\notesize@internal@undernote（の，現在使用中のフォント）における値）
  \def\noteoverhang@internal@undernote{\undernote@noteoverhang}                                 
    %%% parbox に入れるタイプ（スターをつけた時）
    %%% どの程度後ろに注釈部分を張り出させるか
  \def\noteparstyle@internal@undernote{\undernote@parstyle}                                     
    %%% 注釈部分を
    %%% 1 と 2 以外: 囲みなし 1: 実線で囲う 2:点線で囲う


  % command
  \NewDocumentCommand{\SetUNoteSize}{O{\footnotesize}}{%
    \def\notesize@internal@undernote{#1}%
  }                 
  \NewDocumentCommand{\SetUNoteRuleThickness}{O{.4pt}}{%
    \def\noterulethickness@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNoteRuleHShift}{O{1.5mm}}{%
    \def\noterulehshift@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNoteRuleHSize}{O{1.5mm}}{%
    \def\noterulehsize@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNotePos}{O{3mm}}{%
    \def\notepos@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNoteShift}{O{1mm}}{%
    \def\noteshift@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNoteSep}{O{2em}}{%
    \def\notesep@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNoteOverHang}{O{3em}}{%
    \def\noteoverhang@internal@undernote{#1}%
  }
  \NewDocumentCommand{\SetUNoteParstyle}{O{0}}{%
    \ifnum#1=1%
    \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]}%
    \def\vlines@undernote@par{%
        \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt]%
        \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt]%
    }%
    \else\ifnum#1=2
        \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]}%
        \def\vlines@undernote@par{%
          \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt ,dash=true]%
          \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, dash=true]%
        }%
        \else
          \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]}%
          \def\vlines@undernote@par{%
              \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt]%
              \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt]%
          }%
    \fi\fi
  }
  %%%

  %%% modern rule commands
  \ExplSyntaxOn

  % 変数の宣言
  \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:
    }
  \ExplSyntaxOff
  %%%

  \DeclareTotalTCBox{\FramedBox@undernote}{ O{} +m }{%
    on line,arc=0pt,
    sharp corners,boxsep=0mm,
    left=.3mm,right=.3mm,top=0.3mm,bottom=0.3mm,
    colback=white,colframe=white,
    enhanced,before={\hspace*{-.1722\zw}},
    borderline={\noterulethickness@internal@undernote}{0mm}{solid},
    #1
  }{#2}
  \DeclareTotalTCBox{\DashedBox@undernote}{ O{} +m }{%
    on line,arc=0pt,
    sharp corners,boxsep=0mm,
    left=.3mm,right=.3mm,top=0.3mm,bottom=0.3mm,
    colback=white,colframe=white,
    enhanced,before={\hspace*{-.1722\zw}},
    borderline={\noterulethickness@internal@undernote}{0mm}{dashed},
    #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,
    enhanced,before={\hspace*{-.1722\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}{.2153\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}{.2153\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}{.2153\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
    \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]}%
    \def\vlines@undernote@par{%
        \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt]%
        \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt]%
    }
  \else\ifnum\noteparstyle@internal@undernote=2
    \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]}%
    \def\vlines@undernote@par{%
        \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt ,dash=true]%
        \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt, dash=true]%
    }
    \else
        \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]}%
        \def\vlines@undernote@par{%
          \mruletv[height=\dimen@, width=\noterulethickness@internal@undernote, depth=0pt]%
          \mruleth[height=\noterulethickness@internal@undernote, width=\noterulehsize@internal@undernote, depth=0pt]%
        }
  \fi\fi

  \newbox\@undernote@maintext
  \newbox\@undernote@subtext
  \newcounter{undernote@id} \setcounter{undernote@id}{0}
  \DeclareDocumentCommand{\undernote}{ s O{} m +m O{} }{%
        %%% #1（star）注釈をparboxに包む
        %%% #2 (optinal): 注釈を下にずらす「行数」（与えない場合自動設定）
        %%% #3: 注釈をつける語句
        %%% #4: 注釈
        %%% #5: どういう線にするか
    \def\key@undernote@ruler{#5}%
    % \settowidth{\undernote@textlen@tempo}{#3}%
    \begingroup%
    \stepcounter{undernote@id}%
    \ifmmode%
        % \settowidth{\undernote@textlen@tempo}{\ensuremath{#3}}%
        \@note@save@conters%
        \savepos%
        \expandafter\@math@undernote
    \else%
        \settowidth{\undernote@textlen@tempo}{#3}%
        \leavevmode%
        \savepos%
        \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{%
    \begingroup%
    \def\@elt##1{%
        \expandafter\ifx\csname c@##1\endcsname\c@page\else
          \csname c@##1\endcsname\the\csname c@##1\endcsname\relax
        \fi}%
    \edef\@tempa{\cl@@ckpt}%
    \expandafter\endgroup%
    \expandafter\def\expandafter\@note@restore@counters\expandafter{\@tempa}%
  }

  % 数式モードの場合への対応
  \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}%
    }%
  }

  % 注釈の内部実装
  \long\def\@text@undernote#1#2#3{%
    \hbox{%
        \def\@UNDATA@vsize{#1}% \undernoteの第２引数
        \ifx\@UNDATA@vsize\@empty% 
              % 指定なしパターン
              % \undernoteの第２引数が空かそうでないか
          \expandafter\ifx\csname @UNDATAS@\the\c@undernote@id\endcsname\relax%
              % １回目のコンパイルではまだ空
              % →\relaxと比較してスルー
              \def\@UNDATA@vsize{1}%
          \else%
              % ２回目のコンパイルでは自動設定されている
              % →\@UNDATAS@12のようなデータを\@UNDATA@vsizeに格納
              \edef\@UNDATA@vsize{\csname @UNDATAS@\the\c@undernote@id\endcsname}%
          \fi%
        \fi%
        \setbox\@undernote@maintext\hbox{#2\mruletv[height=.8\zw, width=0pt]}% \undernoteの第３引数
        \setbox\@undernote@subtext\hbox{\notesize@internal@undernote #3}% \undernoteの第４引数
        \vtop{%
          \box\@undernote@maintext% 
          \begingroup%
              \notesize@internal@undernote% 
              \if@filesw% .auxへの書き出しokかどうか
                \dimen@\wd\@undernote@subtext%
                \advance\dimen@\notesep@internal@undernote\relax%
                      % 注釈の長さと、sepの長さを足す
                      % 水平方向にどれだけスペースをとっているか
                \edef\@tempa{%
                    \write\@auxout{% .auxへの書き出し
                      \string\undernotedata@internal{\the\c@undernote@id}%
                          {\noexpand\the\lastxpos}{\noexpand\the\lastypos}%
                          {\number\dimen@}{\number\ht\@undernote@subtext}{\number\dp\@undernote@subtext}%
                          {\noexpand\the\c@page}% これで.auxに
                                              % \undernotedata@internal{<id>}{<xpos>}{<ypos>}{<width of the note>}%
                                              % {<height of the note>}{<depth of the note>}{<page>}
                                              % が書き込まれる
                    }%
                }%
                \@tempa%
              \else%
                \write16{}% 書き出し不可の場合、何もしない
              \fi%
          \endgroup%
          \vskip1pt%
          \hline@undernote@par% アンダーライン
          \hbox{\notesize@internal@undernote% 
                % サイズ指定
              \hskip\noterulehshift@internal@undernote% 
                % 横に少しずらす
              \count@\@UNDATA@vsize\relax \advance\count@\m@ne% 
                % \count@ = 現在の段 - 1 
              \dimen@\noteshift@internal@undernote\relax \multiply\dimen@\count@%
                % \count@*\dimen@ i.e. 
                % ノートの縦幅だけ下へ
              \advance\dimen@\notepos@internal@undernote\relax% 
                % 縦線の長さの分さらに下へ
              \vlines@undernote@par%
                % 縦線を出力
              \hbox to \z@ {\lower.38\zw% 
                    % 注釈テキストを.38\zw下へ
                \box\@undernote@subtext\hss%
                    % 注釈配置
              }%
          }%
          \vskip .3\dimexpr\f@size pt\relax%
        }%
    }%
  }

  \newcount\@UNDATA@min
  \newcount\@UNDATA@max
  \global\@UNDATA@max -\@M
  \global\let\@UNDATA@idlist\@empty
  \let\@UNDATA@elt\relax
  \def\undernotedata@internal#1#2#3#4#5#6#7{%%% #1: id, #2: xpos, #3: ypos, #4: width of the note,
                                            %%% #5: height of the note, #6: depth of the note, #7: page
    \@ifundefined{@UNDATA@#1}%
        {\@tempcnta\@UNDATA@max \advance\@tempcnta\@ne%
          % 連番チェック
        \ifnum\@tempcnta=#1\relax%
            \global\@UNDATA@max\@tempcnta%
        \else%
            \ifnum\@UNDATA@max<\z@\else % 
                % 最初はmaxが-10000なので
                % 必ずこの分岐に入り
                % idlistが作られる
              \xdef\@UNDATA@idlist{\@UNDATA@idlist\@UNDATA@elt{\the\@UNDATA@min}{\the\@UNDATA@max}}%
                % １回目では\relaxが入ってるので
                % 残って２回目へ
            \fi%
            \global\@UNDATA@min=#1\relax%
            \global\@UNDATA@max\@UNDATA@min%
        \fi}%
        {\gdef\@multiplelabels{\@latex@warning@no@line{There were multiply-defined labels}}%
        \@latex@warning@no@line{Note ID `#1' multiply appeared}%
        }%
    \global\@namedef{@UNDATA@#1}{{#2}{#3}{#4}{#5}{#6}{#7}}%
        % データを.aux用に格納
  }

  \def\@undernotedata#1#2#3#4#5#6#7{%
    \def\@tempa{{#2}{#3}{#4}{#5}{#6}{#7}}%
    \expandafter\ifx\csname @UNDATA@#1\endcsname\@tempa\else \@tempswatrue \fi%
  }

  \def\checkundernotedata{%
    \ifnum\@UNDATA@max<\z@\else%
        \xdef\@UNDATA@idlist{\@UNDATA@idlist\@UNDATA@elt{\the\@UNDATA@min}{\the\@UNDATA@max}}%
        \begingroup%
          \let\@UNDATA@elt\@check@undernotedata%
          \@UNDATA@idlist%
        \endgroup%
    \fi%
  }

  \def\@check@undernotedata#1#2{%
    \def\@currpage{-10000}%
    \@tempcnta\z@ \@tempcntb\z@%
    \@tempdima-\p@ \@tempdimb-\p@%
    \let\@linelist\@empty%
    \let\@elt\relax%
    \count@#1\relax %
    \advance\count@\m@ne%
    \@whilenum\count@<#2\do{%
        \advance\count@\@ne%
        \@check@undernotedata@split\count@%
        \def\@tempz{T}%
        \ifnum\@currpage=\@thispage\relax%
          \ifdim\@thisy sp<\@tempdima \def\@tempz{F}\fi%
          \ifdim\@thisy sp>\@tempdimb \def\@tempz{F}\fi%
        \else%
          \def\@tempz{F}%
        \fi%
        \if T\@tempz\relax%
          \@tempcntb\count@%
        \else%
          \ifnum\@tempcnta>\z@%
              \edef\@linelist{\@linelist\@elt{\the\@tempcnta}{\the\@tempcntb}}%
          \fi%
          \@tempcnta\count@ \@tempcntb\count@%
          \let\@currpage\@thispage%
          \@tempdima\@thisy sp\relax%
          \@tempdimb\@tempdima%
          \advance\@tempdima -\@UNDATA@yfuzz\relax%
          \advance\@tempdimb  \@UNDATA@yfuzz\relax%
        \fi}%
    \edef\@linelist{\@linelist\@elt{\the\@tempcnta}{\the\@tempcntb}}%
    \let\@elt\@check@undernotedata@elt%
    \@linelist%
  }

  \def\@UNDATA@yfuzz{3\p@}

  \def\@check@undernotedata@split#1{%
    \expandafter\expandafter\expandafter\@check@undernotedata@split@%
        \csname @UNDATA@\number#1\endcsname 000000\@nnil%
  }

  \def\@check@undernotedata@split@#1#2#3#4#5#6#7\@nnil{%
    \def\@thisx{#1}%
    \def\@thisy{#2}%
    \def\@thiswd{#3}%
    \def\@thisht{#4}%
    \def\@thisdp{#5}%
    \def\@thispage{#6}%
  }

  \def\@check@undernotedata@elt#1#2{%
    \count@#2\relax%
    \advance\count@\@ne%
    \@whilenum\count@>#1\do{%
        \advance\count@\m@ne%
        \@check@undernotedata@split\count@%
        \dimen@\@thisx sp\relax%
        \advance\dimen@ \@thiswd sp\relax%
        \advance\dimen@\noterulehsize@internal@undernote\relax%
        \advance\dimen@\p@%
        \let\@currht\@thisht%
        \@tempcntb\@ne%
        \@tempcnta\count@%
        \@whilenum\@tempcnta<#2\do{%
          \advance\@tempcnta\@ne%
          \@check@undernotedata@split\@tempcnta%
          \ifdim\@thisx sp<\dimen@%
              \@tempdima\noteshift@internal@undernote\relax%
              \@tempdimb\@thisdp sp\relax%
              \advance\@tempdimb\@currht sp\relax%
              \advance\@tempdimb\lineskip%
              \divide\@tempdimb\@tempdima%
              \count\tw@\@tempdimb%
              \advance\count\tw@ \@ne%
              \advance\count\tw@\@nameuse{@UNDATAS@\the\@tempcnta}\relax%
              \ifnum\@tempcntb<\count\tw@ \@tempcntb\count\tw@ \fi%
          \fi%
        }%
        \expandafter\xdef\csname @UNDATAS@\the\count@\endcsname{\the\@tempcntb}%
    }%
  }

  \AtEndDocument{%
    \if@filesw%
        \write\@auxout{\string\checkundernotedata}%
        \let\checkundernotedata\relax%
        \def\undernotedata@internal{\@undernotedata}%
    \fi%
  }

  \endinput
\end{lstlisting}
\end{document}