У меня есть ответ ниже. Если у кого-то есть лучший ответ, пожалуйста, прокомментируйте.
Хотелось бы подумать, что можно использовать «UnicodeData .... txt», чтобы понять, что
текст слева направо или справа налево. К сожалению нет, потому что этот список идет на персонажа
стиль, игнорируя понятие «блок». Другими словами, рассмотрим блок на арабском или иврите: не
все кодовые точки определены, но ЯВНО, если кодовая точка добавлена в блок на иврите, НЕ является
будет один в блоке слева направо - это было бы крайне маловероятно.
При внимательном рассмотрении всех символов справа налево при перекрестной ссылке на имена блоков обнаруживается
есть только пять диапазонов символов справа налево. Эти пять диапазонов охватывают все
символьные блоки справа налево и все диапазоны символов, где вновь определены справа налево
кодовая точка, вероятно, будет вставлена.
Мне удалось определить, что в Юникоде 10 есть следующие блоки справа налево.
0590..05FF; Hebrew
0600..06FF; Arabic
0700..074F; Syriac
0750..077F; Arabic Supplement
0780..07BF; Thaana
07C0..07FF; NKo
0800..083F; Samaritan
0840..085F; Mandaic
0860..086F; Syriac Supplement
08A0..08FF; Arabic Extended-A
FB1D..FB4F; Alphabetic Presentation Forms (hebrew part)
FB50..FDFF; Arabic Presentation Forms-A
FE70..FEFF; Arabic Presentation Forms-B
10800..1083F; Cypriot Syllabary
10840..1085F; Imperial Aramaic
10860..1087F; Palmyrene
10880..108AF; Nabataean
108E0..108FF; Hatran
10900..1091F; Phoenician
10920..1093F; Lydian
10980..1099F; Meroitic Hieroglyphs
109A0..109FF; Meroitic Cursive
10A00..10A5F; Kharoshthi
10A60..10A7F; Old South Arabian
10A80..10A9F; Old North Arabian
10AC0..10AFF; Manichaean
10B00..10B3F; Avestan
10B40..10B5F; Inscriptional Parthian
10B60..10B7F; Inscriptional Pahlavi
10B80..10BAF; Psalter Pahlavi
10C00..10C4F; Old Turkic
10C80..10CFF; Old Hungarian
1E800..1E8DF; Mende Kikakui
1E900..1E95F; Adlam
1EE00..1EEFF; Arabic Mathematical Alphabetic Symbols
Вот оптимизированный макрос компаратора языка C: наиболее распространенный текст останавливается на первом «> =».
Этот макрос корректен для каждой кодовой точки в юникоде 10, кроме:
200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;;
Макрос (Слово «левант» является примерно хорошим описанием большинства языков справа налево):
#define IS_LEVANT(c) ((c) >= 0x00590 && ((c) <= 0x008FF || \
((c) >= 0x0FB1D && ((c) <= 0x0FDFF || \
((c) >= 0x0FE70 && ((c) <= 0x0FEFF || \
((c) >= 0x10800 && ((c) <= 0x10CFF || \
((c) >= 0x1E800 && ((c) <= 0x1EEFF))))))))))
Вот скрипт Python для проверки макроса:
f = open('/home/paul/UnicodeData.txt').readlines()
def LEVANT(c):
return \
((c) >= 0x00590 and ((c) <= 0x008FF or \
((c) >= 0x0FB1D and ((c) <= 0x0FDFF or \
((c) >= 0x0FE70 and ((c) <= 0x0FEFF or \
((c) >= 0x10800 and ((c) <= 0x10CFF or \
((c) >= 0x1E800 and ((c) <= 0x1EEFF))))))))))
for ll in f:
ll = ll.strip()
if not ll:
continue
l = ll.split(';')
if l[4] == 'R':
i = l[0]
i = eval('0x' + i)
if not LEVANT(i):
print('R ===> ' + ll)
if l[4] == 'L':
i = l[0]
i = eval('0x' + i)
if LEVANT(i):
print('R ===> ' + ll)