# Cyrillic letters in command names with PDFLaTeX

I would like to know an efficient way to use Cyrillic characters in command names (macro names) with PDFLaTeX (XeLaTeX being unavailable).

I discovered that I can define commands with Cyrillic letters in their names if I keep the source in Windows-1251 8-bit character encoding as so:

\documentclass{article}

\usepackage[T2A]{fontenc}
\usepackage[cp1251]{inputenc}
\usepackage[russian]{babel}

\catcode\л=11\relax
\catcode\п=11\relax
\catcode\к=11\relax

\newcommand{\лк}{«}
\newcommand{\пк}{»}

\begin{document}
\лк Золотой век\пк\ распространения славянской письменности относится ко времени царствования в Болгарии царя Симеона Великого.
\end{document}


My first question is: how "robust" is this solution?

Also, I would like to know how to set the category code to 11 for all Cyrillic letters, without doing it one by one.

Update: I have discovered that if I use hyperref package with this solution and create sections in the document, the generated PDF document outline will have wrong characters in the place of letters for which I set the catcode 11. I would like to know what could be done about this.

Update 2: I've found that there is an "unofficial" package russlh that uses exactly this approach, but its latest update was apparently in 2003, and it does not seem to work with recent versions of hyperref.

My second question is: can I have Cyrillic commands if I use UTF-8 for the source?

Simply reencoding the example file and using utf8 instead of cp1251 did not work:

! Missing number, treated as zero.
\protect
l.7 \catcode\л
=11\relax


There is a related question about Command names with utf-8/special characters, but I did not quite understand this part of the unswer:

With pdfTeX the \√ syntax will not work because of the way pdfTeX handles input (it is theoretically possible to achieve this, though).

• Imho it is not possible. At least not if you want to use the chars also for normal words. The bytes of a char like л can't have at the same time catcode "letter" (for commands) and "active" (for the inputenc processing). Why is xelatex or lualatex not available? – Ulrike Fischer Jul 6 '18 at 15:49
• cp1251 is an 8 bit encoding, so you can do the trick with \catcode(but lose the possibility to use the characters in text); it's not possible with UTF-8. – egreg Jul 6 '18 at 16:05
• @UlrikeFischer, it is for arXiv. – Alexey Jul 6 '18 at 16:09
• @egreg, my example with cp1251 compiled fine, i didn't loose the possibility to use the characters in text. However, when i tried to add hyperref package (with or without unicode option), the letters for which i manually set catcode got misrepresented in the document's outline created by hyperref. – Alexey Jul 6 '18 at 16:14
• @Alexey The layout of T2A encoded fonts somewhat hides the problem. – egreg Jul 6 '18 at 16:46

With multibyte encodings such as UTF-8, what you want to do is basically impossible (or can be implemented in a very fragile way).

It seems to work with 8 bit encodings such as Windows-1251, but a simple example will show what can go wrong:

\documentclass{article}

\usepackage[T2A]{fontenc}
\usepackage[cp1251]{inputenc}
\usepackage[russian]{babel}

\catcode\ё=11\relax

\begin{document}

ё

\end{document}


(this should be saved in Windows-1251 encoding). If I run it the output is

The reason is simple: in the Windows-1251 (cp1251 in LaTeX lingo), the character ё is encoded as 0xB8, but T2A encoded fonts have ҷ in that position (see the table below). By setting the catcode of byte 0xB8 to 11, TeX will interpret it as “print the glyph in position 0xB8 in the current font”.

The job of inputenc is indeed to make byte 0xB8 active with expansion \char"BC (the slot where the ё character lives in T2A encoded fonts).

• Virtual fonts could perform the mapping from input encoding to output encoding slots. But they need to be created for all used fonts. If the input encoding is UTF-8 (multi-byte), then the ligature mechanism can help. – Heiko Oberdiek Jul 6 '18 at 18:06
• @HeikoOberdiek With obvious problems for the hyphenation patterns. – egreg Jul 6 '18 at 18:10
• An adapted version of the hyphenation patterns could also be created, but the way remains cumbersome, not very portable, and therefore not recommended for 8-bit TeX engines. – Heiko Oberdiek Jul 6 '18 at 18:15
• Thanks for the explanation. It seems that without using ё character in commands, a working solution could be to change the catcode of all characters except ё. Unfortunately, this still leaves me with the problem of misencoded contents outline produced by hyperref. – Alexey Jul 6 '18 at 18:45
• @Alexey The bookmark code has to map the characters to UTF16-BE (option unicode or pdfencoding=auto is required, because the other bookmark encoding of the PDF format is 8-bit and does not contain Cyrillic letters). A special font encoding is used to map LICRs (LaTeX internal character representation) to the bookmark. The characters outside ASCII are active. Thus, they can be redefined as macros to LICRs. Since letters with category codes 11 or 12 cannot be redefined at macro level, yu have to use macros \CYRa, \CYRb, ... to get correct bookmarks (see also \texorpdfstring). – Heiko Oberdiek Jul 7 '18 at 6:15

As an alternative I would suggest to define one command (with an ascii name) which takes the cyrillic as argument and builds a command name with \detokenize:

\documentclass{article}
\usepackage[T2A]{fontenc}
\usepackage[russian]{babel}

\newcommand\cyrcmd[1]{\csname cyrcmd\detokenize{#1}\endcsname}
\makeatletter
\@namedef{cyrcmd\detokenize{лк}}{«}
\@namedef{cyrcmd\detokenize{пк}}{»}
%% more commands
\makeatother
\usepackage{hyperref}
\begin{document}
\tableofcontents
\section{\cyrcmd{лк}Золотой век\cyrcmd{пк}}
\cyrcmd{лк}Золотой век\cyrcmd{пк} распространения славянской письменности относится ко времени царствования в Болгарии царя Симеона Великого.
\end{document}
`