Changing the suffix according to the figure number

In Turkish (and possibly in other similar languages), there are suffixes that change corresponding to the word they are applied. This also holds for the numbers.

For example,

in Figure \ref{fig1}


is written in Turkish as follows:

Şekil \ref{fig1}'de


The problem here is that the suffix "de" should change according to the number rendered before it. It should be like

1'de, 2'de, 3'te, 4'te, 5'te, 6'da, ..., 60'ta, ..., 70'te, ...


I don't like to check the suffixes manually after finishing the paper. This also happens for the other cross-references like equations.

How can I do this in LaTeX?

Edit: I'm adding the complete rule as @egreg asks. The determining numbers are as follows:

0'da
1'de
2'de
3'te
4'te
5'te
6'da
7'de
8'de
9'da
10'da
20'de
30'da
40'da
50'de
60'ta
70'te
80'de
90'da
100'de
1000'de
1000000'da
1000000000'da


For all the others, the number at the end determines the suffix if it is non-zero. For example

1234'te  (4'te)
303'te (3'te)


But, if there's a zero at the end and the number is not zero, then the right-most non-zero digit determines the result:

230'da (30'da)
200'de (100'de)
4000'de (1000'de)
40000'de (1000'de)
400000'de (1000'de)
4000000'da (1000000'da)


The suffix is determined by the last read word. For example 40000 is read as "kırk bin" and it becomes "40000'de". It is the same as "1000'de" which is read as "binde".

-
Can you spell out the complete rule? – egreg Feb 15 at 11:16
are these suffixes like the ordinal suffixes in english -- 1st 2nd 3rd 4th ... 11th ... 21st (and so on)? – wasteofspace Feb 15 at 11:53
Yes, they are like the ordinal suffixes in English. – petrichor Feb 15 at 12:57
I've added the full spec. – petrichor Feb 15 at 13:09
The package fmtcount can be of use. I have to go now, but later (3 hours maybe) I'll prepare an .def file for this Turkish rules (unless someone else does so). – tohecz Feb 15 at 13:17

This is a possible implementation using LaTeX3:

