Информация об изменениях

Сообщение Re[16]: Как написать редактор текстов на C#? от 30.11.2022 1:15

Изменено 30.11.2022 1:38 Эйнсток Файр

Re[16]: Как написать редактор текстов на C#?
S> Детали по-прежнему зависят от того, что вы хотите написать. Пока что мы ничего не знаем, кроме того, что вы хотите уметь работать с ударениями (для которых, вообще говоря, достаточно выучить ровно один combining diacritic character) в кириллице и смайликами.

Меня в первую очередь волнует обработка текста.
Мне кажется, что если обработка текста будет сделана корректно,
то потом поверх можно будет без проблем сделать и редактирование.

Грубо говоря, я хочу две(три) сборки/assembly:
1) библиотеку/фреймворк для работы с юникодом;
2) код, который будет текст обрабатывать на самом деле;
3) редактор (опционально).

Поэтому я не вполне понимаю, почему вы спрашиваете про декомпозицию лигатур.

S> Я же вас спрашивал с самого начала — хотите ли вы декомпозировать лигатуры, или вас устроит удаление всей лигатуры целиком?


Меня не волнует редактирование как таковое.
Поэтому я не понимаю, почему вы задаёте этот вопрос, причём несколько раз подряд.

ЭФ>>Вы предлагаете полагаться на систему (и АПИ) рендеринга,

ЭФ>>чтобы о таких штуках знала она, но не знал я.
S> Я предлагаю для внутреннего представления текста использовать дерево. В самом низу этого дерева пусть лежат последовательности символов в такой кодировке, которая удобна для передачи в платформенные функции отображения — например, UTF-16. А узлами дерева будут собственно TextElement, Word, Line.

Поиск — это обработка.

Потому что если у вас на нижнем уровне лигатура ffi, то буква i внутри неё не будет найдена при поиске, потому что в вашей логической модели её нет как отдельного объекта.

А если заранее разобъёте на отдельные Codepoint, то вот другой контрпример про смайлики:

if we want to find an ear of rice 🌾 U+1F33E then it'll match 👨‍🌾 unexpectedly because that farmer emoji is encoded as U+1F468 U+200D U+1F33E


Если в первом случае для обработки разбивать надо, то во втором как раз не надо.

Ваш подход бажный, некорректно обрабатывает текст и вы не прошли собеседование про смайлики.

Вместо использования АПИ с функцией TextElement (которая реализована непонятно как, и, вероятно, опирается на реализацию базы юникодных символов в glibc) я предлагаю закодировать правила из стандарта (14 штук)
https://unicode.org/reports/tr29/#Extend
прямо на сишарпе в виде ДКА, как они там предлагают. Возможно библиотека ICU.NET
https://github.com/sillsdev/icu-dotnet
это делает, но в любом случае она обёртка над C++-кодом. И это плохо, потому что существуют pure C# операционки, куда это не влезет.

Но чисто сишарповая реализация неважна, это был так, вбоквел к обсуждению.

S> у вас же нет цели самостоятельно нормализовывать все композиции?


Если я правильно понимаю, то нормализация — это преобразование исходного потока байтов, то есть уже операция по его редактированию. Если есть такая операция, то должна быть обратная операция — денормализация (для движка Undo/Redo). Я не могу не делать нормализацию самостоятельно, если .Net Framework не предоставляет обратной операции. Это, конечно, в том случае, если я правильно понимаю слово "нормализация", как объединение букв f, f, i в одну лигатуру ffi всегда. Я сомневаюсь, что .Net framework делает такое объединение при нормализации. В моём представлении это происходит при рендеринге (а если не происходит, то рендеринг выполняется некорректно, лигатура не отрисовывается).

S> в арабском письме (и при применении различных "рукописных" шрифтов) отдельно стоящая буква пишется совсем не так, как в составе слова.


Ну, такая же проблема, как у лигатуры ffi, или нет?

Главное, что в результате разбора у меня будут не только TextElement, но и их связь с исходными позициями в потоках Codepoint и byte.

S> Как именно вы отслеживаете эту связь? Вот у вас лежит массив символов "внутренней кодировки". Три подряд из них соответствуют вот этому ffi, который один и тот же текстовый элемент.

Как именно устроено вот это соответствие?

В виде .Net объекта. У меня "лежат" (будут лежать):
1) массив байтов
2) массив кодепоинтов
3) массив TextElement
4) массив моих "внутренних" символов
4-3) массив связок типа "4-3" с количеством объектов как в 4
3-2) массив связок типа "3-2" с количеством объектов как в 3
2-1) не хранится, потому что может быть вычислен алгоритмически на лету.

При создании символов массива 4 я могу провести унификацию, преобразовать ударения в свойства этих символов.
То есть, если TextElement имели значения "а" и "а́", то им будут соответствовать два объекта "а" и "а" класса "4", но с разными значениями свойства "ModernRussianStress" (false и true).

Тип char не даст мне хранить при себе свойства, потому что он слишком простой для этого.

S> вы хотите уметь работать с ударениями (для которых, вообще говоря, достаточно выучить ровно один combining diacritic character) в кириллице


Кириллицей так же записываются церковные книги. А в староцерковном языке три типа ударений — "оксия", "вария", "камора". Вы просто не любите русских и стремитесь уничтожить наше духовное наследие.

