% Unipersian: Persian language support for LaTeX.
%
% Copyright (C) 2026 Amer Amikhteh
%
% This package is free software: you may redistribute it and/or modify
% it under the terms of the LaTeX Project Public License as published
% by the LaTeX Project, either version 1.3c of the License, or
% (at your option) any later version.
%
% This package is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% The full license text is available at:
% https://www.latex-project.org/lppl/
%
% This work is "maintained" by Amer Amikhteh.
%
% The current maintainer of this work is Amer Amikhteh.
%
% This package consists of the file unipersian.sty and the files
% distributed with it.



\NeedsTeXFormat{LaTeX2e}

\def\uper@year{2026}
\def\uper@month{09}
\def\uper@day{08}
\def\uper@date{%
  \uper@year/\uper@month/\uper@day
}
\def\uper@version{0.1.0}

\ProvidesPackage{unipersian}
[\uper@date v\uper@version Persian support for pdfTeX, XeTeX, and LuaTeX]


\RequirePackage{iftex}
\RequirePackage{xparse}
\RequirePackage{xkeyval}

\makeatletter

\@ifpackageloaded{listings}{%
  \RequirePackage{unipersian-listings}%
}{}



% ------------------------------------------
% Package options
% ------------------------------------------

\define@key{persian}{bidi}{%
  \gdef\uper@bidi{#1}%
}

\define@key{persian}{layout}{%
  \edef\uper@layout{%
    \uper@layout\space#1%
  }%
}

\def\uper@layout{}

\ifPDFTeX
  \setkeys{persian}{bidi=default}
\fi

\ifXeTeX
  \setkeys{persian}{bidi=bidi-r}
\fi

\ifLuaTeX
  \setkeys{persian}{%
    bidi=basic,
    layout=counters tabular graphics footnotes
  }
\fi

\DeclareOptionX{bidi}{%
  \setkeys{persian}{bidi=#1}%
}

\DeclareOptionX{layout}{%
  \setkeys{persian}{layout=#1}%
}

\DeclareOptionX*{%
  \edef\uper@babeloptions{%
    \uper@babeloptions,\CurrentOption
  }%
}

\def\uper@babeloptions{}

\ProcessOptionsX\relax

% ------------------------------------------
% beamer conditionals
% ------------------------------------------

\newif\ifuper@beamer
\newif\ifuper@beamerrl
\@ifclassloaded{beamer}{\uper@beamertrue}{}
\@ifclassloaded{beamer-rl}{\uper@beamerrltrue}{}


% ------------------------------------------
% Resolve Bug of arabiccore Package
% ------------------------------------------

\@ifundefined{if@rl}{%
  \newif\if@rl
}{}

\ifPDFTeX
  \ifuper@beamer
    \providecommand{\labelitemiv}
    {\if@rl\protect $-$ %
      \else\protect\textperiodcentred\fi}
    \providecommand{\labelitemi}
    {\if@rl\protect\textLR{$\bullet$}
      \else\protect\textbullet\fi}

    \providecommand{\labelitemii}
    {\if@rl\protect\textLR{$\circ$} %
      \else\protect\textLR{ \normalfont\bfseries\textendash}\fi}

    \providecommand{\labelitemiii}
    {\if@rl\protect\textLR{$*$} %
      \else\protect\textasteriskcentered\fi}

    \providecommand{\labelenumi}
    {\if@rl(\I{\number\c@enumi}).%
      \else{\number\c@enumi}.\fi}

    \providecommand{\labelenumii}
    {\if@rl\abjadnumeral{\number\c@enumii}. %
      \else({\number\c@enumii})\fi}

    \providecommand{\labelenumiii}
    {\if@rl\I{\number\c@enumiii}$\space-\space$ %
      \else({\number\c@enumiii})\fi}

    \providecommand{\labelenumiv}
    {\if@rl\abjadnumeral{\number\c@enumiv}$\space-\space$ %
      \else({\number\c@enumiv})\fi}
  \fi \fi

% ------------------------------------------
% Engine setup
% ------------------------------------------

\ifPDFTeX
  \RequirePackage[utf8]{inputenc}
  \RequirePackage[LAE,LFE,T1]{fontenc}
  \RequirePackage[bidi=\uper@bidi,\uper@babeloptions,english,farsi]{babel}
\fi

\ifXeTeX
  \RequirePackage[
    bidi=\uper@bidi,
    \uper@babeloptions
  ]{babel}

  \babelprovide[import,main]{persian}
  \babelprovide[import]{english}
\fi

\ifLuaTeX

  \RequirePackage{fontspec}

  \ifuper@beamerrl

  \else
    \RequirePackage[
      bidi=\uper@bidi,
      layout=\uper@layout,
      \uper@babeloptions
    ]{babel}

  \fi

  \babelprovide[import,main,mapdigits]{persian}
  \babelprovide[import]{english}

\fi


% ------------------------------------------
% Load package components
% ------------------------------------------
\input{unipersian-numerals.def}
\input{unipersian-book.def}
\input{unipersian-captions.def}

\makeatletter
\ifPDFTeX \g@addto@macro\captionsfarsi{\uper@captions}\fi
\ifTUTeX \g@addto@macro\captionspersian{\uper@captions} \fi
\makeatother
\ifTUTeX \input{unipersian-fonts.def} \fi
\ifPDFTeX \input{unipersian-pdftex.def} \fi
\ifXeTeX
  \input{unipersian-xetex.def}
\fi
\ifLuaTeX \input{unipersian-luatex.def} \fi


% ------------------------------------------
% Beamer beamerbasebox from beamer-rl class
% ------------------------------------------

\makeatletter
\ifuper@beamer
  \ifuper@beamerrl
  \else
    \ifLuaTeX \input{unipersian-beamer-luatex.def} \fi
  \fi
\fi
\makeatother



\makeatletter

% ------------------------------------------------
% Label-safe sanitization of Babel bidi wrappers
% ------------------------------------------------

\long\def\uper@firstofone#1{#1}

\def\uper@strip@babel@bidi{%
  \@ifundefined{babelsublr}{}{%
    \let\babelsublr\uper@firstofone
  }%
  \@ifundefined{babelsubrl}{}{%
    \let\babelsubrl\uper@firstofone
  }%
}

\newif\ifuper@label@patched

\def\uper@patch@label{%
  \ifuper@label@patched
  \else
    \global\uper@label@patchedtrue
    \let\uper@orig@label\label
    \protected\def\label##1{%
      \begingroup
      \uper@strip@babel@bidi
      \edef\uper@tmp{##1}%
      \expandafter\endgroup
      \expandafter\uper@orig@label\expandafter{\uper@tmp}%
    }%
  \fi
}

\AddToHook{begindocument/end}{%
  \uper@patch@label
}



% ------------------------------------------
% Hyperref fallbacks
% ------------------------------------------

\AtBeginDocument{%
  \@ifpackageloaded{hyperref}{%
    \pdfstringdefDisableCommands{%
      \def\harfi#1{}%
      \def\adadi#1{}%
      \def\tartibi#1{}%
      \def\abjad#1{}%
      \def\Abjad#1{}%
      \def\@harfi#1{}%
      \def\@adadi#1{}%
      \def\@tartibi#1{}%
      \def\@abjad#1{}%
      \def\@Abjad#1{}%
      \def\lr#1{#1}%
      \def\rl#1{#1}%
      \def\LR#1{#1}%
      \def\RL#1{#1}%
    }%
  }{}%
}


% ------------------------------------------
% Bidi commands
% ------------------------------------------

\providecommand{\if@RTL}{\ifnum\bbl@thetextdir>\z@}
\providecommand{\@RTLtrue}{\chardef\bbl@thetextdir\@ne}
\providecommand{\@RTLfalse}{\chardef\bbl@thetextdir\z@}


\providecommand{\RLE}[1]{%
  \leavevmode
  {%
    \bbl@textdir{1}%
    #1%
  }%
}%

\providecommand{\LRE}[1]{%
  \leavevmode
  {%
    \bbl@textdir{0}%
    #1%
  }%
}%

\ProvideDocumentEnvironment{RTL}{}
{%
  \par
  \begingroup
  \bbl@pardir{1}%
  \bbl@textdir{1}%
}
{%
  \par
  \endgroup
}%


\ProvideDocumentEnvironment{LTR}{}
{%
  \par
  \begingroup
  \bbl@pardir{0}%
  \bbl@textdir{0}%
}
{%
  \par
  \endgroup
}%

\let\LR\LRE
\let\RL\RLE

% ------------------------------------------
% Inline language commands
% ------------------------------------------

\ProvideDocumentCommand{\lr}{m}{%
  \mbox{\unskip
    \@ifundefined{LatinAlphs}{}{\LatinAlphs}%
    \ifx\languagename\englishlanguage
      #1%
    \else
      \foreignlanguage[captions]{english}{#1}%
    \fi
  }\unskip
}

\ProvideDocumentCommand{\rl}{m}{%
  \mbox{\unskip
    \@ifundefined{PersianAlphs}{}{\PersianAlphs}%
    \ifx\languagename\persianmainlanguage
      #1%
    \else
      \foreignlanguage[captions]{\persianmainlanguage}{#1}%
    \fi
  }\unskip
}


% ------------------------------------------
% Language environments
% ------------------------------------------

\ProvideDocumentEnvironment{latin}{}%
{%
  \begin{LTR}
  \begin{otherlanguage*}[captions]{english}%
  \@ifundefined{LatinAlphs}{}{%
    \LatinAlphs
  }%
}%
{%
  \end{otherlanguage*}%
  \end{LTR}
}%

\ProvideDocumentEnvironment{persian}{}%
{%
  \begin{RTL}
  \begin{otherlanguage*}[captions]{\persianmainlanguage}%
  \@ifundefined{PersianAlphs}{}{%
    \PersianAlphs
  }%
}%
{%
  \end{otherlanguage*}%
  \end{RTL}
}%

% ------------------------------------------
% Latin font reset
% ------------------------------------------

\ProvideDocumentCommand{\resetlatinfont}{}{%
  \selectlanguage{english}%
}

% ------------------------------------------
% Date helpers
% ------------------------------------------

\DeclareRobustCommand{\latintoday}{%
  \foreignlanguage[date]{english}{\today}%
}


% ------------------------------------------------
% Verbatim
% ------------------------------------------------

\def\verbatim@font{%
  \normalfont
  \ifTUTeX \latinttfamily \else  \ttfamily\fontencoding{T1}\selectfont\fi
  \bbl@pardir{0}%
  \bbl@textdir{0}%
  \ifLuaTeX\else\beginL\fi
}

\AddToHook{env/verbatim/after}{%
  \vspace{-\baselineskip}\ifXeTeX\endL\vspace{-\baselineskip}\fi
}

\g@addto@macro\verb@egroup{\ifLuaTeX\else\endL\fi}


% ------------------------------------------------
% Linstings Package
% ------------------------------------------------

\@ifpackageloaded{listings}{%
  \lst@AddToHook{Init}{%
    \lst@ifdisplaystyle
    \selectlanguage{english}
    \else
    \ifXeTeX\unskip\fi
    \begin{otherlanguage*}{english}
    \ifXeTeX\beginL\fi
    \unskip
    \fi
  }
  \lst@AddToHook{DeInit}{%
    \lst@ifdisplaystyle
    \else
    \end{otherlanguage*}
    \ifXeTeX \endL  \fi
    \unskip
    \fi
  }
}{}

\makeatother


\endinput
