%%
%% This is file `arcs2.sty'.
%%
%% Copyright 2026 John Souther
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3c
%% of this license or (at your option) any later version.
%% The latest version of this license is in
%%   https://www.latex-project.org/lppl.txt
%% and version 1.3c or later is part of all distributions of LaTeX
%% version 2008 or later.
%%
%% This work has the LPPL maintenance status `maintained'.
%%
%% The Current Maintainer of this work is John Souther.
%%
%% This work consists of the files listed in MANIFEST.
%%
%% Independent original implementation. It is not a modification of
%% the CTAN package `arcs' and does not contain that package's source.
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{arcs2}[2026/08/24 v1.0.3 Arcs over and under text (Souther)]

%% Color: load the kernel color package so \textcolor/\color work
%% and so picture strokes inherit the current color.
\RequirePackage{color}

%% Default letter count when the optional argument is omitted.
\newcommand{\arcsii@defaultN}{2}

%% Nominal arc rise (about 4pt) and gap between text and stroke.
\newdimen\arcsii@rise
\arcsii@rise=4pt\relax
\newdimen\arcsii@gap
\arcsii@gap=1pt\relax

\newdimen\arcsii@argwd
\newdimen\arcsii@arght
\newdimen\arcsii@argdp
\newdimen\arcsii@span
\newdimen\arcsii@half
\newdimen\arcsii@lift
\newbox\arcsii@argbox
\newif\ifarcsii@math
\newif\ifarcsii@over

%% Thicker stroke in bold text (series b/bx/bold) or bold math version.
\newcommand{\arcsii@rulewd}{0.4pt}
\newcommand{\arcsii@setrule}{%
  \renewcommand{\arcsii@rulewd}{0.4pt}%
  \def\arcsii@tmpa{bold}%
  \ifx\math@version\arcsii@tmpa
    \renewcommand{\arcsii@rulewd}{0.7pt}%
  \fi
  \def\arcsii@tmpa{b}%
  \def\arcsii@tmpb{bx}%
  \def\arcsii@tmpc{bold}%
  \ifx\f@series\arcsii@tmpa
    \renewcommand{\arcsii@rulewd}{0.7pt}%
  \fi
  \ifx\f@series\arcsii@tmpb
    \renewcommand{\arcsii@rulewd}{0.7pt}%
  \fi
  \ifx\f@series\arcsii@tmpc
    \renewcommand{\arcsii@rulewd}{0.7pt}%
  \fi
}

%% Typeset the argument: math if the *caller* was in math mode.
\newcommand{\arcsii@setarg}[1]{%
  \ifarcsii@math
    \setbox\arcsii@argbox=\hbox{$\m@th#1$}%
  \else
    \setbox\arcsii@argbox=\hbox{#1}%
  \fi
  \arcsii@argwd=\wd\arcsii@argbox
  \arcsii@arght=\ht\arcsii@argbox
  \arcsii@argdp=\dp\arcsii@argbox
  \ifdim\arcsii@arght=\z@
    \ifdim\arcsii@argdp=\z@
      \arcsii@arght=1ex\relax
    \fi
  \fi
}

%% Span = N times the width of a sample letter in the current font
%% (an ``x''). Default N=2 covers two letters, not the whole argument.
%% Math mode measures $x$ so the unit matches the formula font.
\newcommand{\arcsii@stdspan}[1]{%
  \ifarcsii@math
    \setbox\z@=\hbox{$\m@th x$}%
  \else
    \setbox\z@=\hbox{x}%
  \fi
  \ifdim\wd\z@>\z@
    \arcsii@span=\dimexpr \wd\z@ * #1 \relax
  \else
    \arcsii@span=#1em\relax
  \fi
}

%% Draw a quadratic Bezier of width \arcsii@span, height \arcsii@rise.
%% All x coordinates stay in [0,w] so the picture box matches the ink
%% (negative x was shifting the stroke left of the letters).
%% Over: nappe (peaks up). Under: cup (peaks down / curves up toward text).
\newcommand{\arcsii@drawarc}{%
  \begingroup
    \arcsii@setrule
    \linethickness{\arcsii@rulewd}%
    \setlength{\unitlength}{1pt}%
    %% Stroke follows current color (\textcolor{red}{\overarc{AB}} etc).
    \arcsii@half=0.5\arcsii@span
    \edef\arcsii@w{\strip@pt\arcsii@span}%
    \edef\arcsii@hw{\strip@pt\arcsii@half}%
    \edef\arcsii@h{\strip@pt\arcsii@rise}%
    \begin{picture}(\arcsii@w,\arcsii@h)%
      \ifarcsii@over
        \qbezier(0,0)(\arcsii@hw,\arcsii@h)(\arcsii@w,0)%
      \else
        \qbezier(0,\arcsii@h)(\arcsii@hw,0)(\arcsii@w,\arcsii@h)%
      \fi
    \end{picture}%
  \endgroup
}

%% #1 letter count, #2 argument, #3 1=over 0=under, #4 scale in thousandths.
\newcommand{\arcsii@place}[4]{%
  \relax
  \ifmmode\arcsii@mathtrue\else\arcsii@mathfalse\fi
  \ifnum#3>\z@\arcsii@overtrue\else\arcsii@overfalse\fi
  \leavevmode
  \hbox{%
    \arcsii@setarg{#2}%
    \arcsii@stdspan{#1}%
    \arcsii@span=\dimexpr \arcsii@span * #4 / 1000 \relax
    \ifdim\arcsii@span<4pt\relax
      \arcsii@span=4pt\relax
    \fi
    \ifarcsii@over
      \arcsii@lift=\dimexpr\arcsii@arght+\arcsii@gap\relax
    \else
      \arcsii@lift=\dimexpr -\arcsii@argdp-\arcsii@gap-\arcsii@rise\relax
    \fi
    %% Overlay a centered stroke on the argument.
    \setbox\z@=\hbox{\copy\arcsii@argbox}%
    \setbox\@ne=\hbox{\arcsii@drawarc}%
    \dimen@=\wd\z@
    \ifdim\wd\@ne>\dimen@
      \dimen@=\wd\@ne
    \fi
    \hbox{%
      \hbox to \dimen@{%
        \hss
        \raisebox{\arcsii@lift}[\z@][\z@]{\copy\@ne}%
        \hss
      }%
      \kern-\dimen@
      \hbox to \dimen@{\hss\copy\z@\hss}%
    }%
    \ifarcsii@over
      \vrule width\z@ height\dimexpr\arcsii@arght+\arcsii@gap+\arcsii@rise\relax
             depth\arcsii@argdp
    \else
      \vrule width\z@ height\arcsii@arght
             depth\dimexpr\arcsii@argdp+\arcsii@gap+\arcsii@rise\relax
    \fi
  }%
}

\newcommand{\overarc}[2][\arcsii@defaultN]{%
  \arcsii@place{#1}{#2}{1}{1000}%
}
\newcommand{\underarc}[2][\arcsii@defaultN]{%
  \arcsii@place{#1}{#2}{0}{1000}%
}
\newcommand{\wideoverarc}[2][\arcsii@defaultN]{%
  \arcsii@place{#1}{#2}{1}{1500}%
}
\newcommand{\wideunderarc}[2][\arcsii@defaultN]{%
  \arcsii@place{#1}{#2}{0}{1500}%
}

\endinput
%%
%% End of file `arcs2.sty'.
%%
