summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/numberpt
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/numberpt
Initial commit
Diffstat (limited to 'macros/latex/contrib/numberpt')
-rw-r--r--macros/latex/contrib/numberpt/README.md44
-rw-r--r--macros/latex/contrib/numberpt/numberpt.dtx564
-rw-r--r--macros/latex/contrib/numberpt/numberpt.ins30
-rw-r--r--macros/latex/contrib/numberpt/numberpt.pdfbin0 -> 325870 bytes
4 files changed, 638 insertions, 0 deletions
diff --git a/macros/latex/contrib/numberpt/README.md b/macros/latex/contrib/numberpt/README.md
new file mode 100644
index 0000000000..95224fb775
--- /dev/null
+++ b/macros/latex/contrib/numberpt/README.md
@@ -0,0 +1,44 @@
+# Package numberpt #
+
+Typeset counters spelled out in Portuguese.
+
+Author: Miguel V. S. Frasson
+[mvsfrasson@gmail.com](mailto:mvsfrasson@gmail.com)
+
+This material is subject to the
+[LaTeX Project Public License 1.3c](https://ctan.org/license/lppl1.3)
+
+## What it does ##
+
+Package `numberpt` defines commands to display counters speeled out in
+Portuguese.
+
+For example,
+``` TeX
+\renewcommand{\thechapter}{\Numberpt{chapter}}
+```
+makes chapter titles to be rendered as
+> **Capítulo Um**
+> **Capítulo Dois**
+
+The styles are
+* `\numberpt` for _all lowercase_
+* `\Numberpt` for _First word capitalized_
+* `\Numberpt` for _All Capitalized_
+* `\NUMBERPT` for _ALL UPPERCASE_
+
+## Options ##
+
+In Portuguese, both “catorze” or “quatorze” (for 14) are correct.
+
+In European Portuguese, the spelled out forms for 16, 17 and 19 are
+“dezasseis”, “dezassete” and “dezanove”. In Brazilian Portuguese, the
+forms are “dezesseis”, “dezessete” and “dezenove”.
+
+The package has options
+* `catorze` (default) and `quatorze` to select form for 14.
+* `dezesseis` (default) and `dezasseis` to select Brazilian or European Portuguese forms for 16, 17 and 19.
+
+## Documentation ##
+
+Full documentation on [numberpt.pdf].
diff --git a/macros/latex/contrib/numberpt/numberpt.dtx b/macros/latex/contrib/numberpt/numberpt.dtx
new file mode 100644
index 0000000000..d2243a4dff
--- /dev/null
+++ b/macros/latex/contrib/numberpt/numberpt.dtx
@@ -0,0 +1,564 @@
+% \iffalse
+% File: numberpt.dtx
+%
+% Copyright (C) 2019 Miguel V. S. Frasson (mvsfrasson@gmail.com)
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008/05/04 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is the author.
+%
+% This work consists of the files numberpt.dtx and numberpt.ins
+% and the derived file numberpt.sty.
+%
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage{doc}
+\usepackage[T1]{fontenc}
+\usepackage{amstext,makeidx,multicol}
+\usepackage{numberpt}
+\begin{document}
+ \DocInput{numberpt.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% \StopEventually
+%
+% \changes{1.0}{2019/07/13}{initial version}
+%
+% \MakeShortVerb+
+%
+% \title{\textsf{numberpt}: counters spelled out in Portuguese}
+% \author{Miguel Vin\'\i cius Santini Frasson}
+% \date{2019--07--13 version 1.0}
+%
+% \maketitle
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% The package \textsf{numberpt} provides a counter style like
+% +\arabic+, +\alph+ etc., but that spells numbers in Portuguese, like
+% ``um'' (one in Portuguese), ``dois'' (two), ``tr\^es'' (three),
+% \ldots, up to ``novecentos e noventa e nove mil novecentos e noventa
+% e nove'' (999{,}999). There are counter commands to output the text
+% in ``lowercase'', ``First word capitalized'', ``All Words
+% Capitalized'' ou in ``UPPERCASE''.
+%
+% \section{User commands}
+%
+% \newcommand{\countername}{\texttt{\textit{counter}}}
+%
+% \DescribeMacro{\numberpt}
+% \DescribeMacro{\Numberpt}
+% \DescribeMacro{\NumberPt}
+% \DescribeMacro{\NUMBERPT}
+% Macros to output counters in Portuguese in ``lowercase'',
+% ``Capitalized'' or in ``UPPERCASE''---:\\
+% + \numberpt{+\countername+}+ (ex: vinte e tr\^es),\\
+% + \Numberpt{+\countername+}+ (ex: Vinte e tr\^es),\\
+% + \NumberPt{+\countername+}+ (ex: Vinte E Tr\^es),\\
+% + \NUMBERPT{+\countername+}+ (ex: VINTE E TR\^ES).
+%
+% Example:
+%
+%\begin{verbatim}
+%\renewcommand{\thechapter}{\Numberpt{chapter}}
+%\end{verbatim}
+% will produce chapter headers like:
+%
+% \centerline{Cap\'itulo Um}
+% \centerline{Cap\'itulo Dois}
+%
+% By default, command +\NumberPt+ for all capitalized numbers output
+% connectors ``e'' in uppercase. For example, if +page+ counter is 23,
+% then +\NumberPt{page}+ $\to$ Vinte E Tr\^es. To change this behavior
+% (connector ``e'' in lowercase), use starred versions +\NumberPt*+.
+%
+% \section{Package options}
+%
+% \DescribeMacro{catorze}
+% \DescribeMacro{quatorze}
+% For 14, both forms ``catorze'' e ``quatorze'' are correct. Use
+% package option +catorze+ (default) or +quatorze+ to select which
+% form is used.
+%
+% \DescribeMacro{dezesseis}
+% \DescribeMacro{dezasseis}
+% In Brazil, the forms for 16, 17 and 19 are ``dezesseis'',
+% ``dezessete'' and ``de\-ze\-no\-ve''. In Portugal, the forms are
+% ``dezasseis'', ``dezassete'' and ``dezanove''. To select Brazilian
+% Portuguese forms (default), use option +dezesseis+; for European
+% Portuguese form, use +dezasseis+.
+%
+% \section{Code}
+%
+% \subsection{Package identification}
+%
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\ProvidesPackage{numberpt}[2019/07/12 v1.0 Counters as numbers in Portuguese]
+% \end{macrocode}
+%
+% We use \LaTeX3 in this package.
+%
+% \begin{macrocode}
+\RequirePackage{expl3,xparse}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \subsection{Package options}
+% Package options declarations +catorze+ or +quatorze+, and
+% +dezasseis+ or +dezesseis+. Creating undocumented ``user commands''
+% +\NumberPTcatorze+, +\NumberPTquatorze+, +\NumberPTdezasseis+ and
+% +\NumberPTdezasseis+ that set switches.
+%
+% \begin{macrocode}
+\bool_new:N \NumberPT_catorze
+\bool_new:N \NumberPT_dezesseis
+\newcommand{\NumberPTcatorze}{\bool_set_true:N \NumberPT_catorze}
+\newcommand{\NumberPTquatorze}{\bool_set_false:N \NumberPT_catorze}
+\DeclareOption{ catorze }{ \NumberPTcatorze }
+\DeclareOption{ quatorze }{ \NumberPTquatorze }
+\ExecuteOptions{ catorze }
+\newcommand{\NumberPTdezesseis}{\bool_set_true:N \NumberPT_dezesseis}
+\newcommand{\NumberPTdezasseis}{\bool_set_false:N \NumberPT_dezesseis}
+\DeclareOption{ dezasseis }{ \NumberPTdezasseis}
+\DeclareOption{ dezesseis }{ \NumberPTdezesseis}
+\ExecuteOptions{ dezesseis }
+\ProcessOptions
+% \end{macrocode}
+%
+% \subsection{Case handling}
+% Command +\NumberPT_case:nn+ and switches govern capitalization.
+%
+% \begin{macrocode}
+\bool_new:N \NumberPT_capital
+\bool_new:N \NumberPT_capitalfirst
+\bool_new:N \NumberPT_capitale
+\bool_new:N \NumberPT_uppercase
+\cs_new:Nn \NumberPT_case:nn {
+ \bool_if:NTF \NumberPT_capital {
+ \uppercase { #1 }
+ } {
+ #1
+ }
+ \bool_if:NTF \NumberPT_uppercase {
+ \uppercase { #2 }
+ } {
+ #2 }
+ \bool_if:NT \NumberPT_capitalfirst {
+ \bool_set_false:N \NumberPT_capital
+ }
+}
+% \end{macrocode}
+%
+% \subsection{Output for numbers with 1, 2 or 3 digits}
+% +\NumberPT_u:n{+$U$+}+ takes digit $U$ and outputs ``zero'', ``um'',
+% ``dois'', \dots, ``nove''.
+%
+% \begin{macrocode}
+\cs_new:Nn \NumberPT_u:n {
+ \if_case:w #1
+ \NumberPT_case:nn {z}{ero}\or:
+ \NumberPT_case:nn {u}{m}\or:
+ \NumberPT_case:nn {d}{ois}\or:
+ \NumberPT_case:nn {t}{r\^es}\or:
+ \NumberPT_case:nn {q}{uatro}\or:
+ \NumberPT_case:nn {c}{inco}\or:
+ \NumberPT_case:nn {s}{eis}\or:
+ \NumberPT_case:nn {s}{ete}\or:
+ \NumberPT_case:nn {o}{ito}\or:
+ \NumberPT_case:nn {n}{ove}%
+ \fi:}
+% \end{macrocode}
+%
+% Command +\NumberPT_e_u:n{+$U$+}+ outputs `` e um'' etc, if $U>0$,
+% otherwise outputs nothing.
+%
+% \begin{macrocode}
+\cs_new:Nn \NumberPT_e_u:n {
+ \int_compare:nNnT #1 > 0 {
+ \space \bool_if:nTF \NumberPT_capitale {E}{e} \space \NumberPT_u:n #1
+ }
+}
+% \end{macrocode}
+%
+% Commands +\NumberPT_du:nn{+$D$+}{+$U$+}+ and
+% +\NumberPT_e_du:nn{+$D$+}{+$U$+}+ are similar, with 2 digits.
+% Numbers from 0 to 19 are all special cases.
+%
+% \begin{macrocode}
+\cs_new:Nn \NumberPT_du:nn {
+ \if_case:w #1 % #1=0
+ \NumberPT_u:n #2
+ \or: % #1=1
+ \if_case:w #2
+ \NumberPT_case:nn {d}{ez}\or:
+ \NumberPT_case:nn {o}{nze}\or:
+ \NumberPT_case:nn {d}{oze}\or:
+ \NumberPT_case:nn {t}{reze}\or:
+ \bool_if:NTF \NumberPT_catorze {
+ \NumberPT_case:nn {c}{atorze}
+ } {
+ \NumberPT_case:nn {q}{uatorze}
+ }\or:
+ \NumberPT_case:nn {q}{uinze}\or:
+ \bool_if:NTF \NumberPT_dezesseis {
+ \NumberPT_case:nn {d}{ezesseis}
+ } {
+ \NumberPT_case:nn {d}{ezasseis}
+ }\or:
+ \bool_if:NTF \NumberPT_dezesseis {
+ \NumberPT_case:nn {d}{ezessete}
+ } {
+ \NumberPT_case:nn {d}{ezassete}
+ }\or:
+ \NumberPT_case:nn {d}{ezoito}\or:
+ \bool_if:NTF \NumberPT_dezesseis {
+ \NumberPT_case:nn {d}{ezenove}
+ } {
+ \NumberPT_case:nn {d}{ezanove}
+ }\or:
+ \fi:
+ \or: % #1>1
+ \NumberPT_case:nn {v}{inte} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {t}{rinta} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {q}{uarenta} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {c}{inquenta} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {s}{essenta} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {s}{etenta} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {o}{itenta} \NumberPT_e_u:n #2
+ \or:
+ \NumberPT_case:nn {n}{oventa} \NumberPT_e_u:n #2
+ \fi:
+}
+
+\cs_new:Nn \NumberPT_e_du:nn {
+ \int_compare:nNnT { #1 + #2 } > 0 {
+ \space \bool_if:nTF \NumberPT_capitale {E}{e} \space \NumberPT_du:nn #1 #2
+ }
+}
+% \end{macrocode}
+%
+% +\NumberPT_cdu:nnn{+$C$+}{+$D$+}{+$U$+}+ takes digits $C$, $D$ and $U$
+% and outputs correspondent number.
+%
+% \begin{macrocode}
+\cs_new:Nn \NumberPT_cdu:nnn {%
+ \if_case:w #1 % #1=0
+ \NumberPT_du:nn #2 #3
+ \or: % #1=1
+ \int_compare:nNnTF { #2 + #3 } = 0 % "cem" if 00 or "cento e " + finish
+ { \NumberPT_case:nn {c}{em} }
+ { \NumberPT_case:nn {c}{ento} \NumberPT_e_du:nn #2 #3 }
+ \or: % #1>1
+ \NumberPT_case:nn {d}{uzentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {t}{rezentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {q}{uatrocentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {q}{uinhentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {s}{eiscentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {s}{etecentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {o}{itocentos} \NumberPT_e_du:nn #2 #3
+ \or:
+ \NumberPT_case:nn {n}{ovecentos} \NumberPT_e_du:nn #2 #3
+ \fi:
+}
+% \end{macrocode}
+%
+% \subsection{Output for numbers with 4, 5 or 6 digits}
+%
+% \DeleteShortVerb+
+% If a number $abcdef$ has between 4 and 6 digits, the rule for
+% spelling this number is\footnote{See
+% \texttt{www.languagesandnumbers.com/como-contar-em-portugues-brasil/pt/por-bra/}}:
+% \begin{itemize}
+% \item spell the 3-digits number $abc$ (unless $abc=001$) + ``mil''
+% \item stop if $def=000$, otherwise:
+% \item add the connector ``e'' for numbers
+% \begin{itemize}
+% \item finishing in 00, \emph{i.e.}, $e+f=0$
+% \item without digit for hundreds , \emph{i.e.}, $d=0$
+% \end{itemize}%
+% \item spell the 3-digits number $def$
+% \end{itemize}
+%
+% \begin{macrocode}
+\cs_new:Nn \NumberPT_e_cdu:nnn {
+ \int_compare:nNnF {#1 + #2 + #3} = 0 {
+ \space
+ \bool_if:nT { \int_compare_p:nNn #1 = 0 || \int_compare_p:nNn {#2 + #3} = 0 }
+ {
+ \bool_if:nTF \NumberPT_capitale {E}{e}
+ \space
+ }
+ \NumberPT_cdu:nnn #1 #2 #3
+ }
+}
+% \end{macrocode}
+%
+% Output for numbers with up to 6 digits.
+%
+% \begin{macrocode}
+\cs_new:Nn \NumberPT_abcdef:nnnnnn {
+ \int_compare:nNnTF {#1 + #2 + #3} = 0 %abc=000
+ {
+ \NumberPT_cdu:nnn #4 #5 #6
+ }
+ % else
+ {
+ % avoid "um mil", using just "mil"
+ \int_compare:nNnF {100 * #1 + 10 * #2 + #3} = 1 {
+ \NumberPT_cdu:nnn #1 #2 #3
+ \space
+ }
+ \NumberPT_case:nn {m}{il}
+ \NumberPT_e_cdu:nnn #4 #5 #6
+ }
+}
+\cs_generate_variant:Nn \NumberPT_abcdef:nnnnnn {xxxxxx}
+% \end{macrocode}
+%
+% \subsection{Conversion from counter to digits}
+%
+% \MakeShortVerb+
+% Now, conversion from counter to digits. digits will be stored in
+% macros +\NumberPT_digit_u+, +\NumberPT_digit_d+, +\NumberPT_digit_c+.
+% Decomposition is done with mod.
+%
+% \begin{macrocode}
+\int_new:N \NumberPT_digit_u
+\int_new:N \NumberPT_digit_d
+\int_new:N \NumberPT_digit_c
+\int_new:N \NumberPT_digit_um
+\int_new:N \NumberPT_digit_dm
+\int_new:N \NumberPT_digit_cm
+
+\cs_new:Nn \NumberPT_decompose:n {
+ \int_set:Nn \l_tmpa_int { #1 }
+ \int_set:Nn \NumberPT_digit_u { \int_mod:nn { \l_tmpa_int } { 10 } }
+ \int_set:Nn \l_tmpa_int { ( \l_tmpa_int - \NumberPT_digit_u ) / 10 }
+ \int_set:Nn \NumberPT_digit_d { \int_mod:nn { \l_tmpa_int } { 10 } }
+ \int_set:Nn \l_tmpa_int { ( \l_tmpa_int - \NumberPT_digit_d ) / 10 }
+ \int_set:Nn \NumberPT_digit_c { \int_mod:nn { \l_tmpa_int } { 10 } }
+ \int_set:Nn \l_tmpa_int { ( \l_tmpa_int - \NumberPT_digit_c ) / 10 }
+ \int_set:Nn \NumberPT_digit_um { \int_mod:nn { \l_tmpa_int } { 10 } }
+ \int_set:Nn \l_tmpa_int { ( \l_tmpa_int - \NumberPT_digit_um ) / 10 }
+ \int_set:Nn \NumberPT_digit_dm { \int_mod:nn { \l_tmpa_int } { 10 } }
+ \int_set:Nn \l_tmpa_int { ( \l_tmpa_int - \NumberPT_digit_dm ) / 10 }
+ \int_set:Nn \NumberPT_digit_cm { \int_mod:nn { \l_tmpa_int } { 10 } }
+}
+% \end{macrocode}
+%
+% Now, command that prints counter: +\NumberPT_print_counter:n+.
+% Declaring error message in case counter is out of range from 0 to 999.
+% Even in case of this error, falls back to arabic number.
+%
+% \begin{macrocode}
+\msg_new:nnn
+{ numberpt } { counter-out-of-range } {Counter~`#1'~out~of~range~0~...~999999}
+
+\cs_new:Nn \NumberPT_print_counter:n {
+ \int_set:Nn \l_tmpa_int { \value{#1} }
+ \bool_if:nTF {
+ \int_compare_p:n { \l_tmpa_int >= 0 } &&
+ \int_compare_p:n { \l_tmpa_int < 1000000 }
+ }
+ {
+ \NumberPT_decompose:n { \l_tmpa_int }
+ \NumberPT_abcdef:xxxxxx
+ { \int_use:N \NumberPT_digit_cm }
+ { \int_use:N \NumberPT_digit_dm }
+ { \int_use:N \NumberPT_digit_um }
+ { \int_use:N \NumberPT_digit_c }
+ { \int_use:N \NumberPT_digit_d }
+ { \int_use:N \NumberPT_digit_u }
+ }
+ {
+ \msg_error:nnn { numberpt } { counter-out-of-range } {#1}
+ \arabic{#1}
+ }
+}
+% \end{macrocode}
+%
+% \subsection{User macros}
+% Finally, user macros. Each macro sets switches for capitalization
+% and calls +\NumberPT_print_counter:n+.
+% \begin{macrocode}
+\NewDocumentCommand{\numberpt}{m}{
+ \bool_set_false:N \NumberPT_capital
+ \bool_set_false:N \NumberPT_capitale
+ \bool_set_false:N \NumberPT_uppercase
+ \NumberPT_print_counter:n { #1 }
+}
+
+\NewDocumentCommand{\NumberPt}{s m}{
+ \bool_set_true:N \NumberPT_capital
+ \bool_set:Nn \NumberPT_capitale {! #1}
+ \bool_set_false:N \NumberPT_capitalfirst
+ \bool_set_false:N \NumberPT_uppercase
+ \NumberPT_print_counter:n { #2 }
+}
+
+\NewDocumentCommand{\Numberpt}{m}{
+ \bool_set_true:N \NumberPT_capital
+ \bool_set_false:N \NumberPT_capitale
+ \bool_set_true:N \NumberPT_capitalfirst
+ \bool_set_false:N \NumberPT_uppercase
+ \NumberPT_print_counter:n { #1 }
+}
+
+\NewDocumentCommand{\NUMBERPT}{m}{
+ \bool_set_true:N \NumberPT_capital
+ \bool_set_true:N \NumberPT_capitale
+ \bool_set_true:N \NumberPT_uppercase
+ \NumberPT_print_counter:n { #1 }
+}
+% \end{macrocode}
+%
+% End of code.
+% \begin{macrocode}
+\ExplSyntaxOff
+\endinput
+% \end{macrocode}
+%
+% \section{Tests}
+%
+% Here we create a counter and spell the numbers for some selected values.
+%
+% \newcounter{test}
+% \newcommand{\test}[1]{\par\setcounter{test}{#1}#1: \numberpt{test}}
+% \newcommand{\Test}[1]{\par\setcounter{test}{#1}#1: \Numberpt{test}}
+% \newcommand{\TesT}[1]{\par\setcounter{test}{#1}#1: \NumberPt{test}}
+% \newcommand{\TesTs}[1]{\par\setcounter{test}{#1}#1: \NumberPt*{test}}
+% \newcommand{\TEST}[1]{\par\setcounter{test}{#1}#1: \NUMBERPT{test}}
+%
+% \subsection{Tests with \texttt{\protect\string\numberpt}}
+%
+% \begin{multicols}{3}
+% \test{1}
+% \test{2}
+% \test{3}
+% \test{4}
+% \test{5}
+% \test{6}
+% \test{7}
+% \test{8}
+% \test{9}
+% \test{10}
+% \test{11}
+% \test{12}
+% \test{13}
+% \test{14}
+% \test{15}
+% \test{16}
+% \test{17}
+% \test{18}
+% \test{19}
+% \test{20}
+% \test{21}
+% \test{22}
+% \test{30}
+% \test{31}
+% \test{40}
+% \test{41}
+% \test{50}
+% \test{51}
+% \test{60}
+% \test{61}
+% \test{70}
+% \test{71}
+% \test{80}
+% \test{81}
+% \test{90}
+% \test{91}
+% \test{100}
+% \test{101}
+% \end{multicols}
+% \subsection{Tests with \texttt{\protect\string\Numberpt}}
+% \begin{multicols}{2}
+% \Test{199}
+% \Test{200}
+% \Test{201}
+% \Test{300}
+% \Test{301}
+% \Test{400}
+% \Test{401}
+% \Test{500}
+% \Test{501}
+% \end{multicols}
+% \subsection{Tests with \texttt{\protect\string\NumberPt}}
+% \begin{multicols}{2}
+% \TesT{600}
+% \TesT{601}
+% \TesT{700}
+% \TesT{701}
+% \end{multicols}
+% \subsection{Tests with \texttt{\protect\string\NumberPt*}}
+% \begin{multicols}{2}
+% \TesTs{800}
+% \TesTs{801}
+% \TesTs{900}
+% \TesTs{999}
+% \end{multicols}
+% \subsection{Tests with \texttt{\protect\string\NUMBERPT}}
+% \begin{multicols}{1}
+% \end{multicols}
+% \TEST{1000}
+% \TEST{1001}
+% \TEST{1099}
+% \TEST{1100}
+% \TEST{1101}
+% \TEST{2000}
+% \TEST{2001}
+% \TEST{2099}
+% \TEST{2100}
+% \TEST{2101}
+% \TEST{2200}
+% \TEST{2201}
+% \TEST{2299}
+% \TEST{2300}
+%
+% \subsection{Tests with 14, 16, 17, 19}
+%
+% \begin{quote}
+%
+% \end{quote}
+% \NumberPTcatorze
+% \test{14} (must be ``catorze'')\medskip
+% \NumberPTquatorze
+% \test{14} (must be ``quatorze'')\bigskip
+%
+% \NumberPTdezasseis
+% \test{16} (must be ``dezasseis'')
+% \test{17} (must be ``dezassete'')
+% \test{19} (must be ``dezanove'')\medskip
+% \NumberPTdezesseis
+% \test{16} (must be ``dezesseis'')
+% \test{17} (must be ``dezessete'')
+% \test{19} (must be ``dezenove'')
+% \end{document}
+
diff --git a/macros/latex/contrib/numberpt/numberpt.ins b/macros/latex/contrib/numberpt/numberpt.ins
new file mode 100644
index 0000000000..8436cc068a
--- /dev/null
+++ b/macros/latex/contrib/numberpt/numberpt.ins
@@ -0,0 +1,30 @@
+\input docstrip
+
+\preamble
+
+Copyright (C) 2019 Miguel V. S. Frasson (mvsfrasson@gmail.com)
+
+This work may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version.
+The latest version of this license is in
+ http://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2008/05/04 or later.
+
+This work has the LPPL maintenance status `maintained'.
+
+The Current Maintainer of this work is the author.
+
+This work consists of the files numberpt.dtx and numberpt.ins
+and the derived file numberpt.sty.
+
+\endpreamble
+
+\askforoverwritefalse
+\askonceonly
+\showprogress
+
+\generate{\file{numberpt.sty}{\from{numberpt.dtx}{}}}
+
+\endbatchfile \ No newline at end of file
diff --git a/macros/latex/contrib/numberpt/numberpt.pdf b/macros/latex/contrib/numberpt/numberpt.pdf
new file mode 100644
index 0000000000..e515cabe7f
--- /dev/null
+++ b/macros/latex/contrib/numberpt/numberpt.pdf
Binary files differ