[This is essentially an extended comment because while I have once researched the options listed here, I haven’t actually implemented any of them.]
I believe you can’t do this with inputenc
and a conventional TeX engine.
Latin letters are special for TeX because they essentially have to be encoded in ASCII for TeX to work (there’s a segment in the TeX source that literally translates ASCII symbols from the host encoding to ASCII after reading them in case TeX is to run on an EBCDIC system or something like that, because TeX primitives that expect keywords like pt
or plus
or to
compare them with literal ASCII codes, categories be damned), and all TeX fonts place Latin letters at glyph numbers equal to their ASCII codepoints. This works because TeX treats a “letter” (category code 11) character with internal TeX codepoint n (on a modern ASCII-compatible system, this usually means host codepoint n) encountered within a paragraph as an instruction to output glyph number n from the current text font. This means that the internal TeX codepoints (the “input encoding”) and glyph numbers in the current font (the “font encoding”) must match. This also means that there can never be more than 28 = 256 characters in a single TeX font.
The usual LaTeX way of solving this is a bit of a hacky workaround. First, every non-ASCII codepoint is declared to be “active” (category code 13), that is, when TeX sees character n with n > 128, it’s instructed to treat it as a single-character macro (the same way it produces a non-breakable space when it encounters ~
: there’s a pair of lines in latex.ltx
that says \catcode`\~=13 \def~{\nobreakspace{}}
); this is done by \inputencoding
and \@inpenc@loop
in inputenc.sty
. Second, when an input encoding is set (when inputenc
is being loaded), those macros are defined to expand to other macros with well-known names by calling \DeclareInputText
from inputenc.sty
(e. g. in a Windows-1251 document, character 168, CYRILLIC CAPITAL LETTER IO, is defined to expand to \CYRYO
by cp1251.def
). (The expansion is actually \IeC{\CYRA}
, but that is not important here.) These well-known macro names constitute the LaTeX internal character representation (LICR). Third, when a font encoding is set (when babel
is being loaded or is instructed to switch languages, or when you change \fontencoding
explicitly), the LICR commands for characters that are present in that encoding are defined to emit the corresponding glyphs in the current font by calling \DeclareTextSymbol
from latex.ltx
(e. g. in a T2A font, \CYRYO
is defined to emit character 156 by t2aenc.def
). (The actual setup is more complicated, but that is again not important here, consult the ltoutenc.dtx
section in source2e for details.)
Multibyte encodings such as UTF-8 are even more complicated because the leading bytes of the encoding are defined to consume the requisite number of tokens from the input stream as undelimited macro arguments, then look up and emit the corresponding LICR code. That’s why you get so many fun errors when you forget to delimit your single UTF-8-encoded Cyrillic letter passed as an undelimited argument to a macro (e. g. *\textit ы
fails while \textit g
works): the Cyrillic letter is not a single TeX token, and furthermore the first token that was passed to the command ate some arbitrary part of the command’s code in an attempt to fetch the trailing bytes.
To be able to use multiple Cyrillic letters in TeX commands, they need to get translated to internal TeX codepoints that declared to be “letters” (category code 11); that’s how the TeX scanner handles the backslash character (or really any “escape”, category code 0, character). So I see several approaches to accomplish what you want, and all of them are rather flaky:
- Use a single-byte encoding like Windows-1251, IBM 866 or (historically most popular) KOI8-R; avoid
inputenc
and instead define them to be letters; use a font that’s already in the requisite encoding (none on a modern LaTeX installation AFAIK) or assemble an incompatible font’s characters in the necessary order by defining a virtual font and a font encoding;
- Use a single-byte encoding or UTF-8; avoid
inputenc
and instead use the (apparently obscure) encTeX extension by regenerating the LaTeX format while passing the -enc
option to initex
; explain your desired input encoding to encTeX, which will tweak the TeX kernel’s input translation mechanism accordingly, and define the result of that translation to be letters; then hack the LaTeX kernel to recognize the result of that translation;
- Use UTF-8 (exclusively); avoid
inputenc
and instead use a TeX engine that is hardwired to use UTF-8 such as XeTeX or LuaTeX; hacking the LaTeX kernel will again be probably required, but I don’t know much of anything about these engines.
If that sounds hazy, that’s because it is. I don’t know how to do this in detail, and unless you have literal hundreds of pages of old TeX documents or need to stay compatible with truly ancient TeX installations, porting your documents (possibly programmatically using a good-enough parser like plasTeX or even a good ol’ pile of regular expressions) is probably easier.
л
can't have at the same time catcode "letter" (for commands) and "active" (for the inputenc processing). Why is xelatex or lualatex not available?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.cp1251
compiled fine, i didn't loose the possibility to use the characters in text. However, when i tried to addhyperref
package (with or withoutunicode
option), the letters for which i manually set catcode got misrepresented in the document's outline created byhyperref
.babel
) Russian support packages for LaTeX that use the same input and font encoding (usually KOI8-R), set Cyrillic letters to catcode 11, and use commands like\лк
(from левая кавычка “left quotation mark”) for « (in modern documents the problem of inputting this character is instead solved by having a ligature for<<
). I suspect the OP is trying to wrangle one of these ancient documents.