From 74b80835fa90fb4fb49702283121fe5747103491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20J=C3=A4rventaus?= Date: Wed, 24 Jun 2026 13:58:51 +0300 Subject: [PATCH 1/2] Improve formatnum parserfn --- src/wikitextprocessor/parserfns.py | 8 ++++++++ tests/test_wikiprocess.py | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/wikitextprocessor/parserfns.py b/src/wikitextprocessor/parserfns.py index 796e779d..11723dc2 100644 --- a/src/wikitextprocessor/parserfns.py +++ b/src/wikitextprocessor/parserfns.py @@ -586,12 +586,20 @@ def ucfirst_fn( return capitalizeFirstOnly(t) +ALLOWED = {".", ",", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"} + + def formatnum_fn( ctx: "Wtp", fn_name: str, args: list[str], expander: Callable[[str], str] ) -> str: """Implements the formatnum parser function.""" arg0 = expander(args[0]).strip() if args else "" + if arg0 == "" or not (set(arg0) <= ALLOWED) or arg0.count(".") > 1: + return arg0 arg1 = expander(args[1]).strip() if len(args) >= 2 else "" + if "," in arg0: + if arg1 != "R": + return arg0 if arg1 == "R": # Reverse formatting # XXX this is a very simplified implementation, should handle more cases diff --git a/tests/test_wikiprocess.py b/tests/test_wikiprocess.py index 58b5ebfa..632b66c1 100644 --- a/tests/test_wikiprocess.py +++ b/tests/test_wikiprocess.py @@ -608,6 +608,30 @@ def test_formatnum9(self): def test_formatnum10(self): self.parserfn("{{formatnum:12345}}", "12,345") + def test_formatnum11(self): + # only numerals + . + , + self.parserfn("{{formatnum:µB}}", "µB") + + def test_formatnum12(self): + # no bad decimals + self.parserfn("{{formatnum:123.4.5}}", "123.4.5") + + def test_formatnum13(self): + # no spaces + self.parserfn("{{formatnum:123 4.5}}", "123 4.5") + + def test_formatnum13_b(self): + # ... except a the start and end + self.parserfn("{{formatnum: 1234.5 }}", "1,234.5") + + def test_formatnum14(self): + # bad commas allowed when |R|eversing + self.parserfn("{{formatnum:123,4.5|R}}", "1234.5") + + def test_formatnum15(self): + # commas in decimals allowed when |R|eversing + self.parserfn("{{formatnum:1234.5,4|R}}", "1234.54") + def test_dateformat1(self): self.parserfn("{{#dateformat:25 dec 2009|ymd}}", "2009 Dec 25") From ba36b4f09b2cade57c41236527ed5533161976f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20J=C3=A4rventaus?= Date: Wed, 1 Jul 2026 08:15:20 +0300 Subject: [PATCH 2/2] Implement partial localization (not alternative digits) for `formatnum` This does not implement "alternative" digits, like in South Asian scripts or West Arabic Numerals, because I didn't find a good authorative way to do it in Python. In the current version of Python, there *SHOULD BE*, but isn't because it's bugged. locale.ALT_DIGITS data (well locale.ALT_DIGITS is a flag that is used to get the data from somewhere else...) is broken, and even if it was broken it contains weird data (the first 0..99 ways to write positive integers in that script), which doesn't tell us whether the localization should use those alternative digits when doing number localization... This needs to be checked later in a later version of Python, but the whole locale module stuff is just weird stuff inherited from Posix and C. --- src/wikitextprocessor/core.py | 48 +++++++- .../data/af/localization.json | 8 ++ .../data/am/localization.json | 8 ++ .../data/as/localization.json | 9 ++ .../data/az/localization.json | 8 ++ .../data/be-x-old/localization.json | 8 ++ .../data/be/localization.json | 8 ++ .../data/bg/localization.json | 8 ++ .../data/br/localization.json | 8 ++ .../data/bs/localization.json | 5 + .../data/ca/localization.json | 8 ++ .../data/cs/localization.json | 8 ++ .../data/cy/localization.json | 8 ++ .../data/da/localization.json | 8 ++ .../data/de/localization.json | 8 ++ .../data/el/localization.json | 5 + .../data/en/localization.json | 8 ++ .../data/eo/localization.json | 5 + .../data/es/localization.json | 8 ++ .../data/et/localization.json | 8 ++ .../data/eu/localization.json | 8 ++ .../data/fa/localization.json | 8 ++ .../data/fi/localization.json | 8 ++ .../data/fo/localization.json | 8 ++ .../data/fr/localization.json | 8 ++ .../data/ga/localization.json | 8 ++ .../data/gd/localization.json | 8 ++ .../data/gl/localization.json | 5 + .../data/gv/localization.json | 8 ++ .../data/he/localization.json | 8 ++ .../data/hi/localization.json | 9 ++ .../data/hr/localization.json | 8 ++ .../data/hu/localization.json | 8 ++ .../data/id/localization.json | 8 ++ .../data/is/localization.json | 8 ++ .../data/it/localization.json | 8 ++ .../data/iu/localization.json | 8 ++ .../data/ja/localization.json | 8 ++ .../data/ka/localization.json | 8 ++ .../data/kl/localization.json | 8 ++ .../data/kn/localization.json | 9 ++ .../data/ko/localization.json | 8 ++ .../data/ks/localization.json | 9 ++ .../data/kw/localization.json | 8 ++ .../data/ky/localization.json | 8 ++ .../data/lo/localization.json | 8 ++ .../data/lt/localization.json | 8 ++ .../data/lv/localization.json | 8 ++ .../data/mi/localization.json | 8 ++ .../data/mk/localization.json | 8 ++ .../data/ml/localization.json | 9 ++ .../data/mr/localization.json | 9 ++ .../data/ms/localization.json | 8 ++ .../data/mt/localization.json | 8 ++ .../data/nl/localization.json | 8 ++ .../data/nn/localization.json | 8 ++ .../data/nso/localization.json | 8 ++ .../data/oc/localization.json | 8 ++ .../data/or/localization.json | 9 ++ .../data/pa/localization.json | 9 ++ .../data/pl/localization.json | 8 ++ .../data/pt/localization.json | 5 + .../data/ro/localization.json | 8 ++ .../data/ru/localization.json | 8 ++ .../data/rw/localization.json | 5 + .../data/sd/localization.json | 9 ++ .../data/sh/localization.json | 5 + .../data/si/localization.json | 8 ++ .../data/sk/localization.json | 8 ++ .../data/sl/localization.json | 5 + .../data/sq/localization.json | 8 ++ .../data/sr/localization.json | 5 + .../data/ss/localization.json | 8 ++ .../data/st/localization.json | 8 ++ .../data/sv/localization.json | 8 ++ .../data/ta/localization.json | 9 ++ .../data/te/localization.json | 9 ++ .../data/tg/localization.json | 8 ++ .../data/th/localization.json | 8 ++ .../data/tl/localization.json | 8 ++ .../data/tn/localization.json | 8 ++ .../data/tr/localization.json | 8 ++ .../data/ts/localization.json | 8 ++ .../data/tt/localization.json | 8 ++ .../data/uk/localization.json | 8 ++ .../data/ur/localization.json | 8 ++ .../data/uz/localization.json | 8 ++ .../data/ve/localization.json | 8 ++ .../data/vi/localization.json | 8 ++ .../data/wa/localization.json | 8 ++ .../data/xh/localization.json | 8 ++ .../data/yi/localization.json | 8 ++ .../data/zh-classical/localization.json | 8 ++ .../data/zh-min-nan/localization.json | 8 ++ .../data/zh-yue/localization.json | 8 ++ .../data/zh/localization.json | 8 ++ .../data/zu/localization.json | 8 ++ src/wikitextprocessor/parserfns.py | 115 +++++++++++++++--- tests/test_wikiprocess.py | 32 +++++ tools/dump_locale_data.py | 105 ++++++++++++++++ 100 files changed, 1032 insertions(+), 20 deletions(-) create mode 100644 src/wikitextprocessor/data/af/localization.json create mode 100644 src/wikitextprocessor/data/am/localization.json create mode 100644 src/wikitextprocessor/data/as/localization.json create mode 100644 src/wikitextprocessor/data/az/localization.json create mode 100644 src/wikitextprocessor/data/be-x-old/localization.json create mode 100644 src/wikitextprocessor/data/be/localization.json create mode 100644 src/wikitextprocessor/data/bg/localization.json create mode 100644 src/wikitextprocessor/data/br/localization.json create mode 100644 src/wikitextprocessor/data/bs/localization.json create mode 100644 src/wikitextprocessor/data/ca/localization.json create mode 100644 src/wikitextprocessor/data/cs/localization.json create mode 100644 src/wikitextprocessor/data/cy/localization.json create mode 100644 src/wikitextprocessor/data/da/localization.json create mode 100644 src/wikitextprocessor/data/de/localization.json create mode 100644 src/wikitextprocessor/data/el/localization.json create mode 100644 src/wikitextprocessor/data/en/localization.json create mode 100644 src/wikitextprocessor/data/eo/localization.json create mode 100644 src/wikitextprocessor/data/es/localization.json create mode 100644 src/wikitextprocessor/data/et/localization.json create mode 100644 src/wikitextprocessor/data/eu/localization.json create mode 100644 src/wikitextprocessor/data/fa/localization.json create mode 100644 src/wikitextprocessor/data/fi/localization.json create mode 100644 src/wikitextprocessor/data/fo/localization.json create mode 100644 src/wikitextprocessor/data/fr/localization.json create mode 100644 src/wikitextprocessor/data/ga/localization.json create mode 100644 src/wikitextprocessor/data/gd/localization.json create mode 100644 src/wikitextprocessor/data/gl/localization.json create mode 100644 src/wikitextprocessor/data/gv/localization.json create mode 100644 src/wikitextprocessor/data/he/localization.json create mode 100644 src/wikitextprocessor/data/hi/localization.json create mode 100644 src/wikitextprocessor/data/hr/localization.json create mode 100644 src/wikitextprocessor/data/hu/localization.json create mode 100644 src/wikitextprocessor/data/id/localization.json create mode 100644 src/wikitextprocessor/data/is/localization.json create mode 100644 src/wikitextprocessor/data/it/localization.json create mode 100644 src/wikitextprocessor/data/iu/localization.json create mode 100644 src/wikitextprocessor/data/ja/localization.json create mode 100644 src/wikitextprocessor/data/ka/localization.json create mode 100644 src/wikitextprocessor/data/kl/localization.json create mode 100644 src/wikitextprocessor/data/kn/localization.json create mode 100644 src/wikitextprocessor/data/ko/localization.json create mode 100644 src/wikitextprocessor/data/ks/localization.json create mode 100644 src/wikitextprocessor/data/kw/localization.json create mode 100644 src/wikitextprocessor/data/ky/localization.json create mode 100644 src/wikitextprocessor/data/lo/localization.json create mode 100644 src/wikitextprocessor/data/lt/localization.json create mode 100644 src/wikitextprocessor/data/lv/localization.json create mode 100644 src/wikitextprocessor/data/mi/localization.json create mode 100644 src/wikitextprocessor/data/mk/localization.json create mode 100644 src/wikitextprocessor/data/ml/localization.json create mode 100644 src/wikitextprocessor/data/mr/localization.json create mode 100644 src/wikitextprocessor/data/ms/localization.json create mode 100644 src/wikitextprocessor/data/mt/localization.json create mode 100644 src/wikitextprocessor/data/nl/localization.json create mode 100644 src/wikitextprocessor/data/nn/localization.json create mode 100644 src/wikitextprocessor/data/nso/localization.json create mode 100644 src/wikitextprocessor/data/oc/localization.json create mode 100644 src/wikitextprocessor/data/or/localization.json create mode 100644 src/wikitextprocessor/data/pa/localization.json create mode 100644 src/wikitextprocessor/data/pl/localization.json create mode 100644 src/wikitextprocessor/data/pt/localization.json create mode 100644 src/wikitextprocessor/data/ro/localization.json create mode 100644 src/wikitextprocessor/data/ru/localization.json create mode 100644 src/wikitextprocessor/data/rw/localization.json create mode 100644 src/wikitextprocessor/data/sd/localization.json create mode 100644 src/wikitextprocessor/data/sh/localization.json create mode 100644 src/wikitextprocessor/data/si/localization.json create mode 100644 src/wikitextprocessor/data/sk/localization.json create mode 100644 src/wikitextprocessor/data/sl/localization.json create mode 100644 src/wikitextprocessor/data/sq/localization.json create mode 100644 src/wikitextprocessor/data/sr/localization.json create mode 100644 src/wikitextprocessor/data/ss/localization.json create mode 100644 src/wikitextprocessor/data/st/localization.json create mode 100644 src/wikitextprocessor/data/sv/localization.json create mode 100644 src/wikitextprocessor/data/ta/localization.json create mode 100644 src/wikitextprocessor/data/te/localization.json create mode 100644 src/wikitextprocessor/data/tg/localization.json create mode 100644 src/wikitextprocessor/data/th/localization.json create mode 100644 src/wikitextprocessor/data/tl/localization.json create mode 100644 src/wikitextprocessor/data/tn/localization.json create mode 100644 src/wikitextprocessor/data/tr/localization.json create mode 100644 src/wikitextprocessor/data/ts/localization.json create mode 100644 src/wikitextprocessor/data/tt/localization.json create mode 100644 src/wikitextprocessor/data/uk/localization.json create mode 100644 src/wikitextprocessor/data/ur/localization.json create mode 100644 src/wikitextprocessor/data/uz/localization.json create mode 100644 src/wikitextprocessor/data/ve/localization.json create mode 100644 src/wikitextprocessor/data/vi/localization.json create mode 100644 src/wikitextprocessor/data/wa/localization.json create mode 100644 src/wikitextprocessor/data/xh/localization.json create mode 100644 src/wikitextprocessor/data/yi/localization.json create mode 100644 src/wikitextprocessor/data/zh-classical/localization.json create mode 100644 src/wikitextprocessor/data/zh-min-nan/localization.json create mode 100644 src/wikitextprocessor/data/zh-yue/localization.json create mode 100644 src/wikitextprocessor/data/zh/localization.json create mode 100644 src/wikitextprocessor/data/zu/localization.json create mode 100644 tools/dump_locale_data.py diff --git a/src/wikitextprocessor/core.py b/src/wikitextprocessor/core.py index 3ce00067..5c3e4cd9 100644 --- a/src/wikitextprocessor/core.py +++ b/src/wikitextprocessor/core.py @@ -74,6 +74,16 @@ total=True, # fields are obligatory ) +LocalizationData = TypedDict( + "LocalizationData", + { + "decimal_point": str, + "grouping_separator": str, + "grouping_method": tuple[int, ...], + }, + total=True, +) + JsonValues = Union[str, int, float, list, dict, bool, None] # Can't specify _LuaTable contents further, so no use specifying the Dict either ParentData = tuple[str, Union["_LuaTable", dict[Union[int, str], str]]] @@ -265,6 +275,8 @@ class Wtp: "suppress_special", # XXX never set to True??? "data_folder", "NAMESPACE_DATA", + "LOCALIZATION_DATA", + "LOCALIZATION_ALLOWED_REVERSABLE_NUMBER_CHARS", "LOCAL_NS_NAME_BY_ID", # Local namespace names dictionary "NS_ID_BY_LOCAL_NAME", "lang_code", @@ -322,8 +334,9 @@ def __init__( self.expand_stack: list[str] = [] # XXX: this has a confusing name self.parser_stack: list["WikiNode"] = [] self.lang_code = lang_code # dump file language code - self.data_folder = files("wikitextprocessor") / "data" / lang_code + self.init_data_folder() self.init_namespace_data() + self.init_localization_data() self.create_db() self.template_override_funcs = template_override_funcs self.beginning_of_line = False @@ -496,6 +509,39 @@ def init_namespace_data(self) -> None: for data in self.NAMESPACE_DATA.values() } + def init_localization_data(self) -> None: + loc_path = self.data_folder.joinpath("localization.json") + if not loc_path.is_file(): + # default localization + self.LOCALIZATION_DATA: LocalizationData = { + "decimal_point": ".", + "grouping_separator": ",", + "grouping_method": (3, 0), + } + self.LOCALIZATION_ALLOWED_REVERSABLE_NUMBER_CHARS: set[str] = set( + ",.0123456789" + ) + return + with loc_path.open(encoding="utf-8") as f: + self.LOCALIZATION_DATA = json.load(f) + + self.LOCALIZATION_ALLOWED_REVERSABLE_NUMBER_CHARS = set( + # XXX this could also be other numeral characters + # locale.ALT_DIGITS is buggy in our version of Python, + # check later if it's usable. + "1234567890" + + self.LOCALIZATION_DATA["decimal_point"] + + self.LOCALIZATION_DATA["grouping_separator"] + + ( + " " + if self.LOCALIZATION_DATA["grouping_separator"] == "\xa0" + else "" + ), + ) + + def init_data_folder(self) -> None: + self.data_folder = files("wikitextprocessor") / "data" / self.lang_code + def _fmt_errmsg(self, kind: str, msg: str, trace: Optional[str]) -> None: if self.quiet_output: return diff --git a/src/wikitextprocessor/data/af/localization.json b/src/wikitextprocessor/data/af/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/af/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/am/localization.json b/src/wikitextprocessor/data/am/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/am/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/as/localization.json b/src/wikitextprocessor/data/as/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/as/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/az/localization.json b/src/wikitextprocessor/data/az/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/az/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/be-x-old/localization.json b/src/wikitextprocessor/data/be-x-old/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/be-x-old/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/be/localization.json b/src/wikitextprocessor/data/be/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/be/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/bg/localization.json b/src/wikitextprocessor/data/bg/localization.json new file mode 100644 index 00000000..8544e952 --- /dev/null +++ b/src/wikitextprocessor/data/bg/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/br/localization.json b/src/wikitextprocessor/data/br/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/br/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/bs/localization.json b/src/wikitextprocessor/data/bs/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/bs/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ca/localization.json b/src/wikitextprocessor/data/ca/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/ca/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/cs/localization.json b/src/wikitextprocessor/data/cs/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/cs/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/cy/localization.json b/src/wikitextprocessor/data/cy/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/cy/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/da/localization.json b/src/wikitextprocessor/data/da/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/da/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/de/localization.json b/src/wikitextprocessor/data/de/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/de/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/el/localization.json b/src/wikitextprocessor/data/el/localization.json new file mode 100644 index 00000000..224e9aac --- /dev/null +++ b/src/wikitextprocessor/data/el/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/en/localization.json b/src/wikitextprocessor/data/en/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/en/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/eo/localization.json b/src/wikitextprocessor/data/eo/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/eo/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/es/localization.json b/src/wikitextprocessor/data/es/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/es/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/et/localization.json b/src/wikitextprocessor/data/et/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/et/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/eu/localization.json b/src/wikitextprocessor/data/eu/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/eu/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/fa/localization.json b/src/wikitextprocessor/data/fa/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/fa/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/fi/localization.json b/src/wikitextprocessor/data/fi/localization.json new file mode 100644 index 00000000..c8eb17b9 --- /dev/null +++ b/src/wikitextprocessor/data/fi/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/fo/localization.json b/src/wikitextprocessor/data/fo/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/fo/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/fr/localization.json b/src/wikitextprocessor/data/fr/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/fr/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ga/localization.json b/src/wikitextprocessor/data/ga/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ga/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/gd/localization.json b/src/wikitextprocessor/data/gd/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/gd/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/gl/localization.json b/src/wikitextprocessor/data/gl/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/gl/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/gv/localization.json b/src/wikitextprocessor/data/gv/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/gv/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/he/localization.json b/src/wikitextprocessor/data/he/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/he/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/hi/localization.json b/src/wikitextprocessor/data/hi/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/hi/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/hr/localization.json b/src/wikitextprocessor/data/hr/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/hr/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/hu/localization.json b/src/wikitextprocessor/data/hu/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/hu/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/id/localization.json b/src/wikitextprocessor/data/id/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/id/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/is/localization.json b/src/wikitextprocessor/data/is/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/is/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/it/localization.json b/src/wikitextprocessor/data/it/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/it/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/iu/localization.json b/src/wikitextprocessor/data/iu/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/iu/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ja/localization.json b/src/wikitextprocessor/data/ja/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ja/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ka/localization.json b/src/wikitextprocessor/data/ka/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/ka/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/kl/localization.json b/src/wikitextprocessor/data/kl/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/kl/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/kn/localization.json b/src/wikitextprocessor/data/kn/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/kn/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ko/localization.json b/src/wikitextprocessor/data/ko/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ko/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ks/localization.json b/src/wikitextprocessor/data/ks/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/ks/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/kw/localization.json b/src/wikitextprocessor/data/kw/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/kw/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ky/localization.json b/src/wikitextprocessor/data/ky/localization.json new file mode 100644 index 00000000..c8eb17b9 --- /dev/null +++ b/src/wikitextprocessor/data/ky/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/lo/localization.json b/src/wikitextprocessor/data/lo/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/lo/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/lt/localization.json b/src/wikitextprocessor/data/lt/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/lt/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/lv/localization.json b/src/wikitextprocessor/data/lv/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/lv/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/mi/localization.json b/src/wikitextprocessor/data/mi/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/mi/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/mk/localization.json b/src/wikitextprocessor/data/mk/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/mk/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ml/localization.json b/src/wikitextprocessor/data/ml/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/ml/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/mr/localization.json b/src/wikitextprocessor/data/mr/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/mr/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ms/localization.json b/src/wikitextprocessor/data/ms/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ms/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/mt/localization.json b/src/wikitextprocessor/data/mt/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/mt/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/nl/localization.json b/src/wikitextprocessor/data/nl/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/nl/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/nn/localization.json b/src/wikitextprocessor/data/nn/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/nn/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/nso/localization.json b/src/wikitextprocessor/data/nso/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/nso/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/oc/localization.json b/src/wikitextprocessor/data/oc/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/oc/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/or/localization.json b/src/wikitextprocessor/data/or/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/or/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/pa/localization.json b/src/wikitextprocessor/data/pa/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/pa/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/pl/localization.json b/src/wikitextprocessor/data/pl/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/pl/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/pt/localization.json b/src/wikitextprocessor/data/pt/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/pt/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ro/localization.json b/src/wikitextprocessor/data/ro/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/ro/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ru/localization.json b/src/wikitextprocessor/data/ru/localization.json new file mode 100644 index 00000000..c8eb17b9 --- /dev/null +++ b/src/wikitextprocessor/data/ru/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/rw/localization.json b/src/wikitextprocessor/data/rw/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/rw/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sd/localization.json b/src/wikitextprocessor/data/sd/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/sd/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sh/localization.json b/src/wikitextprocessor/data/sh/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/sh/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/si/localization.json b/src/wikitextprocessor/data/si/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/si/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sk/localization.json b/src/wikitextprocessor/data/sk/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/sk/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sl/localization.json b/src/wikitextprocessor/data/sl/localization.json new file mode 100644 index 00000000..224e9aac --- /dev/null +++ b/src/wikitextprocessor/data/sl/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sq/localization.json b/src/wikitextprocessor/data/sq/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/sq/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sr/localization.json b/src/wikitextprocessor/data/sr/localization.json new file mode 100644 index 00000000..70656132 --- /dev/null +++ b/src/wikitextprocessor/data/sr/localization.json @@ -0,0 +1,5 @@ +{ + "decimal_point": ",", + "grouping_method": [], + "grouping_separator": "" +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ss/localization.json b/src/wikitextprocessor/data/ss/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ss/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/st/localization.json b/src/wikitextprocessor/data/st/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/st/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/sv/localization.json b/src/wikitextprocessor/data/sv/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/sv/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ta/localization.json b/src/wikitextprocessor/data/ta/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/ta/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/te/localization.json b/src/wikitextprocessor/data/te/localization.json new file mode 100644 index 00000000..1db2947d --- /dev/null +++ b/src/wikitextprocessor/data/te/localization.json @@ -0,0 +1,9 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 2, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/tg/localization.json b/src/wikitextprocessor/data/tg/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/tg/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/th/localization.json b/src/wikitextprocessor/data/th/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/th/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/tl/localization.json b/src/wikitextprocessor/data/tl/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/tl/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/tn/localization.json b/src/wikitextprocessor/data/tn/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/tn/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/tr/localization.json b/src/wikitextprocessor/data/tr/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/tr/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ts/localization.json b/src/wikitextprocessor/data/ts/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ts/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/tt/localization.json b/src/wikitextprocessor/data/tt/localization.json new file mode 100644 index 00000000..c8eb17b9 --- /dev/null +++ b/src/wikitextprocessor/data/tt/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/uk/localization.json b/src/wikitextprocessor/data/uk/localization.json new file mode 100644 index 00000000..004579f1 --- /dev/null +++ b/src/wikitextprocessor/data/uk/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ur/localization.json b/src/wikitextprocessor/data/ur/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ur/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/uz/localization.json b/src/wikitextprocessor/data/uz/localization.json new file mode 100644 index 00000000..c8eb17b9 --- /dev/null +++ b/src/wikitextprocessor/data/uz/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": " " +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/ve/localization.json b/src/wikitextprocessor/data/ve/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/ve/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/vi/localization.json b/src/wikitextprocessor/data/vi/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/vi/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/wa/localization.json b/src/wikitextprocessor/data/wa/localization.json new file mode 100644 index 00000000..e978bf0d --- /dev/null +++ b/src/wikitextprocessor/data/wa/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ",", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "." +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/xh/localization.json b/src/wikitextprocessor/data/xh/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/xh/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/yi/localization.json b/src/wikitextprocessor/data/yi/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/yi/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/zh-classical/localization.json b/src/wikitextprocessor/data/zh-classical/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/zh-classical/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/zh-min-nan/localization.json b/src/wikitextprocessor/data/zh-min-nan/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/zh-min-nan/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/zh-yue/localization.json b/src/wikitextprocessor/data/zh-yue/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/zh-yue/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/zh/localization.json b/src/wikitextprocessor/data/zh/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/zh/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/data/zu/localization.json b/src/wikitextprocessor/data/zu/localization.json new file mode 100644 index 00000000..fd1c6b72 --- /dev/null +++ b/src/wikitextprocessor/data/zu/localization.json @@ -0,0 +1,8 @@ +{ + "decimal_point": ".", + "grouping_method": [ + 3, + 0 + ], + "grouping_separator": "," +} \ No newline at end of file diff --git a/src/wikitextprocessor/parserfns.py b/src/wikitextprocessor/parserfns.py index 11723dc2..99b0a629 100644 --- a/src/wikitextprocessor/parserfns.py +++ b/src/wikitextprocessor/parserfns.py @@ -586,7 +586,27 @@ def ucfirst_fn( return capitalizeFirstOnly(t) -ALLOWED = {".", ",", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"} +# XXX If we implement different numeral characters (western arabic numerals, +# bengali, etc.) this should be only used for "raw" strings and R)eversable +# strings need to allow for those other numeral characters, and if the R-flag +# is set, those numeral characters (and other things) should be allowed. +# XXX if implementing other numeral chars, check out str.maketrans() and +# translate; the mapping needs to be hardcoded or a separate config file, +# because I haven't found any sensible standard library thing for this. +ALLOWED_FORMATNUM_CHARS_NOT_R = { + ".", + ",", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "0", +} def formatnum_fn( @@ -594,35 +614,92 @@ def formatnum_fn( ) -> str: """Implements the formatnum parser function.""" arg0 = expander(args[0]).strip() if args else "" - if arg0 == "" or not (set(arg0) <= ALLOWED) or arg0.count(".") > 1: - return arg0 arg1 = expander(args[1]).strip() if len(args) >= 2 else "" - if "," in arg0: - if arg1 != "R": - return arg0 + if arg1 == "R": - # Reverse formatting - # XXX this is a very simplified implementation, should handle more cases - return arg0.replace(",", "") + return _formatnum_reverse(ctx, arg0) + + if ( + arg0 == "" + # <= is a set subset comparison, for those of you who + # don't know (like me, who wrote this piece of code) + or not (set(arg0) <= ALLOWED_FORMATNUM_CHARS_NOT_R) + or arg0.count(".") > 1 + ): + return arg0 + if arg1 == "NOSEP": sep = "" else: - sep = "," - comma = "." # Really should depend on locale + sep = ctx.LOCALIZATION_DATA["grouping_separator"] + + if sep in arg0: + # separator only allowed when R)eversing + return arg0 + + decimal_point = ctx.LOCALIZATION_DATA["decimal_point"] # XXX implement support for non-english locales for digits - orig = arg0.split(".") + orig = arg0.split(".") # remember, raw input strungs "." always decimal first = orig[0] - parts = [] - first = "".join(reversed(first)) - for i in range(0, len(first), 3): - parts.append("".join(reversed(first[i : i + 3]))) - parts = [sep.join(reversed(parts))] + + parts: list[str] = [] + # Tuple with ints, usually (3, 0). + # (2, 2, 2, 3, 0) means "first do three groups of 2 and then a group of 3; + # at 0, just start repeating the previous group. + # TECHNICALLY the docs/specs say that instead of ending with a "0" this + # could end with locale. + algo = ctx.LOCALIZATION_DATA["grouping_method"] + if len(algo) > 0: + first = "".join(reversed(first)) + i = 0 + algo_i = 0 + group_size = algo[algo_i] + while i < len(first): + parts.append("".join(reversed(first[i : i + group_size]))) + i += group_size + if algo_i + 1 < len(algo): + algo_i += 1 + if algo[algo_i] > 0: + group_size = algo[algo_i] + # for i in range(0, len(first), 3): + # parts.append("".join(reversed(first[i : i + 3]))) + parts = [sep.join(reversed(parts))] + else: + parts = [first] + if len(orig) > 1: - parts.append(comma) - parts.append(".".join(orig[1:])) + parts.append(decimal_point) + parts.extend(orig[1:]) + return "".join(parts) +def _formatnum_reverse(ctx: "Wtp", arg0: str) -> str: + # Reverse formatting + # XXX this is a very simplified implementation, should handle more cases + decimal = ctx.LOCALIZATION_DATA["decimal_point"] + if ( + arg0 == "" + # <= is a set subset comparison, for those of you who + # don't know (like me, who wrote this piece of code) + or not (set(arg0) <= ctx.LOCALIZATION_ALLOWED_REVERSABLE_NUMBER_CHARS) + or arg0.count(decimal) > 1 + ): + return arg0 + + sep = ctx.LOCALIZATION_DATA["grouping_separator"] + + # XXX implement other numeral systems, like west arabic or bengali + + # Kludge for French; the locale data has non-breaking spaces as the + # separators, but it seems clear we must also allow normal spaces + if sep == "\xa0": # non-breaking space + return arg0.replace(decimal, ".").replace(sep, "").replace(" ", "") + + # Currently only doing the minimum by removing thousand separators + return arg0.replace(decimal, ".").replace(sep, "") + + def dateformat_fn( ctx: "Wtp", fn_name: str, args: list[str], expander: Callable[[str], str] ) -> str: diff --git a/tests/test_wikiprocess.py b/tests/test_wikiprocess.py index 632b66c1..f900ae1c 100644 --- a/tests/test_wikiprocess.py +++ b/tests/test_wikiprocess.py @@ -632,6 +632,38 @@ def test_formatnum15(self): # commas in decimals allowed when |R|eversing self.parserfn("{{formatnum:1234.5,4|R}}", "1234.54") + def test_formatnum_fr_locale_1(self): + self.ctx.lang_code = "fr" + self.ctx.init_data_folder() + self.ctx.init_localization_data() + self.parserfn("{{formatnum:1234.54}}", "1\xa0234,54") + + def test_formatnum_fr_locale_2(self): + self.ctx.lang_code = "fr" + self.ctx.init_data_folder() + self.ctx.init_localization_data() + self.parserfn("{{formatnum:1 234,54|R}}", "1234.54") + + def test_formatnum_fr_locale_3(self): + # French locale data has non-breaking space as the numeral separator, + # which has a separate kludge so that normal space works too. + self.ctx.lang_code = "fr" + self.ctx.init_data_folder() + self.ctx.init_localization_data() + self.parserfn("{{formatnum:1\xa0234,54|R}}", "1234.54") + + def test_formatnum_hi_locale_1(self): + self.ctx.lang_code = "hi" + self.ctx.init_data_folder() + self.ctx.init_localization_data() + self.parserfn("{{formatnum:123456789.0123}}", "12,34,56,789.0123") + + def test_formatnum_hi_locale_2(self): + self.ctx.lang_code = "hi" + self.ctx.init_data_folder() + self.ctx.init_localization_data() + self.parserfn("{{formatnum:12,34,56,789.0123|R}}", "123456789.0123") + def test_dateformat1(self): self.parserfn("{{#dateformat:25 dec 2009|ymd}}", "2009 Dec 25") diff --git a/tools/dump_locale_data.py b/tools/dump_locale_data.py new file mode 100644 index 00000000..c1eec5f1 --- /dev/null +++ b/tools/dump_locale_data.py @@ -0,0 +1,105 @@ +import argparse +import json +import locale +import os +import pathlib + +from wikitextprocessor.core import LocalizationData + +parser = argparse.ArgumentParser( + description="Generate config files for locale stuff" +) +parser.add_argument( + "langdirs", + type=pathlib.Path, + help="Directory containing language configuration " + "directories, usually 'src/wikitextprocessor/data/...'." + "This is used as input to determine what language codes " + "need to have configs generated for them.", +) + +parser.add_argument( + "outputdir", + type=pathlib.Path, + help="Directory where individual directories named " + "by language code ('en/', 'de/' etc.) are outputted. " + "Recommended not to use src/wikitextprocessor/data " + "directly, but to copy-paste into that directory later.", +) +args = parser.parse_args() + + +def main() -> None: + # get the names (lang-codes) of the config directories + dirs = sorted([f.name for f in os.scandir(args.langdirs) if f.is_dir()]) + # print(dirs) + + # list of language-code -> locale code + # map. Based on your system, yet many of these locale codes fail + aliases = locale.locale_alias + + configs: dict[str, LocalizationData] = {} + + for dir_code in dirs: + main_code = dir_code.split("-")[0] + if dir_code not in aliases and main_code not in aliases: + continue + if dir_code not in aliases: + lang_code = main_code + else: + lang_code = dir_code + + alias = aliases[lang_code] + utf8ed = alias.split(".")[0] + ".UTF-8" + failed = True + plog = [] + for x in (alias, utf8ed): + try: + locale.setlocale(locale.LC_ALL, x) + failed = False + plog.append(f"{x=} succeeded") + break + except Exception as e: + plog.append(f"Failed {e=} for {x=}") + + if failed: + plog.append( + f"BOTH FAILED {dir_code=} {alias=}, {utf8ed=}; no " + "config file will be generated" + ) + print("[[" + "\n".join(plog) + "]]") + if failed: + continue + + envv = locale.localeconv() + sep: str = envv["thousands_sep"] # type: ignore + decimal: str = envv["decimal_point"] # type: ignore + grouping: tuple[int] = tuple(envv["grouping"]) # type: ignore + mon_grouping: tuple[int] = tuple(envv["mon_grouping"]) # type:ignore + + # For some reason, for hindi "grouping" and "mon_grouping" are + # different, so we will use the "non-default" one. + if grouping != mon_grouping: + if grouping == (3, 0): + grouping = mon_grouping + + configs[dir_code] = { + "decimal_point": decimal, + "grouping_method": tuple(grouping), + "grouping_separator": sep, + } + + for dirname, locdata in configs.items(): + data_folder = args.outputdir / dirname + if not data_folder.exists(): + data_folder.mkdir() + with open( + data_folder / "localization.json", + mode="w", + encoding="utf-8", + ) as f: + json.dump(locdata, f, ensure_ascii=False, indent=2) + + +if __name__ == "__main__": + main()