From cf8049b8a6f2dbd26ccc5be762dc457a8ec4918e Mon Sep 17 00:00:00 2001 From: Christian Lawson-Perfect Date: Mon, 14 Apr 2025 13:24:13 +0000 Subject: [PATCH] Use Intl It now uses `Intl.NumberFormat` for as many formats as it can. I've also tried to identify different locale-dependent styles. Indian and Swiss with Latin digits are the only ones I found. Firefox thinks that an Algeria locale code should return Tibetan digits, which must be wrong. I've also added scientific, engineering and compact renderings, offered by Intl.NumberFormat. --- script.js | 278 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 153 insertions(+), 125 deletions(-) diff --git a/script.js b/script.js index a0555d7..02b72d5 100644 --- a/script.js +++ b/script.js @@ -2,6 +2,14 @@ function span(first, n=10) { return [...new Array(n)].map((_,i) => first.slice(0,first.length-1)+String.fromCharCode(first.charCodeAt(first.length-1) + i)); } +function intl_formatter(system, name, locale='nu', extra) { + const formatter = new Intl.NumberFormat(locale, Object.assign({numberingSystem:system},extra)); + return { + name, + fn: formatter.format + } +} + function positional_unicode_span(name, zero, base=10n, extra) { // Make a function to render a positional number system whose digits are in a contiguous span of unicode code points. return Object.assign({ @@ -22,9 +30,11 @@ function positional_unicode_span(name, zero, base=10n, extra) { }, extra || {}) } -function positional_symbols(name, symbols) { +function positional_symbols(name, symbols, extra) { + if(extra) { + } // Make a function to render a positional number system whose digits are drawn from the given string. - return { + return Object.assign({ name, fn: (n) => { let o = ''; @@ -40,7 +50,7 @@ function positional_symbols(name, symbols) { } return o; } - }; + }, extra || {}); } function concatenative(power_lists, base=10n) { @@ -122,8 +132,6 @@ const systems = { } }, - arabic: positional_unicode_span('Eastern Arabic', '٠'), - roman: { name: 'Roman', fn: concatenative([ @@ -159,7 +167,7 @@ const systems = { ]) }, - hebrew: { + hebr: { name: 'Hebrew', fn: (n) => { if(n >= 10000n) { @@ -175,7 +183,6 @@ const systems = { let o = ''; for(let symbols of [ones,tens,hundreds,thousands]) { - console.log(symbols, n); if(n==0n) { break; } @@ -189,7 +196,24 @@ const systems = { } }, - greek: { + + indian: intl_formatter('latn','Indian','en-in'), + + latn_commas: intl_formatter('latn','Latin with commas','en-gb'), + + latn_spaces: intl_formatter('latn','Latin with spaces','fi-fi'), + + latn_dots: intl_formatter('latn','European','eu'), + + latn_swiss: intl_formatter('latn','Swiss','de-ch'), + + scientific: intl_formatter('latn','Engineering','en',{notation:'scientific'}), + + engineering: intl_formatter('latn','Engineering','en',{notation:'engineering'}), + + compact: intl_formatter('latn','Compact','en',{notation:'compact'}), + + grek: { name: 'Greek', fn: concatenative([ ["Αʹ", "Βʹ", "Γʹ", "Δʹ", "Εʹ", "Ϛʹ", "Ζʹ", "Ηʹ", "Θʹ" ], @@ -201,7 +225,7 @@ const systems = { ]) }, - chinese: { + hans: { name: 'Chinese', fn: chinese_system( '〇', @@ -213,9 +237,9 @@ const systems = { counting_rod_horizontal: positional_symbols('Counting rod (horizontal)', ['〇'].concat(span('𝍠',9))), - counting_rod_vertical: positional_symbols('Counting rod (vertical)', ['〇'].concat(span('𝍩',9)), 10n, {orientation: 'vertical-lr'}), + counting_rod_vertical: positional_symbols('Counting rod (vertical)', ['〇'].concat(span('𝍩',9)), {orientation: 'vertical-lr'}), - suzhou: { + hant: { name: 'Suzhou', fn: (n) => { const zero = '〇'; @@ -235,7 +259,7 @@ const systems = { } }, - ethiopic: { + ethi: { name: 'Ethiopic', fn: concatenative([ span('፩',9), @@ -283,7 +307,7 @@ const systems = { ]) }, - armenian: { + armn: { name: 'Armenian', fn: concatenative([ ['Ա','Բ','Գ','Դ','Ե','Զ','Է','Ը','Թ'], @@ -313,7 +337,7 @@ const systems = { ]) }, - cyrillic: { + cyrl: { name: 'Cyrillic', fn: (() => { const units = ["А","В","Г","Д","Є","Ѕ","З","И","Ѳ"]; @@ -362,114 +386,10 @@ const systems = { mayan: positional_unicode_span('Mayan', '𝋠', 20n, {orientation: 'vertical-lr'}), - nko: positional_unicode_span('N\'Ko', '߀'), - - devanagari: positional_unicode_span('Devanagari', '०'), - - bengali: positional_unicode_span('Bengali', '০'), - - gurmukhi: positional_unicode_span('Gurmukhi','੦'), - - gujarati: positional_unicode_span('Gujarati', '૦'), - - odia: positional_unicode_span('Odia', '୦'), - - tamil: positional_unicode_span('Tamil', '௦'), - - telugu: positional_unicode_span('Telugu', '౦'), - - kannada: positional_unicode_span('Kannada', '೦'), - - malayalam: positional_unicode_span('Malayalam', '൦'), - - thai: positional_unicode_span('Thai', '๐'), - - lao: positional_unicode_span('Lao', '໐'), - - tibetan: positional_unicode_span('Tibetan', '༠'), - - burmese: positional_unicode_span('Burmese', '၀'), - - khmer: positional_unicode_span('Khmer', '០'), - - mongolian: positional_unicode_span('Mongolian', '᠐'), - - limbu: positional_unicode_span('Limbu', '᥆'), - - new_tai_lue: positional_unicode_span('New Tai Lue', '᧐'), - - lek_hora: positional_unicode_span('Lek Hora','᪀'), - - lek_nai_tham: positional_unicode_span('Lek Nai Tham', '᪐'), - - balinese: positional_unicode_span('Balinese', '᭐'), - - sundanese: positional_unicode_span('Sundanese', '᮰'), - - lepcha: positional_unicode_span('Lepcha', '᱀'), - - ol_chiki: positional_unicode_span('Ol Chiki', '᱐'), - - vai: positional_unicode_span('Vai', '꘠'), - - saurashtra: positional_unicode_span('Saurashtra', '꣐'), - - kayah_li: positional_unicode_span('Kayah Li', '꤀'), - - javanese: positional_unicode_span('Javanese', '꧐'), - - cham: positional_unicode_span('Cham', '꩐'), - - meitei: positional_unicode_span('meitei', '꯰'), - - osmanya: positional_unicode_span('Osmanya', '𐒠'), - - brahmi: positional_unicode_span('Brahmi', '𑁦'), - - sorang_sompeng: positional_unicode_span('Sorang Sompeng', '𑃰'), - - chakma: positional_unicode_span('Chakma', '𑄶'), - - sharada: positional_unicode_span('Sharada', '𑇐'), - - takri: positional_unicode_span('Takri', '𑛀'), - - sinhala: positional_unicode_span('Sinhala', '෦'), - - tai_laing: positional_unicode_span('Tai Laing', '꧰'), - - khudabadi: positional_unicode_span('Khudabadi', '𑋰'), - - tirhuta: positional_unicode_span('Tirhuta', '𑓐'), - - modi: positional_unicode_span('Modi', '𑙐'), - - warang_citi: positional_unicode_span('Warang Citi', '𑣠'), - - mro: positional_unicode_span('Mro', '𖩠'), - - pahawh_hmong: positional_unicode_span('Pahawh Hmong', '𖭐'), - - ahom: positional_unicode_span('Tai Ahom', '𑜰'), - prachalit: positional_unicode_span('Prachalit', '𑑐'), - hanifi_rohingya: positional_unicode_span('Hanifi Rohingya', '𐴰'), - - bhaiksuki: positional_unicode_span('Bhaiksuki', '𑱐'), - - masaram_gondi: positional_unicode_span('Masaram Gondi', '𑵐'), - - gunjala_gondi: positional_unicode_span('Gunjala Gondi', '𑶠'), - medefaidrin: positional_unicode_span('Medefaidrin', '𖺀', 20n), - nyiakeng_puachue_hmong: positional_unicode_span('Nyiakeng Puachue Hmong', '𞅀'), - - wancho: positional_unicode_span('Wancho', '𞋰'), - - adlam: positional_unicode_span('Adlam', '𞥐'), - kaktovik: positional_unicode_span('Kaktovik', '𝋀', 20n), // garay: positional_unicode_span('Garay', '𐵀'), //(not in noto??) @@ -506,25 +426,133 @@ const systems = { } } +const intl_system_names = { + "adlm": "Adlam", + "ahom": "Ahom", + "arab": "Arabic-Indic", + "arabext": "Farsi/Urdu", + "armn": "Armenian upper case", + "armnlow": "Armenian lower case", + "bali": "Balinese", + "beng": "Bengali", + "bhks": "Bhaiksuki", + "brah": "Brahmi", + "cakm": "Chakma", + "cham": "Cham", + "cyrl": "Cyrillic", + "deva": "Devanagari", + "diak": "Dives Akuru", + "ethi": "Ethiopic", + "fullwide": "Full width", + "gara": "Garay", + "geor": "Georgian", + "gong": "Gunjala Gondi", + "gonm": "Masaram Gondi", + "grek": "Greek upper case", + "greklow": "Greek lower case", + "gujr": "Gujarati", + "gukh": "Gurung Khema", + "guru": "Gurmukhi", + "hanidays": "Han calendar", + "hanidec": "Chinese (positional)", + "hans": "Simplified Chinese", + "hansfin": "Simplified Chinese financial", + "hant": "Traditional Chinese", + "hantfin": "Traditional Chinese financial", + "hebr": "Hebrew", + "hmng": "Pahawh Hmong", + "hmnp": "Nyiakeng Puachue Hmong", + "java": "Javanese", + "jpan": "Japanese", + "jpanfin": "Japanese financial", + "jpanyear": "Japanese calendar", + "kali": "Kayah Li", + "kawi": "Kawi", + "khmr": "Khmer", + "knda": "Kannada", + "krai": "Kirat Rai", + "lana": "Tai Tham Hora", + "lanatham": "Tai Tham", + "laoo": "Lao", + "latn": "Latin", + "lepc": "Lepcha", + "limb": "Limbu", + "mathbold": "Mathematical bold", + "mathdbl": "Mathematical double-struck", + "mathmono": "Mathematical monospace", + "mathsanb": "Mathematical sans-serif bold", + "mathsans": "Mathematical sans-serif", + "mlym": "Malayalam", + "modi": "Modi", + "mong": "Mongolian", + "mroo": "Mro", + "mtei": "Meetei Mayek", + "mymr": "Myanmar", + "mymrepka": "Myanmar Eastern Pwo Karen", + "mymrpao": "Myanmar Pao", + "mymrshan": "Myanmar Shan", + "mymrtlng": "Myanmar Tai Laing", + "nagm": "Nag Mundari", + "newa": "Newa", + "nkoo": "N'Ko", + "olck": "Ol Chiki", + "onao": "Ol Onal", + "orya": "Oriya", + "osma": "Osmanya", + "outlined": "Outlined digits", + "rohg": "Hanifi Rohingya", + "roman": "Roman upper case", + "romanlow": "Roman lowercase", + "saur": "Saurashtra", + "segment": "7-segment display", + "shrd": "Sharada", + "sind": "Khudawadi", + "sinh": "Sinhala Lith", + "sora": "Sora_Sompeng", + "sund": "Sundanese", + "sunu": "Sunuwar", + "takr": "Takri", + "talu": "New Tai Lue", + "taml": "Tamil", + "tamldec": "Modern Tamil decimal", + "telu": "Telugu", + "thai": "Thai", + "tibt": "Tibetan", + "tirh": "Tirhuta", + "tnsa": "Tangsa", + "vaii": "Vai", + "wara": "Warang Citi", + "wcho": "Wancho" +} + +Intl.supportedValuesOf('numberingSystem').forEach(system => { + systems[system] = intl_formatter(system, intl_system_names[system]); +}); + const dl = document.getElementById('systems'); -Object.entries(systems).forEach(([id, entry]) => { +function sort_by_name([_,{name: a}], [__,{name: b}]) { + return a < b ? -1 : a>b ? 1 : 0; +} + +Object.entries(systems).toSorted(sort_by_name).forEach(([id, entry]) => { const {name, orientation} = entry; const dt = document.createElement('dt'); dt.textContent = name; dl.append(dt); const dd = document.createElement('dd'); - if(orientation) { - dd.style['writing-mode'] = orientation; - } + const bdi = document.createElement('bdi'); + dd.append(bdi); dl.append(dd); - entry.dd = dd; + if(orientation) { + bdi.style['writing-mode'] = orientation; + } + entry.dd = bdi; }) function update() { const n = BigInt(decimal_input.value || '0'); Object.values(systems).forEach(({name,fn,dd}) => { - console.log(name); dd.textContent = fn(n); }); } @@ -533,4 +561,4 @@ const decimal_input = document.getElementById('decimal'); update(); -decimal_input.addEventListener('input', update); \ No newline at end of file +decimal_input.addEventListener('input', update) \ No newline at end of file