Compound representation of numbers. Possible?

I’ve got a Glagolitic font (Epistula Croatica) with letters mapped to numbers and some ligatures programmed. I don’t want to describe the nature of the Glagolitic numeral system here but to present what I’d like to achieve (the font’s licence doesn’t allow me to modify it). I’m trying to find a solution that will allow me to use custom numerical system in page numbers, the enumerate environment and in text.

What I need is just a different representation of arabic numerals, as in the examples below:

• 1 through 9 — no change
• 11 — 10 1
• 19 — 10 9
• 25 — 20 5
• 347 — 300 40 7
• 901 — 900 1
• 50681 — 50000 600 80 1 etc.

Between the numbers I’d like to have a \textcompwordmark.

I’d really appreciate any answers for the following questions:

• Is it possible to define such a numerical system with way of using as roman, arabic, alph, fnsymbol? I use LuaLaTeX so the solution can be a Lua code.
• If yes, how to use it in page numbers or the enumerate environment?
• Is it possible to have a text-mode command similar to \mynumerals{123}?

-
Maybe you can port the code from the Cyrillic Numerals Module for ConTEXt. The system is pretty close, in fact afair Glagolitic numerals are a bit less complex due to the numerical values being assigned to letters in plain alphabetical order. The converter is written in Lua and does not rely on ConTEXt specific features. –  phg May 12 '12 at 14:54
I will try it. The only problem is that my font contains appropriate characters neither in the Glagolitic, nor in the Cyrillic block. –  Artur S. May 12 '12 at 15:04
If you have a Glagolitic font containing the letters, you have everything you need to represent the numbers as well. The font might lack the titlo glyph (U+0483), though. Should you require it you might want to look at the metapost code that the module provides to draw titla above numbers, but I’m not sure how to achieve the same without metafun. –  phg May 12 '12 at 15:18

