%%
%% firstindexletter.sty
%% A LaTeX package for emphasizing the first entry of each index letter group.
%%
%% This file is part of the firstindexletter package.
%% The functional code below is unchanged from the Hungarian-documented
%% development version; only comments have been converted to English.
%%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{firstindexletter}[2026/06/13 First item initial in each index group]

% The package is intended primarily for xindy/texindy-generated indexes.
\RequirePackage[xindy]{imakeidx}
\RequirePackage{xcolor}

\makeatletter

\newif\iffil@enabled
\fil@enabledfalse

\newif\iffil@separatedz
\fil@separatedzfalse

\newif\iffil@separatedzs
\fil@separatedzsfalse

\newif\iffil@indexgroupstart
\newif\iffil@pendingindexspace

\newcommand{\FirstIndexLetterEnable}{%
  \global\fil@enabledtrue
}

\newcommand{\FirstIndexLetterSeparateDz}{%
  \global\fil@separatedztrue
}

\newcommand{\FirstIndexLetterSeparateDzs}{%
  \global\fil@separatedztrue
  \global\fil@separatedzstrue
}

\providecommand\IndexInitialSize{\LARGE}
\providecommand\IndexInitialFamily{\fontfamily{cmr}\selectfont}
\providecommand\IndexInitialColor{black}

\providecommand\IndexKerningAscenders{hlbkdti}

\providecommand\IndexKerningGroupOneLetters{TY}
\providecommand\IndexKerningGroupOneValue{-1.2ex}
\providecommand\IndexKerningGroupOneAscenderValue{-0.2ex}

\providecommand\IndexKerningGroupTwoLetters{VW}
\providecommand\IndexKerningGroupTwoValue{-0.8ex}
\providecommand\IndexKerningGroupTwoAscenderValue{-0.1ex}

\providecommand\IndexKerningGroupThreeLetters{PF}
\providecommand\IndexKerningGroupThreeValue{-0.4ex}
\providecommand\IndexKerningGroupThreeAscenderValue{0ex}

