Index: gc_lang/fr/modules-js/gce_suggestions.js ================================================================== --- gc_lang/fr/modules-js/gce_suggestions.js +++ gc_lang/fr/modules-js/gce_suggestions.js @@ -556,47 +556,52 @@ return "les|la"; } return "la"; } -function formatNumber (s) { - let nLen = s.length; - if (nLen < 4 ) { - return s; - } - let sRes = ""; - // nombre ordinaire - let nEnd = nLen; - while (nEnd > 0) { - let nStart = Math.max(nEnd-3, 0); - sRes = sRes ? s.slice(nStart, nEnd) + " " + sRes : sRes = s.slice(nStart, nEnd); - nEnd = nEnd - 3; - } - // binaire - if (/^[01]+$/.test(s)) { - nEnd = nLen; - let sBin = ""; - while (nEnd > 0) { - let nStart = Math.max(nEnd-4, 0); - sBin = sBin ? s.slice(nStart, nEnd) + " " + sBin : sBin = s.slice(nStart, nEnd); - nEnd = nEnd - 4; - } - sRes += "|" + sBin; - } - // numéros de téléphone - if (nLen == 10) { - if (s.startsWith("0")) { - sRes += "|" + s.slice(0,2) + " " + s.slice(2,4) + " " + s.slice(4,6) + " " + s.slice(6,8) + " " + s.slice(8); // téléphone français - if (s[1] == "4" && (s[2]=="7" || s[2]=="8" || s[2]=="9")) { - sRes += "|" + s.slice(0,4) + " " + s.slice(4,6) + " " + s.slice(6,8) + " " + s.slice(8); // mobile belge - } - sRes += "|" + s.slice(0,3) + " " + s.slice(3,6) + " " + s.slice(6,8) + " " + s.slice(8); // téléphone suisse - } - sRes += "|" + s.slice(0,4) + " " + s.slice(4,7) + "-" + s.slice(7); // téléphone canadien ou américain - } else if (nLen == 9 && s.startsWith("0")) { - sRes += "|" + s.slice(0,3) + " " + s.slice(3,5) + " " + s.slice(5,7) + " " + s.slice(7,9); // fixe belge 1 - sRes += "|" + s.slice(0,2) + " " + s.slice(2,5) + " " + s.slice(5,7) + " " + s.slice(7,9); // fixe belge 2 +function formatNumber (sNumber) { + let nLen = sNumber.length; + if (nLen < 4 ) { + return sNumber; + } + let sRes = ""; + if (!sNumber.includes(",")) { + // Nombre entier + sRes = _formatNumber(sNumber, 3); + // binaire + if (/^[01]+$/.test(sNumber)) { + sRes += "|" + _formatNumber(sNumber, 4); + } + // numéros de téléphone + if (nLen == 10) { + if (sNumber.startsWith("0")) { + sRes += "|" + _formatNumber(sNumber, 2); // téléphone français + if (sNumber[1] == "4" && (sNumber[2]=="7" || sNumber[2]=="8" || sNumber[2]=="9")) { + sRes += "|" + sNumber.slice(0,4) + " " + sNumber.slice(4,6) + " " + sNumber.slice(6,8) + " " + sNumber.slice(8); // mobile belge + } + sRes += "|" + sNumber.slice(0,3) + " " + sNumber.slice(3,6) + " " + sNumber.slice(6,8) + " " + sNumber.slice(8); // téléphone suisse + } + sRes += "|" + sNumber.slice(0,4) + " " + sNumber.slice(4,7) + "-" + sNumber.slice(7); // téléphone canadien ou américain + } else if (nLen == 9 && sNumber.startsWith("0")) { + sRes += "|" + sNumber.slice(0,3) + " " + sNumber.slice(3,5) + " " + sNumber.slice(5,7) + " " + sNumber.slice(7,9); // fixe belge 1 + sRes += "|" + sNumber.slice(0,2) + " " + sNumber.slice(2,5) + " " + sNumber.slice(5,7) + " " + sNumber.slice(7,9); // fixe belge 2 + } + } else { + // Nombre réel + let [sInt, sFloat] = sNumber.split(",", 2); + sRes = _formatNumber(sInt, 3) + "," + sFloat; + } + return sRes; +} + +function _formatNumber (sNumber, nGroup=3) { + let sRes = ""; + let nEnd = sNumber.length; + while (nEnd > 0) { + let nStart = Math.max(nEnd-nGroup, 0); + sRes = sRes ? sNumber.slice(nStart, nEnd) + " " + sRes : sRes = sNumber.slice(nStart, nEnd); + nEnd = nEnd - nGroup; } return sRes; } function formatNF (s) { Index: gc_lang/fr/modules/gce_suggestions.py ================================================================== --- gc_lang/fr/modules/gce_suggestions.py +++ gc_lang/fr/modules/gce_suggestions.py @@ -431,42 +431,46 @@ return "la" _zBinary = re.compile("^[01]+$") -def formatNumber (s): +def formatNumber (sNumber): "add spaces or hyphens to big numbers" - nLen = len(s) + nLen = len(sNumber) if nLen < 4: - return s - sRes = "" - # nombre ordinaire - nEnd = nLen - while nEnd > 0: - nStart = max(nEnd-3, 0) - sRes = s[nStart:nEnd] + " " + sRes if sRes else s[nStart:nEnd] - nEnd = nEnd - 3 - # binaire - if _zBinary.search(s): - nEnd = nLen - sBin = "" - while nEnd > 0: - nStart = max(nEnd-4, 0) - sBin = s[nStart:nEnd] + " " + sBin if sBin else s[nStart:nEnd] - nEnd = nEnd - 4 - sRes += "|" + sBin - # numéros de téléphone - if nLen == 10: - if s.startswith("0"): - sRes += "|" + s[0:2] + " " + s[2:4] + " " + s[4:6] + " " + s[6:8] + " " + s[8:] # téléphone français - if s[1] == "4" and (s[2]=="7" or s[2]=="8" or s[2]=="9"): - sRes += "|" + s[0:4] + " " + s[4:6] + " " + s[6:8] + " " + s[8:] # mobile belge - sRes += "|" + s[0:3] + " " + s[3:6] + " " + s[6:8] + " " + s[8:] # téléphone suisse - sRes += "|" + s[0:4] + " " + s[4:7] + "-" + s[7:] # téléphone canadien ou américain - elif nLen == 9 and s.startswith("0"): - sRes += "|" + s[0:3] + " " + s[3:5] + " " + s[5:7] + " " + s[7:9] # fixe belge 1 - sRes += "|" + s[0:2] + " " + s[2:5] + " " + s[5:7] + " " + s[7:9] # fixe belge 2 + return sNumber + sRes = "" + if "," not in sNumber: + # nombre entier + sRes = _formatNumber(sNumber, 3) + # binaire + if _zBinary.search(sNumber): + sRes += "|" + _formatNumber(sNumber, 4) + # numéros de téléphone + if nLen == 10: + if sNumber.startswith("0"): + sRes += "|" + _formatNumber(sNumber, 2) # téléphone français + if sNumber[1] == "4" and (sNumber[2]=="7" or sNumber[2]=="8" or sNumber[2]=="9"): + sRes += "|" + sNumber[0:4] + " " + sNumber[4:6] + " " + sNumber[6:8] + " " + sNumber[8:] # mobile belge + sRes += "|" + sNumber[0:3] + " " + sNumber[3:6] + " " + sNumber[6:8] + " " + sNumber[8:] # téléphone suisse + sRes += "|" + sNumber[0:4] + " " + sNumber[4:7] + "-" + sNumber[7:] # téléphone canadien ou américain + elif nLen == 9 and sNumber.startswith("0"): + sRes += "|" + sNumber[0:3] + " " + sNumber[3:5] + " " + sNumber[5:7] + " " + sNumber[7:9] # fixe belge 1 + sRes += "|" + sNumber[0:2] + " " + sNumber[2:5] + " " + sNumber[5:7] + " " + sNumber[7:9] # fixe belge 2 + else: + # Nombre réel + sInt, sFloat = sNumber.split(",", 1) + sRes = _formatNumber(sInt, 3) + "," + sFloat + return sRes + +def _formatNumber (sNumber, nGroup=3): + sRes = "" + nEnd = len(sNumber) + while nEnd > 0: + nStart = max(nEnd-nGroup, 0) + sRes = sNumber[nStart:nEnd] + " " + sRes if sRes else sNumber[nStart:nEnd] + nEnd = nEnd - nGroup return sRes def formatNF (s): "typography: format NF reference (norme française)" Index: gc_lang/fr/rules.grx ================================================================== --- gc_lang/fr/rules.grx +++ gc_lang/fr/rules.grx @@ -1227,22 +1227,24 @@ !! !! __[s]/unit(unit_nbsp_avant_unités1)__ ((\d+(?:,\d+[⁰¹²³⁴⁵⁶⁷⁸⁹]?|[⁰¹²³⁴⁵⁶⁷⁸⁹]|)) ?)(?:[kcmµn]?(?:[slgJKΩ]|m[²³]?|Wh?|Hz|dB)|[%‰€$£¥Åℓhj]|min|°C|℃)(?![’']) @@0,0 - <<- -1>> "\2 " - # Avec une unité de mesure, mettez un espace insécable. + <<- option("num") -1>> =formatNumber(\2) + " " # Avec une unité de mesure, mettez un espace insécable. + <<- __else__ -1>> "\2 " # Avec une unité de mesure, mettez un espace insécable. + __[s]/unit(unit_nbsp_avant_unités2)__ ((\d+(?:,\d+[⁰¹²³⁴⁵⁶⁷⁸⁹]?|[⁰¹²³⁴⁵⁶⁷⁸⁹])) ?)([a-zA-Zµ][a-zA-Z0-9Ωℓ⁰¹²³⁴⁵⁶⁷⁸⁹/·]*) @@0,0,$ - <<- morph(\3, ";S", ":[VCR]") or mbUnit(\3) or not spell(\3) - -1>> "\2 " - # Si “\3” est une unité de mesure, il manque un espace insécable. Si le nombre se rapporte au mot suivant, c’est aussi valable. + <<- morph(\3, ";S", ":[VCR]") or mbUnit(\3) or not spell(\3) >>> + <<- option("num") -1>> =formatNumber(\2) + " " # Si “\3” est une unité de mesure, il manque un espace insécable. Si le nombre se rapporte au mot suivant, c’est aussi valable. + <<- __else__ -1>> "\2 " # Si “\3” est une unité de mesure, il manque un espace insécable. Si le nombre se rapporte au mot suivant, c’est aussi valable. + __[s]/unit(unit_nbsp_avant_unités3)__ ((\d+) )([a-zA-Zµ][a-zA-Z0-9Ωℓ⁰¹²³⁴⁵⁶⁷⁸⁹/·]*)(?![’']) @@0,0,$ - <<- (\2.__len__() > 4 and not spell(\3)) or morph(\3, ";S", ":[VCR]") or mbUnit(\3) - -1>> "\2 " - # Si “\3” est une unité de mesure, il manque un espace insécable. Si le nombre se rapporte au mot suivant, c’est aussi valable. + <<- (\2.__len__() > 4 and not spell(\3)) or morph(\3, ";S", ":[VCR]") or mbUnit(\3) >>> + <<- option("num") -1>> =formatNumber(\2) + " " # Si “\3” est une unité de mesure, il manque un espace insécable. Si le nombre se rapporte au mot suivant, c’est aussi valable. + <<- __else__ -1>> "\2 " # Si “\3” est une unité de mesure, il manque un espace insécable. Si le nombre se rapporte au mot suivant, c’est aussi valable. TEST: Ça a duré {{3}}µs TEST: Ça a duré {{3,5 }}µs TEST: il y en a {{3 }}m² TEST: il a fait {{10}}%