Détecter les glyphes manquants dans le texte

10

J'ai écrit un indicateur Python3 qui appelle fortuneet capture la sortie pour l'afficher dans la notification à l'écran.

Certaines fortunes contiennent des carrés avec un nombre hexadécimal lorsque le glyphe correspondant n'existe pas dans la police actuelle. Chaque carré est la représentation du point de code Unicode hexadécimal pour le glyphe manquant.

Je souhaite supprimer le texte hexadécimal avant de l'afficher à l'utilisateur. J'espérais trouver une API Python qui me permettrait d'inspecter le texte, caractère par caractère, pour déterminer quelque chose de similaire char.isValidCodePoint()ou similaire, mais je ne peux pas le trouver en tant que tel.

J'ai trouvé une solution possible que je voulais étudier ici, mais après l'installation fonttoolsvia le terminal, mon programme Python n'a pas pu importer fonttools/fontTools.

Des idées - en utilisant l'API Python ou en appelant à un terminal?

Mise à jour # 1: J'ai depuis réalisé que l' fonttoolsexemple de code du lien ci-dessus ne fonctionnera pas pour moi car il s'agit de Python2. Je suppose que si je fonttoolspouvais en quelque sorte être utilisé, je pourrais invoquer un interpréteur Python2 à partir de mon script Python3.

Mise à jour # 2: Après beaucoup de lecture (voir références ci-dessous), j'ai depuis trouvé fc-matchmais il ne peut pas toujours identifier de manière unique la police utilisée. J'obtiens la police actuelle en Python:

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

résultant en Ubuntu 11. En passant ce résultat pango-viewavec le caractère hexadécimal, j'obtiens une liste de polices, y compris Ubuntu. À mon avis, si le glyphe n'était PAS rendu par la police, la police ne devrait pas apparaître dans le résultat de pango-view!

Références:

Bernmeister
la source

Réponses:

0

Il s'agit d'une approche différente de celle que vous utilisiez avec cela, mais vous pourriez peut-être simplement utiliser des méthodes str.replace()ou des pythons re.sub()pour analyser les chaînes hexidécimales de votre corps de texte. c'est à dire:

Si l'hex est prévisible:

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

Ou si vous devez faire correspondre des caractères hexadécimaux avec une expression régulière:

import re

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

Discussion plus approfondie sur cette stratégie

Christopher Hunter
la source
C'est OK pour donner des options alternatives, mais je pense que vous pourriez améliorer considérablement votre réponse en 1) ajoutant un court exemple de code 2) décrivant les avantages et les inconvénients possibles de la solution proposée après la proposition d'origine et la vôtre.
lpanebr
1
Je n'essaie pas de critiquer la solution originale, donc je ne sais pas si une comparaison PRO / CON sera utile ici. J'ai cependant ajouté des exemples de code pour mes suggestions à la réponse.
Christopher Hunter
@ChristopherHunter: Le texte qui vient de la fortune est du texte brut et ce n'est que lorsque ce texte est rendu que l'hexadécimal apparaît (et c'est trop tard pour que je le capture et le traite comme vous le suggérez).
Bernmeister
0

Moteur de mise en forme Unicode

Utilisez un moteur de mise en forme Unicode comme Harfbuzz pour détecter les glyphes manquants. Voici un exemple de travail:

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'])

Production

registered
.notdef

Voici la sortie dans IDLE3 lors de la vérification:

>>> 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}]

Vérifiez le chemin de police correct, je viens de choisir le premier que j'ai vu dans ma machine actuelle.

Remarque:

  • Je suis sûr que Gtk / Pango ont une fonction similaire, Pango est déjà passé à utiliser Harfbuzz à bas niveau. Cependant, je n'ai aucune expérience en utilisant une telle lib.
user.dz
la source