\def\fil@initialkern#1#2{%
  \edef\fil@checkone{\noexpand\in@{#1}{\IndexKerningGroupOneLetters}}%
  \fil@checkone
  \ifin@
    \edef\fil@checkasc{\noexpand\in@{#2}{\IndexKerningAscenders}}%
    \fil@checkasc
    \ifin@
      \hspace{\IndexKerningGroupOneAscenderValue}%
    \else
      \hspace{\IndexKerningGroupOneValue}%
    \fi
  \else
    \edef\fil@checktwo{\noexpand\in@{#1}{\IndexKerningGroupTwoLetters}}%
    \fil@checktwo
    \ifin@
      \edef\fil@checkasc{\noexpand\in@{#2}{\IndexKerningAscenders}}%
      \fil@checkasc
      \ifin@
        \hspace{\IndexKerningGroupTwoAscenderValue}%
      \else
        \hspace{\IndexKerningGroupTwoValue}%
      \fi
    \else
      \edef\fil@checkthree{\noexpand\in@{#1}{\IndexKerningGroupThreeLetters}}%
      \fil@checkthree
      \ifin@
        \edef\fil@checkasc{\noexpand\in@{#2}{\IndexKerningAscenders}}%
        \fil@checkasc
        \ifin@
          \hspace{\IndexKerningGroupThreeAscenderValue}%
        \else
          \hspace{\IndexKerningGroupThreeValue}%
        \fi
      \fi
    \fi
  \fi
}

\def\fil@normalpair#1#2{%
  \leavevmode
  \hbox{%
    {\IndexInitialSize\IndexInitialFamily\color{\IndexInitialColor}#1}%
    \fil@initialkern{#1}{#2}%
    #2%
  }%
}

\def\fil@doublepair#1#2{%
  \leavevmode
  \hbox{%
    {\IndexInitialSize\IndexInitialFamily\color{\IndexInitialColor}#1#2}%
  }%
}

\def\fil@triplepair#1#2#3{%
  \leavevmode
  \hbox{%
    {\IndexInitialSize\IndexInitialFamily\color{\IndexInitialColor}#1#2#3}%
  }%
}

\def\fil@grabthirdforDzs#1#2{%
  \def\fil@currentthird{#1}%
  \def\fil@checks{s}%
  \ifx\fil@currentthird\fil@checks
    \iffil@separatedzs
      \fil@triplepair{D}{z}{s}#2%
    \else
      \iffil@separatedz
        \fil@doublepair{D}{z}#1#2%
      \else
        \fil@normalpair{D}{z}#1#2%
      \fi
    \fi
  \else
    \iffil@separatedz
      \fil@doublepair{D}{z}#1#2%
    \else
      \fil@normalpair{D}{z}#1#2%
    \fi
  \fi
}

\def\fil@grabfirst#1#2{%
  \def\fil@currentpair{#1#2}%
  \def\fil@checkdz{Dz}%
  \ifx\fil@currentpair\fil@checkdz
    \expandafter\fil@grabthirdforDzs
  \else
    \def\fil@checkcs{Cs}%
    \ifx\fil@currentpair\fil@checkcs
      \fil@doublepair{C}{s}%
    \else
      \def\fil@checksz{Sz}%
      \ifx\fil@currentpair\fil@checksz
        \fil@doublepair{S}{z}%
      \else
        \def\fil@checkzs{Zs}%
        \ifx\fil@currentpair\fil@checkzs
          \fil@doublepair{Z}{s}%
        \else
          \def\fil@checkgy{Gy}%
          \ifx\fil@currentpair\fil@checkgy
            \fil@doublepair{G}{y}%
          \else
            \def\fil@checkly{Ly}%
            \ifx\fil@currentpair\fil@checkly
              \fil@doublepair{L}{y}%
            \else
              \def\fil@checkny{Ny}%
              \ifx\fil@currentpair\fil@checkny
                \fil@doublepair{N}{y}%
              \else
                \def\fil@checkty{Ty}%
                \ifx\fil@currentpair\fil@checkty
                  \fil@doublepair{T}{y}%
                \else
                  \fil@normalpair{#1}{#2}%
                \fi
              \fi
            \fi
          \fi
        \fi
      \fi
    \fi
  \fi
}

% Convert the raw lettergroup name into an effective, invisible group name.
% For Dz/Dzs this decides whether a block starts separately, or is merged
% into the D or Dz effective group.

\def\fil@makeeffectivegroup#1{%
  \def\fil@rawgroup{#1}%
  \def\fil@checkD{D}%
  \def\fil@checkDz{Dz}%
  \def\fil@checkDzs{Dzs}%
  \ifx\fil@rawgroup\fil@checkDzs
    \iffil@separatedzs
      \def\fil@effectivegroup{Dzs}%
    \else
      \iffil@separatedz
        \def\fil@effectivegroup{Dz}%
      \else
        \def\fil@effectivegroup{D}%
      \fi
    \fi
  \else
    \ifx\fil@rawgroup\fil@checkDz
      \iffil@separatedz
        \def\fil@effectivegroup{Dz}%
      \else
        \def\fil@effectivegroup{D}%
      \fi
    \else
      \def\fil@effectivegroup{#1}%
    \fi
  \fi
}

\def\fil@emptygroup{}

\def\fil@handlelettergroup#1{%
  \fil@makeeffectivegroup{#1}%
  \ifx\fil@currenteffectivegroup\fil@emptygroup
    \let\fil@currenteffectivegroup\fil@effectivegroup
    \global\fil@indexgroupstarttrue
    \global\fil@pendingindexspacefalse
  \else
    \ifx\fil@currenteffectivegroup\fil@effectivegroup
      \global\fil@indexgroupstartfalse
      \global\fil@pendingindexspacefalse
    \else
      \iffil@pendingindexspace
        \fil@oldindexspace
      \fi
      \let\fil@currenteffectivegroup\fil@effectivegroup
      \global\fil@indexgroupstarttrue
      \global\fil@pendingindexspacefalse
    \fi
  \fi
}

\let\fil@oldtheindex\theindex

\renewcommand\theindex{%
  \fil@oldtheindex
  \iffil@enabled

    \def\fil@currenteffectivegroup{}%

    \let\fil@oldindexspace\indexspace
    \def\indexspace{%
      \global\fil@pendingindexspacetrue
    }%

    \def\lettergroup##1{%
      \fil@handlelettergroup{##1}%
    }%

    \let\fil@olditem\item
    \def\item{%
      \fil@olditem
      \iffil@indexgroupstart
        \global\fil@indexgroupstartfalse
        \expandafter\fil@grabfirst
      \fi
    }%

  \fi
}

\makeatother
\endinput
