It looks like \alph
(or rather, \@alph
) is redefined to use the macro \@hebrew@numeral
, which produces these numbers.
I'm redefining it to first look up if a number is bad and print something different if this is the case. The output will be unchanged otherwise.
Bad numbers are declared using \newbadnum{<number>}{<good representation>}
, which I also define below.
Note: Like the original, this is a XeLaTeX document.
\documentclass{book}
\usepackage{polyglossia}
\setdefaultlanguage{hebrew}
\setotherlanguage{english}
\usepackage{fontspec}
\newfontfamily\hebrewfont{Times New Roman}[Script=Hebrew]
\makeatletter %% <- make @ usable in command names
\let\@hebrew@numeral@bad\@hebrew@numeral %% <- store old definition
\newcommand*\@hebrew@numeral@good[1]{% %% <- new definition
\ifcsdef{badnum@\number#1} %% <- if this number is bad
{\csuse{badnum@\number#1}} %% <- replace it
{\@hebrew@numeral@bad{#1}}% %% <- otherwise use old definition
}
\let\@hebrew@numeral\@hebrew@numeral@good %% <- replace old definition
\makeatother %% <- revert @
%% Declare bad numbers:
\newcommand*\newbadnum[2]{\csdef{badnum@#1}{#2}}
\newbadnum{270}{ער} %% <- literally bad
\newbadnum{271}{אאאא} %% <- for demonstration purposes
\newbadnum{272}{בבבב} %% <- for demonstration purposes
\newbadnum{274}{:-)} %% <- I wonder if this will smile in reverse
\pagenumbering{alph}
\begin{document}
\setcounter{page}{270}
\textenglish{The page number is now correct: $\uparrow\uparrow$}
\begin{enumerate}
\item \textenglish{Also second level enumerations use these:}
\begin{enumerate}\setcounter{enumii}{268}
\item \textenglish{This is item \#\arabic{enumii}}
\item \textenglish{This is item \#\arabic{enumii}}
\item \textenglish{This is item \#\arabic{enumii}}
\item \textenglish{This is item \#\arabic{enumii}}
\item \textenglish{This is item \#\arabic{enumii}}
\item \textenglish{This is item \#\arabic{enumii}} %% <- Still smiling :-)
\end{enumerate}
\end{enumerate}
\end{document}

This also changes the behaviour of \hebrewnumeral
, \Hebrewnumeral
and \Hebrewnumeralfinal
, which may not be desirable. (See the addendum below for how to avoid this.)
Here's a brief explanation of what a couple of the above lines do:
\newbadnum{270}{ער}
calls \csdef{badnum@270}{ער}
, which defines the macro \badnum@270
to expand to ער
.
You can't call \badnum@270
directly because it contains an @
and digits. However, \csuse{badnum@270}
does expand to ער
if it was defined as above.
If you were to call \@hebrew@numeral@good{\somectr}
and \somectr
is a TeX counter (not a LaTeX counter) with value 270
, it will effectively run \ifcsdef{badnum@270}{<true branch>}{<false branch>}
.
This tests if \badnum@270
is defined and chooses the appropriate branch.
The true branch is simply \csuse{badnum@\number#1}
, so it'd expand to ער
as described above.
The false branch just calls the original \@hebrew@numeral
with the same argument.
The commands \csuse
, \ifcsdef
and \csdef
are all from the etoolbox
package, which was already loaded by polyglossia
.
If there are a lot of bad numbers, you can replace the "Declare bad numbers" block by something like
%% Declare bad numbers:
\makeatletter %% <- make @ usable in command names
\newcommand*\newbadnum[2]{\csdef{badnum@#1}{#2}}
\newcommand*\newbadnums[1]{\forcsvlist\newbadnum@{#1}}
\def\newbadnum@#1{\newbadnum@@#1\newbadnum@@}
\def\newbadnum@@#1=#2\newbadnum@@{\newbadnum{#1}{#2}}
\makeatother %% <- revert @
\newbadnums{{270}={ער},{271}={אאאא},{272}={בבבב},
{274}={:-)}}
Edit: Interesting, the last line above looks fine in my editor, but it appears rather messed up here.
It'll work if you copy-paste it, but I can't guarantee that it'll be human-readable. (The combination of left-to-right and right-to-left text in a single document is supremely confusing.)
Note that the =
s are not allowed to be surrounded by spaces and that the ,
s are not allowed to be preceded by spaces, but are allowed to be followed by spaces and/or a single newline. The braces ({…}
) are entirely optional, but without them the combination of left-to-right and right-to-left text just confuses the hell out of both my text editor and this website (and me):
\newbadnums{270=ער,271=אאאא,272=בבבב,274=:-)}
(That's the same as the last two lines above, just without the {…}
and the line break.)
Addendum
Here's a version that lets you specify separately what the \Hebrewnumeral
numbers (used by \Alph
) and the \Hebrewnumeralfinal
numbers (not used?) look like. The syntax is
\newbadnum{<number>}{<hebrew>}{<Hebrew>}[<Hebrewfinal>]
where <number>
is a number in arabic numerals and the other three arguments are the three relevant representations.
The same value is used for <Hebrew>
and <Hebrewfinal>
if the optional argument is left out because it appears that these two representations usually coincide.
I must say that attempting post code fragments that contain Hebrew here is nightmare. The bottom four lines below appear rather mangled in my browser, but they're fine when I copy them to a text editor.
%% Declare bad numbers:
\makeatletter %% <- make @ usable in command names
\newcommand*\newbadnum[3]{\@testopt{\newbadnumopt{#1}{#2}{#3}}{#3}}
\def\newbadnumopt#1#2#3[#4]{%
\csdef{badnum@#1}{%
\if@gim@apost
\if@gim@final #4\else #3\fi
\else
#2%
\fi
}%
}
\makeatother %% <- revert @
%% The following looks fine in my editor, but not here.
\newbadnum{270}{ער}{ר״ע} %% <- leave \Hebrew unchanged
\newbadnum{271}{אאאא}{אאאא}[רע״א] %% <- leave only \Hebrewfinal version unchanged
\newbadnum{274}{:-)}{:-D}[:-P] %% <- In a good mood
\newbadnum{50}{נ}{נ׳}[ן׳] %% <- The default
If you use numbers greater than (or equal to) 1000 some further modification may (or may not?) be required because \@hebrew@numeral
is actually recursive for those. I don't know if these replacements should also be applied to parts of numbers.
\Hebrewnumeral
or\Hebrewnumeralfinal
?