Commit Graph
61 Commits
Author SHA1 Message Date
Dylan M. Taylor 3e5b5ecb60 i18n: keep fold search, isolate wrapping and locale fallbacks linear (#539)
* i18n: keep fold search, isolate wrapping and locale fallbacks linear

- Folded::matches restarted str::find one character past every occurrence
  turned down at a combining mark, so overlapping occurrences of a long
  needle cost haystack x needle. It now finds every occurrence, overlapping
  ones included, in one Knuth-Morris-Pratt pass and checks the boundaries
  as before.
- wrap searched the whole open-control stack for an isolate at every PDI;
  it now keeps a count of open isolates.
- candidates made one joined prefix per subtag of a locale tag of any
  length; a tag longer than 128 bytes is not a locale and has none.

* address review: length check only on the public candidates entry
2026-11-11 06:17:52 -05:00
aiongg 02eb391d39 Merge #202: i18n: parse_number for typed and pasted numbers
# Conflicts:
#	crates/i18n/README.md
2026-10-24 02:26:12 +00:00
aiongg a8b8fbd5a8 i18n: the RTL unit test sets its number format, as the region now decides digits 2026-10-24 02:26:04 +00:00
aiongg 5f4c39ea94 i18n: a region-formatted count is a left-to-right isolate in RTL wordings; trn_plain has no marks 2026-10-24 02:26:04 +00:00
aiongg aaf9f29e4f Merge #210: i18n: numbers for a region on ICU4X, locale digits in counts and sizes
# Conflicts:
#	Cargo.lock
#	crates/i18n/Cargo.toml
#	crates/i18n/README.md
#	crates/i18n/src/lib.rs
2026-10-24 02:25:57 +00:00
aiongg fa78cb52a5 Merge #206: craft-i18n: search folding and locale sorting
# Conflicts:
#	crates/i18n/Cargo.toml
#	crates/i18n/src/lib.rs
2026-10-24 02:25:27 +00:00
aiongg 7cb4a73b3c i18n: file sizes and measures fill {n} as a left-to-right isolate 2026-10-24 02:20:40 +00:00
aiongg c465dd3f47 Merge #204: i18n: file sizes and measures with translatable unit names
# Conflicts:
#	crates/i18n/README.md
#	crates/i18n/src/lib.rs
2026-10-24 02:20:40 +00:00
aiongg 1faeabfead Merge #203: i18n: formatting region apart from the interface language
# Conflicts:
#	Cargo.lock
#	crates/i18n/README.md
#	crates/i18n/src/lib.rs
2026-10-24 02:20:33 +00:00
aiongg 93b7b34f2f Merge upstream main into i18n-isolation 2026-10-24 00:15:07 +00:00
aiongg dd50095dbb Merge upstream main into i18n-scripts
# Conflicts:
#	crates/i18n/README.md
2026-10-23 23:58:43 +00:00
Martin BallandClaude Opus 5.5 f7cc8a7df1 i18n: row-problem log and README name precedence (review)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 22:11:30 +01:00
Martin BallandClaude Opus 5.5 4ecda6fa8c i18n: parse each locale lazily on first lookup
I18n::new keeps the embedded text and parses nothing; a locale's rows
are parsed on the first lookup that reaches it (also as a fallback) and
its bad rows logged with log::warn!. new returns only the locale-level
problems. check_all parses every locale and returns all problems.
name() scans for the language.name row instead of parsing the locale.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 21:11:48 +01:00
aiongg 72a1dc7728 i18n: the shipped-locale collation test checks each locale's own order 2026-10-23 08:15:24 +00:00
aiongg 6ea2d2c7f2 i18n: standalone Hangul jamo are letters in search, not syllable parts 2026-10-23 08:15:24 +00:00
aiongg 3596b2ee8c i18n: round-trip tests for Windows' equal marks, a chosen digit system and the C locale 2026-10-23 05:47:11 +00:00
aiongg b0be5d5155 Merge branch 'i18n-format' into i18n-parse-number 2026-10-23 05:47:11 +00:00
aiongg 5620df6e45 i18n: a system grouping mark equal to the decimal mark is dropped 2026-10-23 05:47:10 +00:00
aiongg cc7020654e i18n: the C locale is A4, metric and ungrouped; a chosen digit system stays in the locale 2026-10-23 05:47:10 +00:00
aiongg 1711202871 Merge branch 'i18n-region' into i18n-format 2026-10-23 05:47:10 +00:00
aiongg 7143c25157 i18n: contain values that carry bidi controls
A value with an embedding, override, isolate or mark (LRE RLE PDF LRO
RLO LRI RLI FSI PDI LRM RLM ALM) makes fmt isolate, even in text with no
right-to-left letter, so an ASCII file name with an RLO can't reorder
the sentence. Embeddings, overrides and isolates a value opens are
closed inside its isolate, and stray PDF and PDI are dropped.
2026-10-21 17:20:34 +00:00
aiongg aaec0e1e5f i18n: Format::number_ungrouped for pixel sizes and years 2026-10-21 06:18:21 +00:00
aiongg 2ff3f11654 i18n: base_direction of a paragraph from its first strong character 2026-10-21 06:13:49 +00:00
aiongg 365f7672b5 i18n: don't match part of a Hangul syllable 2026-10-21 06:07:40 +00:00
aiongg 61db8b71b5 i18n: break collation ties by code point 2026-10-21 06:07:40 +00:00
aiongg 188c313c69 Merge remote-tracking branch 'origin/i18n-format' into i18n-parse-number 2026-10-21 06:07:18 +00:00
aiongg 540dafb9c3 i18n: generate.sh keeps locales.rs when locales.py fails 2026-10-21 06:07:07 +00:00
aiongg 9b4c4350b6 Merge remote-tracking branch 'origin/i18n-region' into i18n-format 2026-10-21 06:07:02 +00:00
aiongg c9013e08c7 i18n: Hani and yue-Hant pick Han forms by region; usual scripts for kk, ky, tg, ku, ms, ug 2026-10-21 06:06:51 +00:00
aiongg 31b5f953ee i18n: plain wording for where Region separators come from 2026-10-21 06:06:44 +00:00
aiongg b7d5394802 i18n: a grouping dot stays grouping beside a system decimal mark 2026-10-21 06:06:29 +00:00
aiongg 56bbf840a7 i18n: strip every isolate mark in fmt_plain 2026-10-21 06:06:08 +00:00
aiongg 502f799716 i18n: han and catalog matching follow region-implied scripts
han(zh-US), zh-AU and the other regions CLDR writes in Traditional
characters give Traditional, and pa-PK picks a pa-arab catalog, never
Gurmukhi pa, as pa-Arab-PK does.
2026-10-21 05:54:12 +00:00
aiongg b010389df2 i18n: Format::parse on the format's own marks; lone decimal marks
Format::parse reads what a Format writes: its digits, its decimal and
grouping separators (the system's included) and the locale's Latin
marks in an Arabic-Indic format, plus every digit set. parse_number is
Format::from_tag(locale).parse, so the decimal marks come from CLDR's
data alone and the hand-made table is gone.

A lone . in a comma locale is the decimal mark when it can't be
grouping (1.5, 0.250, 1234.5, .5); 1.234 and 1.234.567 stay grouped in
German. The same holds for , in a point locale. Percent signs and units
are documented as the caller's to strip.
2026-10-21 05:54:08 +00:00
aiongg 217f108ee0 Merge remote-tracking branch 'origin/i18n-format' into i18n-parse-number
# Conflicts:
#	crates/i18n/src/lib.rs
2026-10-21 05:54:08 +00:00
aiongg 9d636cf6cb Merge remote-tracking branch 'origin/i18n-file-size' into i18n-format
# Conflicts:
#	crates/i18n/src/size.rs
2026-10-21 05:50:09 +00:00
aiongg f2ab6dc7f3 i18n: rewrap the Region README paragraph 2026-10-21 05:49:46 +00:00
aiongg 233e0b7aa0 i18n: plural rules by language, CLDR data for every locale, trn_plain
Plural rules are looked up by language alone: CLDR's parent of sr-Latn
and zh-Hant is the root, whose only category is other, so sr-latn rows
were rejected. The baked data covers every CLDR locale (10 KB): plural
rules for he, ro, nb, ca, sk, th, ms and the rest, and decimal symbols
for nb-NO, sk-SK, bn-BD, ar-MA and English in Europe. Format applies a
Region's separators only where the system set them, and an empty
grouping separator writes none.

trn_plain writes counts in 0-9 without grouping, for documents and file
names. reset_format goes back to the system region. trn_decimal and
Format write infinities and NaN as CLDR does and take the other form.
Tests that don't set a format use en-US, not the machine's region. The
ICU4X crates are pinned to ~2.3, the minor version the data is for.
2026-10-21 05:49:38 +00:00
aiongg 44dbe32226 i18n: glibc names in Collator; fa and hi collation; Persian letters and digits in folding
Collator::new takes sv_SE.UTF-8 and sr_RS@latin. Folding maps every
script's decimal digits to ASCII and, ignoring accents, Persian keheh,
Farsi yeh, alef maksura, teh marbuta and heh with hamza to the Arabic
letters. The collation data grows 4.8 KB (465 bytes gzipped).
2026-10-21 05:45:47 +00:00
aiongg c1f64180c9 i18n: check whole_from after rounding
9,960,000 bytes in DECIMAL with whole_from(10) rounds to 10.0 MB, which
is written 10 MB.
2026-10-21 05:44:52 +00:00
aiongg 01ad4a3b11 Merge remote-tracking branch 'origin/i18n-region' into i18n-format 2026-10-21 05:44:48 +00:00
aiongg 3e4cca9737 i18n: Region separators only where the system sets them; C in LC_* is en-US
Region::decimal and grouping are None unless Windows' or macOS's own
settings set them, so the number locale's CLDR data decides otherwise.
A cleared Windows sThousand is no grouping. LC_ALL=C and LC_NUMERIC=C
(and the other LC_* variables) mean the C locale; only LANG=C gives way
to the preferred language.
2026-10-21 05:44:34 +00:00
aiongg 705e91e183 i18n: isolate only text with a right-to-left letter
fmt and trn add isolates only when the template or an inserted value has
a strong RTL character (bidi class R or AL). Text with none comes out as
before, and a value's own isolate from ltr or isolate is taken off.
2026-10-21 05:44:27 +00:00
aiongg 75b97a9192 i18n: non_exhaustive Script and Han; regions that imply a script
pa-PK, uz-AF and az-IR are written in Arabic and sd-IN in Devanagari, as
CLDR's likely subtags give them. A script subtag still wins.
2026-10-21 05:43:04 +00:00
aiongg cf36f3cb21 i18n: numbers for a region on ICU4X, locale digits in counts and sizes
Format writes integers, decimals and percentages for a Region on ICU4X's
decimal formatter: the locale's digits (Arabic-Indic in Egypt, Persian in
Iran) or Latin ones on request, its separators and grouping sizes (Indian
12,34,567), CLDR's percent patterns, and the region's own separators where
the system sets them. I18n::format holds the one trn, file_size and
measure use, the system region's until set_format.

Plural rules move from intl_pluralrules to ICU4X, and trn_decimal picks
the form from the digits shown (1.0 files, 1,5 файла).

The CLDR data (decimal symbols, digits, plural rules, percent patterns)
covers the shipped languages and their regional variants; data/generate.sh
rebuilds it.
2026-10-21 05:14:23 +00:00
69a4154fb8 craft-i18n: search folding and locale sorting
`Folder` folds text for case- and accent-insensitive search (Turkish and
Azerbaijani i by locale, ß, final sigma, ligatures, full-width forms) and
maps matches back to the original text for highlighting. `Collator`
(feature `collate`) sorts lists in the locale's order with digits compared
by value, on ICU4X with collation data for the shipped locales only.

The Turkish i and sigma handling come from PdfCraft's `fold_case`.

Part of #198.

Co-authored-by: snipeTR <31975916+snipeTR@users.noreply.github.com>
Co-authored-by: nevicia2010-hub <nevicia2010@gmail.com>
2026-10-21 04:56:28 +00:00
aiongg 3f8226ac69 Merge remote-tracking branch 'origin/i18n-region' into i18n-format
# Conflicts:
#	crates/i18n/README.md
#	crates/i18n/src/lib.rs
2026-10-21 04:47:06 +00:00
aiongg 3fcaddbdae i18n: file sizes and measures with translatable unit names
I18n::file_size writes a byte count in steps of 1024 (KB or KiB) or 1000
(KB), with decimals per unit, no decimals from a given value up, a
smallest and largest unit, and bytes as B or in words. I18n::measure
writes any value with a unit template such as "{n} px". Unit names are
catalog rows in context `unit`, keyed by the English template, so a
translation can change the symbol and its spacing.
2026-10-21 04:44:53 +00:00
aiongg 90a5999a1d i18n: parse_number for typed and pasted numbers
Reads any Unicode decimal digits, the locale's decimal mark plus ٫,
grouping by the locale's other mark, spaces, apostrophes or ٬ (threes
or Indian 2-2-3), and -/−/+ signs, ignoring bidi marks. Input that
fits no single reading is an error, not a guess.
2026-10-21 04:44:16 +00:00
ce70b2ede8 i18n: formatting region apart from the interface language
Region holds the number and time locales, metric or US measurement, A4 or
Letter, the decimal separator, and the grouping separator and clock when
the system sets them. Region::system reads Windows' regional format with
the user's changes, Apple's current locale, the POSIX LC_* variables each
on their own, and the preferred language on the web and Android.
Region::from_setting takes an app's saved choice ("auto" or a tag).

Ported from WordCraft's Region (storytold/wordcraft#857, #1494).

Co-authored-by: Dmitrii Khlapov <dkhlapov@pm.me>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-21 04:41:41 +00:00