Wykryj brakujące glify w tekście


10

Napisałem appindicator Python3, który wywołuje fortunei przechwytuje dane wyjściowe do wyświetlenia w powiadomieniu na ekranie.

Niektóre fortuny zawierają kwadraty z liczbą szesnastkową, gdy odpowiedni glif nie istnieje w bieżącej czcionce. Każdy kwadrat reprezentuje szesnastkowy punkt kodowy Unicode brakującego glifu.

Chcę usunąć tekst szesnastkowy przed wyświetleniem użytkownikowi. Miałem nadzieję znaleźć API Pythona, które pozwoliłoby mi sprawdzić tekst, znak po znaku, aby ustalić coś podobnego char.isValidCodePoint()lub podobnego, ale nie mogę znaleźć jako takiego.

Znalazłem możliwe rozwiązanie, które chciałem zbadać tutaj, ale po zainstalowaniu fonttoolsza pomocą terminala mój program Python nie mógł zaimportować fonttools/fontTools.

Wszelkie pomysły - przy użyciu interfejsu API języka Python lub wywoływania terminala?

Aktualizacja nr 1: Od tego czasu zdałem sobie sprawę, że fonttoolsprzykładowy kod z powyższego łącza nie będzie dla mnie działał, ponieważ jest to Python2. fonttoolsPodejrzewam, że jeśli można by jakoś użyć, mógłbym wywołać interpreter Python2 z mojego skryptu Python3.

Aktualizacja nr 2: Po wielu lekturach (patrz odnośniki poniżej) znalazłem, fc-matchale nie zawsze może jednoznacznie zidentyfikować używaną czcionkę. Otrzymuję bieżącą czcionkę w Pythonie:

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

powodując Ubuntu 11. Podając ten wynik pango-viewwraz ze znakiem szesnastkowym, otrzymuję listę czcionek, w tym Ubuntu. Według mnie, jeśli glif NIE był renderowany przez czcionkę, czcionka nie powinna pojawić się w wyniku z pango-view!

Bibliografia:

Odpowiedzi:


0

Jest to inne podejście niż to, do czego zmierzałeś, ale być może możesz po prostu użyć języka Python str.replace()lub re.sub()metod, aby przeanalizować ciągi szesnastkowe z treści tekstu. to znaczy:

Jeśli hex jest przewidywalny:

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

Lub jeśli chcesz dopasować dowolne znaki szesnastkowe z wyrażeniem regularnym:

import re

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

Więcej dobrych dyskusji na temat tej strategii


Można podać alternatywne opcje, ale myślę, że możesz znacznie poprawić swoją odpowiedź, 1) dodając krótki przykładowy kod 2) opisujący możliwe PRO i CON z oryginalnego proponowanego rozwiązania i twojego.
lpanebr

1
Nie próbuję krytykować oryginalnego rozwiązania, więc nie wiem, czy porównanie PRO / CON przyda się tutaj. Do odpowiedzi dodałem jednak przykłady kodu dla moich sugestii.
Christopher Hunter,

@ChristopherHunter: Tekst pochodzący z fortuny jest zwykłym tekstem i pojawia się dopiero po wyrenderowaniu tego tekstu w systemie szesnastkowym (i to dla mnie za późno, by złapać i przetworzyć, jak sugerujesz).
Bernmeister,

0

Silnik kształtujący Unicode

Użyj silnika kształtującego Unicode, takiego jak Harfbuzz, aby wykryć brakujący glif. Oto działający przykład:

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

Wynik

registered
.notdef

Tutaj dane wyjściowe w IDLE3 podczas sprawdzania:

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

Sprawdź poprawną ścieżkę czcionki, właśnie wybrałem pierwszą, którą zobaczyłem na bieżącym komputerze.

Uwaga:

  • Jestem spokojny, że Gtk / Pango mają podobną funkcję, Pango już przełączył się na używanie Harfbuzz na niskim poziomie. Jednak nie mam doświadczenia w korzystaniu z takiej biblioteki.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.