Here's an implementation using expl3

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\glagonumeral}{m}{\glago_numeral:n { \int_eval:n { #1 } } }

\seq_new:N \l_glago_digits_seq
\int_new:N \l_glago_position_int

\cs_new_protected:Npn \glago_numeral:n #1
{
\cs_set:Npn \glago_reverse_ten: { }
\seq_set_split:Nnx \l_glago_digits_seq { } { #1 }
\int_set:Nn \l_glago_position_int {\seq_length:N \l_glago_digits_seq - 1 }
\seq_map_inline:Nn \l_glago_digits_seq
{
\glago_symbol:x { \glago_make_digit:nn { ##1 } { \l_glago_position_int } }
\int_decr:N \l_glago_position_int
}
\glago_reverse_ten:
}
\cs_generate_variant:Nn \seq_set_split:Nnn {Nnx}
\cs_new:Npn \glago_make_digit:nn #1 #2
{
#1 \prg_replicate:nn { \l_glago_position_int } { 0 }
}
\cs_new:Npn \glago_symbol:n #1
{
\int_compare:nTF { #1 == 10 }
{
\cs_set:Npx \glago_reverse_ten: { \prop_get:Nn \g_glago_numerals_prop { #1 } }
}
{
\prop_get:Nn \g_glago_numerals_prop { #1 }
}
}
\cs_generate_variant:Nn \glago_symbol:n {x}

\prop_new:N \g_glago_numerals_prop
\prop_put:Nnn \g_glago_numerals_prop {0}{\textcompwordmark}
\prop_put:Nnn \g_glago_numerals_prop {1}{A}
\prop_put:Nnn \g_glago_numerals_prop {2}{B}
\prop_put:Nnn \g_glago_numerals_prop {3}{C}
\prop_put:Nnn \g_glago_numerals_prop {4}{D}
\prop_put:Nnn \g_glago_numerals_prop {5}{E}
\prop_put:Nnn \g_glago_numerals_prop {6}{F}
\prop_put:Nnn \g_glago_numerals_prop {7}{G}
\prop_put:Nnn \g_glago_numerals_prop {8}{H}
\prop_put:Nnn \g_glago_numerals_prop {9}{I}
\prop_put:Nnn \g_glago_numerals_prop {00}{\textcompwordmark}
\prop_put:Nnn \g_glago_numerals_prop {10}{J}
\prop_put:Nnn \g_glago_numerals_prop {20}{K}
\prop_put:Nnn \g_glago_numerals_prop {30}{L}
\prop_put:Nnn \g_glago_numerals_prop {40}{M}
\prop_put:Nnn \g_glago_numerals_prop {50}{N}
\prop_put:Nnn \g_glago_numerals_prop {60}{O}
\prop_put:Nnn \g_glago_numerals_prop {70}{P}
\prop_put:Nnn \g_glago_numerals_prop {80}{Q}
\prop_put:Nnn \g_glago_numerals_prop {90}{R}
\prop_put:Nnn \g_glago_numerals_prop {000}{\textcompwordmark}
\prop_put:Nnn \g_glago_numerals_prop {100}{S}
\prop_put:Nnn \g_glago_numerals_prop {200}{T}
\prop_put:Nnn \g_glago_numerals_prop {300}{U}
\prop_put:Nnn \g_glago_numerals_prop {400}{V}
\prop_put:Nnn \g_glago_numerals_prop {500}{W}
\prop_put:Nnn \g_glago_numerals_prop {600}{X}
\prop_put:Nnn \g_glago_numerals_prop {700}{Y}
\prop_put:Nnn \g_glago_numerals_prop {800}{Z}
\prop_put:Nnn \g_glago_numerals_prop {900}{@}

\ExplSyntaxOff

\newcommand{\glagovalue}[1]{\glagonumeral{\number\value{#1}}}

\renewcommand{\thesection}{\glagovalue{section}}

\begin{document}

\tableofcontents

\section{A section}

\setcounter{section}{100}

\section{Another}

\glagonumeral{909}

\glagonumeral{1} --
\glagonumeral{2} --
\glagonumeral{3} --
\glagonumeral{4} --
\glagonumeral{5} --
\glagonumeral{6} --
\glagonumeral{7} --
\glagonumeral{8} --
\glagonumeral{9} --
\glagonumeral{10} --
\glagonumeral{11} --
\glagonumeral{12} --
\glagonumeral{13} --
\glagonumeral{14} --
\glagonumeral{15} --
\glagonumeral{16} --
\glagonumeral{17} --
\glagonumeral{18} --
\glagonumeral{19} --
\glagonumeral{20} --
\glagonumeral{21} --
\glagonumeral{22} --
\glagonumeral{312} --
\glagonumeral{321} --
\glagonumeral{322}

\end{document}


What you have to do now is to change the letters I've used for the digits into suitable commands giving the appropriate glagolitic letters.

You can use \glagovalue{<counter>} just like \arabic{<counter>}.

Note: this version correctly sets 12 to "AJ", while 21 becomes "KA".

Important change

Due to the changes made to expl3 in Summer 2012, \seq_length:N should be replaced by \seq_count:N

\cs_new_protected:Npn \glago_numeral:n #1
{
\cs_set:Npn \glago_reverse_ten: { }
\seq_set_split:Nnx \l_glago_digits_seq { } { #1 }
\int_set:Nn \l_glago_position_int {\seq_count:N \l_glago_digits_seq - 1}
\seq_map_inline:Nn \l_glago_digits_seq
{
\glago_symbol:x { \glago_make_digit:nn { ##1 } { \l_glago_position_int } }
\int_decr:N \l_glago_position_int
}
\glago_reverse_ten:
}

-
I can’t wait to test it. Unfortunately, I don’t have TeX on my notebook . ;-( I’ll let you know how it works. –  Artur S. May 12 '12 at 15:23
I’ve forgotten about one thing. In Slavic languages, just like in English, in numbers 11—19 the digits are read the opposite way: compare twenty-five (25) with nineteen (19). In Glagolitic this is written like 9+10. Therefore if the one-before-last digit is logically 10, it is the last. Is it possible to include it in the code? –  Artur S. May 12 '12 at 15:46
@ArturS. Is this for all numbers? Even if they have other digits, I mean. So 341 should be "300 + 1 + 40"? And 234 is "200+4+30"? –  egreg May 12 '12 at 15:49
No, only in 11—19 the digits change places. 341 stays 300 + 40 + 1 while 517 should be 500 + 7 + 10. –  Artur S. May 12 '12 at 15:56
@ArturS. Here it is. :) –  egreg May 12 '12 at 16:16

A half baked LuaTeX solution. I don't know the LaTeX stuff that is needed to define the page counter, but this Lua function prints a string as you need. Perhaps someone can edit this code to make it work with LaTeX counters.

Edit: take the reverse numbering between 10 and 20 into account.

\documentclass{article}
\usepackage{luacode}
\begin{luacode*}
glagolitic = function(cnt)
local glag_reverse = {}
local i = 0
local m
while cnt > 0 do
m = cnt % 10
cnt = cnt - m
glag_reverse[#glag_reverse + 1] = string.rep("0",i) .. m
cnt = cnt / 10
i = i + 1
end
if glag_reverse[2] == "01" then
glag_reverse[1], glag_reverse[2] = glag_reverse[2], glag_reverse[1]
end
-- insert \textcompwordmark between elements and reverse the string
tex.sprint(string.reverse(table.concat(glag_reverse,"kramdrowpmoctxet\\")))
end
\end{luacode*}

% (here we need to define some macros that use the function glagolitic)
\begin{document}

%  prints: 310 203 100203 400506 500710 ...
\directlua{glagolitic(13)}
\directlua{glagolitic(23)}
\directlua{glagolitic(123)}
\directlua{glagolitic(456)}
\directlua{glagolitic(517)}
...
\end{document}

-
+1 for kramdrowpmoctxet\ –  Marco May 12 '12 at 15:53
Numbers from 11 to 19 are to be printed little endian: 15 -> 5.1; 515 -> 5.5.1 etc. Also for numbers > 999 the whole series starts anew, using a special prefix (U+0482) to mark the three-digit left shift. Above 999,999 you will have trouble finding a valid notation. (Btw. not using locals will mess up the output of the next call to glagolitic().) –  phg May 12 '12 at 16:16
@phg Thanks for pointing out the non-local variables, embarrassing - fixed ... I don't understand the other points though, as I read from the question for example 15 should be printed 10*5 where * is \textcompwordmark. –  topskip May 12 '12 at 16:58
@Patrick Gundlach The \textcompwordmark breaks ligatures. There are over 800 Glagolitic ligatures known, and they don’t look good in numbers. And 15 should be 5.10 actually. :) In Glagolitic, 10, 20, 100, 500 etc. are separate symbols. –  Artur S. May 12 '12 at 17:24
Generally you resolve 42 into the list (40, 2) and take the symbols in this order from the corresponding lists. However, numbers between 10 and 20 have the order of their figures inverted so the lower value (n*10^0) precedes the higher (n*10^1): 15 -> (5, 10). –  phg May 12 '12 at 17:26