duodecimal page number

With expl3 it's quite easy (and there's no limit on numbers, other than the usual 2147483647, the maximum number in TeX)

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\basetwelve}{m}
  { \duodec_convert:n { #1 } }

\tl_new:N \l_duodec_string_tl
\cs_new_protected:Npn \duodec_convert:n #1
  {
   \tl_set:Nx \l_duodec_string_tl { \int_to_base:nn { #1 } { 12 } }
   \tl_replace_all:Nnn \l_duodec_string_tl { A } { $\odot$ }
   \tl_replace_all:Nnn \l_duodec_string_tl { B } { $\Delta$ }
   \tl_use:N \l_duodec_string_tl
 }
\ExplSyntaxOff

\renewcommand{\thepage}{\basetwelve{\arabic{page}}}

\begin{document}

\ExplSyntaxOn
\int_step_inline:nnnn { 1 } { 1 } { 145 }
  { \basetwelve{#1} ~ }
\ExplSyntaxOff


\end{document}

The code is in the preamble and after it is a test for showing that the numbers are correctly produced in the requested form.

enter image description here

The \int_to_base:nn function produces A for 10 and B for 11, so we have to replace the letters with the symbols.

The input \basetwelve{123456} produces 5∆540.


What do we do? We define a robust command, \basetwelve, that will wrap the call to the conversion, performed by \duodec_convert:n. This command takes as input something that ultimately expands to a decimal number (for instance \arabic{page} and stores away the number converted into duodecimal form, with digits 0123456789AB, through the function \int_to_base:nn. Then we replace all A's with $\odot$ and all B's with $\Delta$ and deliver the so converted token list.

When LaTeX wants to write a page number to the .aux file, it will expand \thepage, getting \basetwelve{\arabic{page}}. Since \basetwelve is robust (all commands defined with \NewDocumentCommand are), it will be written untouched. Instead \arabic{page} will be expanded to the current page number, so what's written in the .aux file is, for instance, \basetwelve{23}. When this is used by \pageref the conversion will be performed, giving 1∆.


Here's a solution using the fmtcount package plus a new \duodecimal macro that is modelled on fmtcount's \hexadecimal. (Actually, it's an example of cargo-cult programming: I basically took the fmtcount macro set and replaced "hexa" with "duo", "16" with "12", and "65536" [16^4] with "20736" [12^4].)

\documentclass[12pt]{article}
\usepackage[paperheight=1.8in, textheight=0.8in]{geometry}

\newcommand{\sirdot}{$\odot$}
\newcommand{\apple}{$\Delta$}

\usepackage{fmtcount}

\makeatletter

\newcommand*{\@@duodecimal}[1]{\ifcase#10\or1\or2\or3\or4\or5\or
6\or7\or8\or9\or $\odot$\or $\Delta$\fi}

\newcommand*{\@duodecimal}[1]{%
\@DT@padzeroestrue
\@DT@loopN=5\relax
\@strctr=\@DT@loopN
\whiledo{\@strctr<\c@padzeroesN}{0\advance\@strctr by 1}%
\@strctr=20736\relax
\@DT@X=#1\relax
\loop
\@DT@modctr=\@DT@X
\divide\@DT@modctr by \@strctr
\ifthenelse{\boolean{@DT@padzeroes}\and\(\@DT@modctr=0\)\and
\(\@DT@loopN>\c@padzeroesN\)}{}{\@@duodecimal\@DT@modctr}%
\ifnum\@DT@modctr=0\else\@DT@padzeroesfalse\fi
\multiply\@DT@modctr by \@strctr
\advance\@DT@X by -\@DT@modctr
\divide\@strctr by 12\relax
\advance\@DT@loopN by -1\relax
\ifnum\@strctr>1
\repeat
\@@duodecimal\@DT@X}

\let\duodecimalnum=\@duodecimal

\providecommand*{\duodecimal}[1]{%
\expandafter\protect\expandafter\@duodecimal{%
\expandafter\the\csname c@#1\endcsname}}

\makeatother

\renewcommand*{\thepage}{\duodecimal{page}}

\begin{document}

The duodecimal numbers:
\begin{center}
1, 2, \ldots, 8, 9, \sirdot,  \apple, 10, 11, \ldots, 19, 1\sirdot,
1\apple, 20, 21, \ldots, \apple 9, \apple\sirdot, \apple\apple, 100 \ldots
\end{center}

\setcounter{page}{10}
Set page counter to 10, so this should be page \sirdot.
\newpage
This should be page \apple.
\newpage
This should be page 10.

\end{document}

Here's a first stab at it and it relies on the fact that you only require two-digit page numbers. As such, this solution is only good up to 144 pages:

enter image description here

\documentclass{article}
\usepackage[paperheight=50pt,paperwidth=5em,footskip=-10em]{geometry}%
\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\newcommand{\basetwelve}[1]{%
  \vphantom{0}\ifcase#1
    0\or1\or2\or3\or4\or5\or6\or7\or8\or9\or\smash{\raisebox{.2ex}{$\odot$}}\or\smash{$\Delta$}%
  \fi%
}
\newcounter{duo}%
\renewcommand{\thepage}{%
  \setcounter{duo}{\value{page}}%
  \FPeval\remainder{clip(\theduo-(12*round(\theduo/12-.5:0)))}%
  \FPeval\result{clip(round(\theduo/12-.5:0))}%
  \ifnum\result=0\else\basetwelve\result\fi\basetwelve\remainder%
}
\newcommand{\npage}{\mbox{}\newpage}
\pagestyle{plain}%
\begin{document}
\npage\npage\npage\npage\npage\npage\npage\npage\npage\npage
\npage\npage\npage\npage\npage\npage\npage\npage\npage\npage
\npage\npage\npage\npage\npage\npage\npage\npage\npage\npage
\npage\npage\npage\npage\npage\npage\npage\npage\npage\npage
\end{document}

\basetwelve{<num>} works like a lookup function, returning 0,1,...,9,"10","11" based on the input values. \result contains the first digit of the page number, and \remainder the second. fp was used to perform the modulo calculations for base 12.

Height adjustments for the non-numeric symbols is done using a combination of \smash and \raisebox, as well as a \vphantom{0} for numbers smaller than 12.

geometry settings is just for this example.