\documentclass{article}
\usepackage[turkish]{babel}
\usepackage{refcount}
\usepackage{multicol}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\turkishref}{sm}
{
\IfBooleanTF{#1}{\ref*{#2}}{\ref{#2}}
\turksuf_suffix_get:n { #2 }
}

\seq_new:N \l__turksuf_ref_seq
\tl_new:N \l__turksuf_ref_tl
\cs_new_protected:Npn \turksuf_suffix_get:n #1
{
\seq_set_split:Nnx \l__turksuf_ref_seq { . } { \getrefnumber { #1 } }
\seq_pop_right:NN \l__turksuf_ref_seq \l__turksuf_ref_tl
\turksuf_suffix:V \l__turksuf_ref_tl
}
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }

\NewDocumentCommand{\turkishsuffix}{m}
{
\turksuf_suffix:n { #1 }
}

\cs_new:Npn \turksuf_suffix:n #1
{
\int_compare:nTF { #1 == 0 } { 'da } { \turksuf_nonzero:n { #1 } }
}
\cs_new:Npn \turksuf_nonzero:n #1
{
\int_case:nnn { #1 }
{
{1}{'de}
{2}{'de}
{3}{'te}
{4}{'te}
{5}{'te}
{6}{'da}
{7}{'de}
{8}{'de}
{9}{'da}
{10}{'da}
{20}{'de}
{30}{'da}
{40}{'da}
{50}{'de}
{60}{'da}
{70}{'de}
{80}{'de}
{90}{'da}
{100}{'de}
{1000}{'de}
}
{
\turksuf_complex:n { #1 }
}
}
\cs_generate_variant:Nn \turksuf_suffix:n { V }

\cs_new:Npn \turksuf_complex:n #1
{
\int_compare:nTF { \int_mod:nn { #1 } { 10 } = 0 }
{ \turksuf_complex_ten:n { #1 } }
{ \turksuf_nonzero:n { \int_mod:nn { #1 } { 10 } } }
}

\cs_new:Npn \turksuf_complex_ten:n #1
{
\int_compare:nTF { \int_mod:nn { #1 } { 100 } = 0 }
{ \turksuf_complex_hundred:n { #1 } }
{ \turksuf_nonzero:n { \int_mod:nn { #1 } { 100 } } }
}
\cs_new:Npn \turksuf_complex_hundred:n #1
{
\int_compare:nTF { \int_mod:nn { #1 } { 1000 } = 0 }
{ \turksuf_complex_thousand:n { #1 } }
{ 'de }%{ \turksuf_nonzero:n { \int_mod:nn { #1 } { 1000 } } }
}
\cs_new:Npn \turksuf_complex_thousand:n #1
{
\int_compare:nTF { \int_mod:nn { #1 } { 10000 } = 0 }
{ \turksuf_complex_tenthousand:n { #1 } }
{ 'de }%{ \turksuf_nonzero:n { \int_mod:nn { #1 } { 10000 } } }
}
\cs_new:Npn \turksuf_complex_tenthousand:n #1
{
\int_compare:nTF { \int_mod:nn { #1 } { 100000 } = 0 }
{ \turksuf_complex_hundredthousand:n { #1 } }
{ 'de }%{ \turksuf_nonzero:n { \int_mod:nn { #1 } { 100000 } } }
}
\cs_new:Npn \turksuf_complex_hundredthousand:n #1
{
\int_compare:nTF { \int_mod:nn { #1 } { 1000000 } = 0 }
{ \turksuf_complex_million:n { #1 } }
{ 'da }%{ \turksuf_nonzero:n { \int_mod:nn { #1 } { 1000000 } } }
}
\NewDocumentCommand\test{m}
{
\int_step_inline:nnnn { 0 } { 1 } { #1 }
{ ##1\turkishsuffix{##1}\par }
}
\ExplSyntaxOff

\setlength{\parindent}{0pt} % just for the test

\begin{document}
\begin{multicols}{5}
\test{300}
\end{multicols}

\setcounter{figure}{12}
\begin{figure}
\caption{X}\label{A}
\end{figure}
\figurename~\turkishref{A}.

1234\turkishsuffix{1234}\\
1320\turkishsuffix{1320}\\
1330\turkishsuffix{1330}\\
1000\turkishsuffix{1000}\\
1003\turkishsuffix{1003}

\setcounter{section}{1}
\setcounter{subsection}{3}
\subsection{B}\label{B}

Subsection~\turkishref{B}

\end{document}


I show only the last lines with the reference to the figure and the following test cases.

NOTE Support for "composite numbers" has been added. Moreover, one has \turkishref* that calls \ref* instead of \ref (of course hyperref is needed for this to work).

-
 It gives an error at line 17 saying that: Illegal parameter number in definition of \turksuf_suffix_get:n: ...turksuf_ref_seq { . } { \getrefnumber { #2 .... How can I fix it? – petrichor Feb 17 at 21:32 @petrichor Sorry, a copy-paste error; the #2 should be #1; I'll fix it in a moment. – egreg Feb 17 at 21:39 It works perfect now with the composite numbers. Thank you very much. – petrichor Feb 17 at 21:47

This tweaks into the package fmtcount and provides the numeric ordinals for turkish language.

First, save the following code as fc-turkish.tex (for example, the name does not matter). The official name inside the package fmtcount would be different, but I don't want to use the official one since this is not an official file of the package.

\makeatletter
\def\@OT@do#1#2#3#4#5#6#7\@OT@enddo{%
\ifcase0#1 % ~0
\ifx\relax#2\relax% 0
\def\@OT@suf{da}%
\else
\ifcase#2 % ~00
\ifx0#3% ~000
\ifx0#4% ~0000
\ifx0#5% ~00000
\ifx0#6% ~000000
\def\@OT@suf{da}%
\else % ~x00000
\def\@OT@suf{de}%
\fi
\else % ~x0000
\def\@OT@suf{de}%
\fi
\else % ~x000
\def\@OT@suf{de}%
\fi
\else % ~x00
\def\@OT@suf{de}%
\fi
\or% ~10
\def\@OT@suf{da}%
\or% ~20
\def\@OT@suf{de}%
\or% ~30
\def\@OT@suf{da}%
\or% ~40
\def\@OT@suf{da}%
\or% ~50
\def\@OT@suf{de}%
\or% ~60
\def\@OT@suf{da}%
\or% ~70
\def\@OT@suf{de}%
\or% ~80
\def\@OT@suf{de}%
\or% ~90
\def\@OT@suf{da}%
\fi
\fi
\or% ~1
\def\@OT@suf{de}%
\or% ~2
\def\@OT@suf{de}%
\or% ~3
\def\@OT@suf{te}%
\or% ~4
\def\@OT@suf{te}%
\or% ~5
\def\@OT@suf{te}%
\or% ~6
\def\@OT@suf{da}%
\or% ~7
\def\@OT@suf{de}%
\or% ~8
\def\@OT@suf{de}%
\or% ~9
\def\@OT@suf{da}%
\fi
}
\def\@OT@rev#1#2\revA#3\revB{%
\if\relax\detokenize{#2}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi{#1#3}{\@OT@rev#2\revA#1#3\revB}}
\newcommand{\@ordinalMturkish}[1]{%
\@orgargctr=#1\relax
\@ordinalctr=#1%
\edef\@OT@str{\the\@ordinalctr}%
\edef\@OT@str{\expandafter\@OT@rev\@OT@str\revA\revB}%
\expandafter\@OT@do\@OT@str\relax\relax\relax\relax\relax\relax\@OT@enddo
\the\@orgargctr\fmtord{'\@OT@suf}%
}
\def\ordref#1{%
\edef\@OD@ref{\csname r@#1\endcsname\relax}%
\edef\@OD@num{\expandafter\@firstoftwo\@OD@ref}%
\ifx\@OD@num\relax
\@orgargctr0%
\else
\expandafter\@orgargctr0\@OD@num
\fi
\@ordinalMturkish\@orgargctr
}
\let\@ordinalFturkish=\@ordinalMturkish
\makeatother


Then, you can use the package fmtcount with turkish. Test document:

\documentclass[12pt, oneside]{article}
\usepackage[turkish]{babel}
\usepackage[level]{fmtcount}
\input{fc-turkish.tex}
\def\fmtord#1{#1}
\begin{document}

\ttfamily

\section{First}

\section{Hello World!}\label{sec2s}

In \ordref{sec2s} section, there is a test of package functionality:

\raggedright\ttfamily

\ordinal{section}
\loop
\ifnum\value{section}<1000
\refstepcounter{section}
\ordinal{section}
\repeat

\loop
\ifnum\value{section}<100000
\ordinal{section}
\repeat

\setcounter{section}{0}

\loop
\ifnum\value{section}<1000000

I apologize for not commenting the code. I'm actually not sure how I would comment it. Part is taken from fc-english.def and another part is a bunch of tests to get the right suffix. Only a small note: the macro \OT@do is fed the number to be typeset, but written reversed, so the least significant digit is got as #1. The macro \ordref won't work with nested numbers (2 is ok, 2.4 is not).
 It gave an error for my case: Line 18: Undefined control sequence: ...e c@section\endcsname }{\@fc@ordstr : \ordinal{section}. I am using Miktex on Windows and generating via pdflatex. I saved the file with the name you gave and trying to compile the second file. – petrichor Feb 17 at 21:43