我编写了一个 Python3 appindicator,它调用fortune
并捕获输出以在屏幕通知中显示。
当当前字体中不存在相应的字形时,某些运势会包含带有十六进制数字的方块。每个方块都是缺失字形的十六进制 Unicode 代码点的表示。
我想在向用户显示之前删除十六进制文本。我希望找到一些 Python API,让我逐个字符地检查文本,以确定类似char.isValidCodePoint()
或类似的内容,但我找不到这样的 API。
我找到了一个可能的解决方案,我想研究一下这里但是fonttools
通过终端安装后,我的 Python 程序无法导入fonttools/fontTools
。
有什么想法吗——使用 Python API 还是调用终端?
更新 #1:我后来意识到fonttools
上面链接中的示例代码对我来说不起作用,因为它是 Python2。我想如果fonttools
可以以某种方式使用,我可以从我的 Python3 脚本中调用 Python2 解释器。
更新 #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
!
参考:
答案1
这与您之前所采用的方法不同,但也许您可以使用 pythonstr.replace()
或re.sub()
方法从文本主体中解析出十六进制字符串。即:
如果十六进制是可预测的:
originalText = "\xc3\xa5Test"
filteredText = originalText.replace("\xc3\xa5", "")
或者如果您需要使用正则表达式匹配任何十六进制字符:
import re
originalText = "\xc3\xa5Test"
filteredText = re.sub(r'[^\x00-\x7f]', r'', originalText)
答案2
Unicode 整形引擎
使用 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。不过,我没有使用此类库的经验。
答案3
已经想出解决方案了……最初我以为财富文本文件不包含十六进制字符。结果发现这是错误的。因此,当我意识到这一点时,我想出了以下解决方案:
import codecs
fortune = <call the fortune program>
output = ""
for c in fortune:
if codecs.encode( str.encode( c ), "hex" ) == b'07':
continue
output += c
print( output )