在 run.text 中看不到特殊字体字符(有时)



我有一个word文档,将一些Wingdings字符与Cambria文本混合在一起。当我查看运行时,我有时会看到长度为 1 的 run.text,并且字符是十六进制,例如 0xf063。run.font.name 是例如Wingdings 2。这是意料之中的。但是我经常看到一个空的run.text(字体名称仍然是Wingdings(。尽管如此,字符必须在那里,因为当我将运行附加到新段落时,我可以在 Word 中看到它们,至少当我刚刚通过它们时。然而,当我复制运行时(尽我所能(,字符丢失了,可能是因为,当我重复运行时,我错过了一些东西。所以我的问题是,当run.text为空时,字符存储在哪里,当我复制这样的运行时,我必须观察什么。 但是,如果 run.text 不为空,则在运行复制期间不会丢失字符。因此,问题起源于读取文档时,有时字符在 run.text 中,有时在其他地方。哪一个对我来说是不可预测的。

我只是想到解压缩文档并查看文档.xml。我在那里看到

<w:r w:rsidRPr="00946796"> 
<w:rPr> <w:color w:val="EE9512"/> 
<w:lang w:val="de-DE"/> 
</w:rPr> 
<w:t xml:space="preserve">YYYYYYY 
</w:t> 
</w:r> 
<w:r w:rsidR="009E034B" w:rsidRPr="00695B07"> 
<w:rPr> 
<w:rFonts w:ascii="Wingdings 3" w:hAnsi="Wingdings 3"/> 
<w:color w:val="EE9512"/> 
</w:rPr> 
<w:sym w:font="Wingdings 2" w:char="F038"/> 
</w:r> 

因此,当 run.text 为空时,字符位于 w:sym 元素中,否则位于 w:t 元素中。

您可以在此处将特殊字符视为"符号":

<w:r w:rsidR="009E034B" w:rsidRPr="00695B07"> 
<w:rPr> 
<w:rFonts w:ascii="Wingdings 3" w:hAnsi="Wingdings 3"/> 
<w:color w:val="EE9512"/> 
</w:rPr> 
<w:sym w:font="Wingdings 2" w:char="F038"/>  <!-- <<==== this line -->
</w:r>

我没有深入研究这一点,但我希望这里的区别在于,这种"字体"中的字形不是它们出现的 unicode 代码点的风格化版本。

例如,此字体中没有"A","B","C"字符,这些位置由箭头或其他东西代替。

我想这种区别很重要,因为如果当前机器上没有安装 Windings 2,则无法通过替换类似的字体来获得良好的结果。因此,至少此符号的字体替换行为与常规字符的字体替换行为不同。

目前尚不支持运行中的符号,因此需要使用lxml调用来访问这些元素,例如:

from docx.oxml.ns import qn
syms = run._r.xpath("./w:sym")
for sym in syms:
print("font == %s" % sym.get(qn("w:font")))
print("char == %s" % sym.get(qn("w:char")))

再过几个小时,我想我看到了完整的画面。首先,正如scanny上面所写的,python-docx根本不处理w:sym元素(还?(,所以这些元素在阅读docx后会丢失,除非你求助于lxml。那么,为什么我有时会在w:t中看到一个Wingdings字符,有时在w:sym中看到?好吧,如果我使用单词符号选择器(一个包含字体中所有字符的窗口,您可以在其中选择一个字符,然后按底部的"插入"(,那么您将得到一个 w:sym 元素。如果您只是将字体设置为Wingdings,然后在键盘上键入合适的字符(例如,8表示Wingdings 2圆圈,里面有点(,那么您将获得一个w:t元素。 因此,我设法删除了所有 w:sym 元素。要确定"合适"的字符,请在谷歌上搜索"Wingdings翻译器"。

最新更新