Показывать акцентную метку Юникода рядом с буквой Юникода, а не комбинировать - PullRequest
0 голосов
/ 08 ноября 2018

Как видно из названия, я пытаюсь отобразить знаки акцента в Юникоде рядом с буквами

Эта задача возникает из-за необходимости перебирать строку, определять специальный символ и затем «упрощать» его, разбивая знак ударения и букву и отображая их рядом (правильное слово не имеет значения, имеет значение только форматирование).

т.е. Às --> Aˋs

У меня уже есть необходимый Юникод, поэтому мне не нужно идентифицировать ни одного из символов.

Я пытаюсь сделать это динамически, поэтому я сохранил весь специальный символ Unicode и замену Unicode в объектах в массиве. Вместо того, чтобы перебирать каждый отдельный символ в строке, я глобально заменяю каждый экземпляр специального символа новой комбинацией символов Юникода, которую я хочу. пожалуйста, смотрите мой текущий код ниже:

//String to check for special characters
var string_data = "Às simple as this sounds...it is trivial"

//Array of special(incompatible) characters and replacement unicode characters
var unicodeChars = [
{
    incompatible_unicode_char: "\u00C0",//À
    replace_uni_char_one: "\u0041", //A
    replace_uni_char_two: "\u0300" //ˋ
}
];

//Convert property values from unicodeChars objects to readable characters
for(var i = 0; i< unicodeChars.length;i++){ 
    String.fromCharCode(parseInt(unicodeChars[i].incompatible_unicode_char,16));
    String.fromCharCode(parseInt(unicodeChars[i].replace_uni_char_one,16));
    String.fromCharCode(parseInt(unicodeChars[i].replace_uni_char_two,16));
}

//Iterate through each object in unicodeChars array 
for(var i = 0; i<unicodeChars.length;i++){

  //Creating a string that holds the value of what to replace the special character with
  var replacement_chars = unicodeChars[i].replace_uni_char_one;
  if(unicodeChars[i].replace_uni_char_two != null){
    replacement_chars = replacement_chars + unicodeChars[i].replace_uni_char_two;
  }

  //creating regex object in order to globally replace any occurrence of the special character in the string
  var regex = new RegExp(unicodeChars[i].incompatible_unicode_char, "g");

  //attempting to replace the occurrence 
  string_data = string_data.replace(regex, replacement_chars);
 }

Мое желаемое конечное значение string_data: : Aˋs simple as this sounds...it is trivial

Однако проблема здесь в том, что текущее конечное значение равно : Às simple as this sounds...it is trivial

Так что string_data в основном не меняется вообще, но в то же время это так. В ходе расследования я обнаружил, что добавление символов и маркеров ударения объединяет их в одну букву.

Так что в моем коде, когда я делаю следующее: replacement_chars = replacement_chars + unicodeChars[i].replace_uni_char_two; код автоматически объединяет знак ударения от unicodeChars[i].replace_uni_char_two со стандартной буквой, удерживаемой в replacement_chars.

Я не хочу, чтобы это объединение происходило, я хочу отображать их рядом друг с другом, например Aˋs, а не Às. Как остановить автоматическое объединение javascript знака акцента и стандартной буквы ?

Пожалуйста, имейте в виду, что мне нужно сохранить текущую структуру этого кода (массив unicodeCharacters, преобразовывать значения Unicode в символы, а затем использовать регулярное выражение для выполнения глобального replace) заранее, и я желаю чтобы сохранить это решение динамичным, как оно есть в настоящее время.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Проблема возникает из-за того, что вы используете комбинирующий символ вместо буквы модификатора для серьезного ударения в вашем примере кода, поэтому просто измените значение replace_uni_char_two с \u0300 до \u02CB. Чтобы подтвердить, что изменение устраняет проблему, запустите этот простой JavaScript:

console.log('u00C0         : \u00C0');
console.log('u0041 + u0300 : \u0041\u0300  [Uses combining character for grave accent]');
console.log('u0041 + u02cb : \u0041\u02cb [Uses modifier letter for grave accent]');

Вот вывод:

u00C0         : À
u0041 + u0300 : À  [Uses combining character for grave accent]
u0041 + u02cb : Aˋ [Uses modifier letter for grave accent]

Обратите внимание, что:

  • Декомпозиция для + U00C0 (À) - это БУКВА ЛАТИНСКОГО КАПИТАЛА (U + 0041) плюс АКЦЕНТ КОМБИНИРОВАННОЙ МОГИЛКИ (U + 0300).
  • ACCENT КОМБИНИРОВАНИЯ GRAVE (U + 0300) - это символ комбинирования , который будет объединен с предыдущим символом в один глиф для рендеринга. Это проблема, которую вам нужно исправить в вашем коде.
  • В противоположность этому, персонаж, который решает вашу проблему, ПИСЬМО МОДИФЕРА АКЦЕНТ МОЛОДЕЖНОГО (U + 02CB) , визуально очень похож на АКЦЕНТ КОМБИНИРОВАНИЯ МОГРОГО (U + 0300), но это буква модификатора . не будет объединен с предыдущим символом в один глиф для рендеринга.

Поэтому общий подход к исправлению вашего кода:

  • Определите декомпозицию каждого определенного вами специального символа, который, вероятно, будет базовым символом, за которым следует один комбинирующий символ .
  • Получите модификатор буквы аналог * комбинирующего символа . Имя Unicode объединяющего символа будет содержать « COMBINING », а имя его буквы-модификатора будет содержать « MODIFIER LETTER ». Например: « КОМБИНИРОВАНИЕ GRAVE ACCENT" vs " ПИСЬМО МОДИФИКАТОРА GRAVE ACCENT".
  • В объявлении кода unicodeChars укажите значения букв-модификаторов вместо символов объединения .

Подробнее об этой нетривиальной проблеме см. В чем разница между «сочетанием символов» и «букв-модификаторов»?

0 голосов
/ 14 ноября 2018

Как остановить автоматическое сочетание javascript со знаком акцента и стандартной буквой?

Вы обвиняете не ту систему, это средство визуализации шрифтов, которое объединяет глифы.


В Javascript просто окружайте метки пробелами, чтобы они оставались в одиночестве.

XRegExp.replace(
    "Às simple as this sounds...it is trivial".normalize('NFD'),
    XRegExp('(\\p{Mark})'),
    ' $1 '
)
...