Обнаружить пропущенные глифы в тексте

10

Я написал приложение Python3, которое вызывает fortuneи записывает вывод для отображения в экранном уведомлении.

Некоторые состояния содержат квадраты с шестнадцатеричным числом, когда соответствующий глиф не существует в текущем шрифте. Каждый квадрат представляет собой шестнадцатеричный код Unicode для отсутствующего глифа.

Я хочу удалить шестнадцатеричный текст перед отображением для пользователя. Я надеялся найти какой-нибудь Python API, который позволил бы мне проверять текст, символ за символом, чтобы определить что-то похожее char.isValidCodePoint()или похожее, но я не могу найти как таковой.

Я нашел возможное решение, которое я хотел бы найти здесь, но после установки fonttoolsчерез терминал моя программа на Python не смогла импортировать fonttools/fontTools.

Есть идеи - использовать Python API или вызвать терминал?

Обновление № 1: с тех пор я понял, что fonttoolsпример кода по ссылке выше не будет работать для меня, так как это Python2. Я полагаю, что если fonttoolsбы можно было как-то использовать, я мог бы вызвать интерпретатор Python2 из моего скрипта Python3.

Обновление № 2: После большого прочтения (см. Ссылки ниже) я с тех пор нашел, fc-matchно он не всегда может однозначно идентифицировать используемый шрифт. Я получаю текущий шрифт в Python:

from gi.repository import Gio
fontName = Gio.Settings( "org.gnome.desktop.interface" ).get_string( "font-name" )

в результате чего Ubuntu 11. Передав этот результат pango-viewвместе с шестнадцатеричным символом, я получаю список шрифтов, включая Ubuntu. На мой взгляд, если глиф НЕ отрисован шрифтом, шрифт не должен появляться в результате из pango-view!

Ссылки:

Bernmeister
источник

Ответы:

0

Это другой подход по сравнению с тем, к которому вы шли, но, возможно, вы могли бы просто использовать python str.replace()или re.sub()методы для анализа шестнадцатеричных строк в вашем текстовом теле. то есть:

Если гекс предсказуем:

originalText = "\xc3\xa5Test"
filteredText = originalText.replace("\xc3\xa5", "")

Или, если вам нужно сопоставить любые шестнадцатеричные символы с регулярным выражением:

import re

originalText = "\xc3\xa5Test"
filteredText = re.sub(r'[^\x00-\x7f]', r'', originalText)

Более хорошее обсуждение этой стратегии

Кристофер Хантер
источник
Можно давать альтернативные варианты, но я думаю, что вы могли бы значительно улучшить свой ответ, 1) добавив краткий пример кода 2) описав возможные "за" и "против" из исходного пост-предложенного решения и вашего.
lpanebr
1
Я не пытаюсь критиковать исходное решение, поэтому не знаю, поможет ли здесь сравнение PRO / CON. Однако я добавил примеры кода для моих предложений к ответу.
Кристофер Хантер
@ChristopherHunter: текст, получаемый из fortune, представляет собой простой текст, и только когда этот текст визуализируется, появляется шестнадцатеричный код (и это слишком поздно для меня, чтобы перехватить и обработать, как вы предлагаете).
Бернмейстер
0

Unicode Shaping Engine

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

from pyharfbuzz import shape
f = "/usr/local/lib/python3.6/site-packages/werkzeug/debug/shared/ubuntu.ttf"
t = "®"
s = shape(f, t)
print(s[1]['glyph_name'])
t = "რ"
s = shape(f, t)
print(s[1]['glyph_name'])

Вывод

registered
.notdef

Вот вывод в IDLE3 при проверке:

>>> t = "®"
>>> s = shape(f, t)
>>> s
[{'cluster': 0, 'glyph_name': 'registered', 'x_advance': 29.453125, 'y_advance': 0.0, 'x_offset': 0.0, 'y_offset': 0.0}]
>>> t = "რ"
>>> s = shape(f, t)
>>> s
[{'cluster': 0, 'glyph_name': '.notdef', 'x_advance': 36.0, 'y_advance': 0.0, 'x_offset': 0.0, 'y_offset': 0.0}]

Проверьте правильность пути к шрифту, я просто выбрал первый, который увидел в моей текущей машине.

Замечания:

  • Я уверен, что Gtk / Pango имеют похожую функцию, Pango уже переключился на использование Harfbuzz на низком уровне. Однако у меня нет опыта использования такой библиотеки.
user.dz
источник