Skip to content

Commit 83c74fa

Browse files
committed
Apocopate "uno"/"veintiuno" before mil and millones in Spanish
Spanish shortens "uno" to "un" and "veintiuno" to "veintiún" immediately before "mil" and the "-illón/-illones" scale words. So 21000 is "veintiún mil" and 21000000 is "veintiún millones", not "veintiuno mil" or "veintiuno millones". The apocope was already applied to currency output but never to plain cardinals. Apply it in Num2Word_ES.to_cardinal and add regression tests. Fixes #515
1 parent 07814cb commit 83c74fa

2 files changed

Lines changed: 21 additions & 1 deletion

File tree

num2words/lang_ES.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from __future__ import division, print_function, unicode_literals
1919

2020
import math
21+
import re
2122

2223
from .lang_EU import Num2Word_EU
2324

@@ -302,6 +303,18 @@ def merge(self, curr, next):
302303

303304
return (ctext + ntext, cnum * nnum)
304305

306+
# "uno" apocopates to "un", and "veintiuno" to "veintiún", right before
307+
# "mil" and the "-illón/-illones" scale words: "veintiún mil", "treinta y
308+
# un millones", "veintiún mil millones". Source: https://www.rae.es/dpd/uno
309+
_APOCOPE_SCALE = r'(?=\s+(?:mil|\w*ll(?:ón|ones))\b)'
310+
311+
def to_cardinal(self, value):
312+
result = super(Num2Word_ES, self).to_cardinal(value)
313+
result = re.sub(r'\bveintiuno' + self._APOCOPE_SCALE, 'veintiún',
314+
result)
315+
result = re.sub(r'\buno' + self._APOCOPE_SCALE, 'un', result)
316+
return result
317+
305318
def to_ordinal(self, value, gender='m'):
306319
gender_stem = 'a' if gender == 'f' else 'o'
307320

tests/test_es.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,14 @@
8484
(100000000000000, 'cien billones'),
8585
(1000000000000000000, 'un trillón'),
8686
(1000000000000000000000, 'mil trillones'),
87-
(10000000000000000000000000, 'diez cuatrillones')
87+
(10000000000000000000000000, 'diez cuatrillones'),
88+
# apocope of "uno"/"veintiuno" before mil/millones (issue #515)
89+
(21000, 'veintiún mil'),
90+
(31000, 'treinta y un mil'),
91+
(101000, 'ciento un mil'),
92+
(121000, 'ciento veintiún mil'),
93+
(21000000, 'veintiún millones'),
94+
(21000000000, 'veintiún mil millones'),
8895
)
8996

9097
TEST_CASES_ORDINAL = (

0 commit comments

Comments
 (0)