diff --git a/modules/util/svg_paths_rtl_fix.js b/modules/util/svg_paths_rtl_fix.js index 63e00a19b..0410cfc55 100644 --- a/modules/util/svg_paths_rtl_fix.js +++ b/modules/util/svg_paths_rtl_fix.js @@ -1,77 +1,16 @@ // see https://github.com/openstreetmap/iD/pull/3707 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60 -var chars = { - // madda above alef - 1570: { initial: 'آ‎', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' }, - - // hamza above and below alef - 1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' }, - // 1572 is ؤ - 1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' }, - // 1574 is ئ - 1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' }, - 1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' }, - - // 1577 ة - 1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' }, - - 1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' }, - 1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' }, - 1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' }, - 1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' }, - 1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' }, - 1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' }, - 1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' }, - 1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' }, - 1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' }, - 1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' }, - 1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' }, - 1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' }, - 1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' }, - 1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' }, - 1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' }, - 1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' }, - 1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' }, - 1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' }, - - // 1595 ػ - may be very rare - - 1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' }, - 1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' }, - 1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' }, - 1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' }, - 1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' }, - 1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' }, - 1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' }, - - // 1609 ى - 1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' }, - // 1610 ي - 1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' }, - - // short vowel sounds / tashkil markings - - 1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' }, - - 1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' }, - 1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' }, - 1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' }, - 1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' }, - 1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' }, - 5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' } -}; +import { BaselineSplitter, WordShaper } from 'alif-toolkit'; export var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0780-\u07BF]/; export function fixRTLTextForSvg(inputText) { - var context = true; - var ret = ''; - var rtlBuffer = []; - var arabicRegex = /[\u0600-\u06FF]/g; - var arabicTashkil = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/; - var thaanaVowel = /[\u07A6-\u07B0]/; - var hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/; + let ret = '', rtlBuffer = []; + let arabicRegex = /[\u0600-\u06FF]/g; + let arabicTashkil = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/; + let thaanaVowel = /[\u07A6-\u07B0]/; + let hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/; if (!arabicRegex.test(inputText)) { // Hebrew or Thaana RTL script @@ -90,59 +29,22 @@ export function fixRTLTextForSvg(inputText) { rtlBuffer = []; } } + ret += rtlBuffer.reverse().join(''); + return ret; } else { - for (var i = 0, l = inputText.length; i < l; i++) { - var code = inputText[i].charCodeAt(0); - var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0; - - if (!chars[code]) { - if (code === 32 && rtlBuffer.length) { - // whitespace - rtlBuffer = [rtlBuffer.reverse().join('') + ' ']; - } else if (arabicTashkil.test(inputText[i]) && rtlBuffer.length) { - // tashkil mark - rtlBuffer[rtlBuffer.length - 1] += inputText[i]; - } else { - // non-RTL character - ret += rtlBuffer.reverse().join('') + inputText[i]; - rtlBuffer = []; - } - continue; - } - if (context) { - if (i === l - 1 || nextCode === 32) { - rtlBuffer.push(chars[code].isolated); - } else { - // special case for لا - if (code === 1604 && nextCode === 1575) { - rtlBuffer.push(chars[5000].initial); - i++; - context = true; - continue; - } - rtlBuffer.push(chars[code].initial); - } - } else { - if (i === l - 1 || nextCode === 32){ - rtlBuffer.push(chars[code].final); - } else { - // special case for ﻼ - if (code === 1604 && nextCode === 1575){ - rtlBuffer.push(chars[5000].final); - i++; - context = true; - continue; - } - if (chars[code].medial === ''){ - rtlBuffer.push(chars[code].final); - } else { - rtlBuffer.push(chars[code].medial); - } - } - } - context = (chars[code].medial === '') || nextCode === 32; - } + let myWord = BaselineSplitter(WordShaper(inputText)); + myWord.forEach((baseline) => { + if (baseline === ' ') { + ret = baseline + rtlBuffer.reverse().join('') + ret; + rtlBuffer = []; + } else if (baseline.match(/^\d+$/)) { + ret = rtlBuffer.reverse().join('') + ret + baseline; + rtlBuffer = []; + } else { + rtlBuffer.push(baseline); + } + }); + ret = rtlBuffer.reverse().join('') + ret; + return ret; } - ret += rtlBuffer.reverse().join(''); - return ret; } diff --git a/package.json b/package.json index 95a136bbd..62e2cb801 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@mapbox/togeojson": "0.16.0", "@mapbox/vector-tile": "^1.3.1", "@turf/bbox-clip": "^6.0.0", + "alif-toolkit": "^1.2.4", "diacritics": "1.3.0", "fast-json-stable-stringify": "2.0.0", "lodash-es": "4.17.11",