Ещё эта фигня с необязательностью точек над ё. Нужен будет специальный код, который правильно угадывает букву "ё", но помечает её признаком "WithoutPointsOverIt".
Re[16]: Как написать редактор текстов на C#?
S> Детали по-прежнему зависят от того, что вы хотите написать. Пока что мы ничего не знаем, кроме того, что вы хотите уметь работать с ударениями (для которых, вообще говоря, достаточно выучить ровно один combining diacritic character) в кириллице и смайликами.

Меня в первую очередь волнует обработка текста.
Мне кажется, что если обработка текста будет сделана корректно,
то потом поверх можно будет без проблем сделать и редактирование.

Грубо говоря, я хочу две(три) сборки/assembly:
1) библиотеку/фреймворк для работы с юникодом;
2) код, который будет текст обрабатывать на самом деле;
3) редактор (опционально).

Поэтому я не вполне понимаю, почему вы спрашиваете про декомпозицию лигатур.

S> Я же вас спрашивал с самого начала — хотите ли вы декомпозировать лигатуры, или вас устроит удаление всей лигатуры целиком?


Меня не волнует редактирование как таковое.
Поэтому я не понимаю, почему вы задаёте этот вопрос, причём несколько раз подряд.

ЭФ>>Вы предлагаете полагаться на систему (и АПИ) рендеринга,

ЭФ>>чтобы о таких штуках знала она, но не знал я.
S> Я предлагаю для внутреннего представления текста использовать дерево. В самом низу этого дерева пусть лежат последовательности символов в такой кодировке, которая удобна для передачи в платформенные функции отображения — например, UTF-16. А узлами дерева будут собственно TextElement, Word, Line.

Поиск — это обработка.

Потому что если у вас на нижнем уровне лигатура ffi, то буква i внутри неё не будет найдена при поиске, потому что в вашей логической модели её нет как отдельного объекта.

А если заранее разобъёте на отдельные Codepoint, то вот другой контрпример про смайлики:

if we want to find an ear of rice 🌾 U+1F33E then it'll match 👨‍🌾 unexpectedly because that farmer emoji is encoded as U+1F468 U+200D U+1F33E


Если в первом случае для обработки разбивать надо, то во втором как раз не надо.

Ваш подход бажный, некорректно обрабатывает текст и вы не прошли собеседование про смайлики.

Вместо использования АПИ с функцией TextElement (которая реализована непонятно как, и, вероятно, опирается на реализацию базы юникодных символов в glibc) я предлагаю закодировать правила из стандарта (14 штук)
https://unicode.org/reports/tr29/#Extend
прямо на сишарпе в виде ДКА, как они там предлагают. Возможно библиотека ICU.NET
https://github.com/sillsdev/icu-dotnet
это делает, но в любом случае она обёртка над C++-кодом. И это плохо, потому что существуют pure C# операционки, куда это не влезет.

Но чисто сишарповая реализация неважна, это был так, вбоквел к обсуждению.

S> у вас же нет цели самостоятельно нормализовывать все композиции?


Если я правильно понимаю, то нормализация — это преобразование исходного потока байтов, то есть уже операция по его редактированию. Если есть такая операция, то должна быть обратная операция — денормализация (для движка Undo/Redo). Я не могу не делать нормализацию самостоятельно, если .Net Framework не предоставляет обратной операции. Это, конечно, в том случае, если я правильно понимаю слово "нормализация", как объединение букв f, f, i в одну лигатуру ffi всегда. Я сомневаюсь, что .Net framework делает такое объединение при нормализации. В моём представлении это происходит при рендеринге (а если не происходит, то рендеринг выполняется некорректно, лигатура не отрисовывается).

S> в арабском письме (и при применении различных "рукописных" шрифтов) отдельно стоящая буква пишется совсем не так, как в составе слова.


Ну, такая же проблема, как у лигатуры ffi, или нет?

Главное, что в результате разбора у меня будут не только TextElement, но и их связь с исходными позициями в потоках Codepoint и byte.

S> Как именно вы отслеживаете эту связь? Вот у вас лежит массив символов "внутренней кодировки". Три подряд из них соответствуют вот этому ffi, который один и тот же текстовый элемент. Как именно устроено вот это соответствие?


В виде .Net объекта. У меня "лежат" (будут лежать):
1) массив байтов
2) массив кодепоинтов
3) массив TextElement
4) массив моих "внутренних" символов
4-3) массив связок типа "4-3" с количеством объектов как в 4
3-2) массив связок типа "3-2" с количеством объектов как в 3
2-1) не хранится, потому что может быть вычислен алгоритмически на лету.

При создании символов массива 4 я могу провести унификацию, преобразовать ударения в свойства этих символов.
То есть, если TextElement имели значения "а" и "а́", то им будут соответствовать два объекта "а" и "а" класса "4", но с разными значениями свойства "ModernRussianStress" (false и true).

Тип char не даст мне хранить при себе свойства, потому что он слишком простой для этого.

S> вы хотите уметь работать с ударениями (для которых, вообще говоря, достаточно выучить ровно один combining diacritic character) в кириллице


Кириллицей так же записываются церковные книги. А в староцерковном языке три типа ударений — "оксия", "вария", "камора". Вы просто не любите русских и стремитесь уничтожить наше духовное наследие.

Ещё эта фигня с необязательностью точек над ё. Нужен будет специальный код, который правильно угадывает букву "ё", но помечает её признаком "WithoutPointsOverIt".