Python-Docx:识别斜体段落

Python-Docx: Identify an italicized paragraph

现在,下面的代码应该是通过一个word文件,检查第一个字符是否是一个管道字符,然后将段落的索引号保存到slide_list中,用于管道字符的每次出现.这意味着将斜体管道字符添加到他们自己的列表中。 (使用最新的python-docx v0.8.11)

import docx
doc = docx.Document(r'C:\example.docx')

slide_list = []
italicized_list = []
slide_char = '|'

for i, paragraph in enumerate(doc.paragraphs):
    #Avoids IndexError from blank paragraphs
    if not paragraph.text:
        continue

    #Looks for slide_char in paragraph, saves position of paragraph to slide_list
    if paragraph.text[0] == slide_char:
        for run in paragraph.runs:
            for char in run.text[:50]:
                #Checks whether char is italicized and skips if so
                if char == slide_char and not run.italic:
                    slide_list.append(i)
                elif char == slide_char:
                    italicized_list.append(i)

看起来不错吧?不幸的是,这不能可靠地工作。一方面,当整个段落为斜体时,它无法将管道字符识别为斜体。另一方面,在某些文件中,随机地,它甚至无法识别斜体运行。

我将附上 test file 1 where the first paragraph fails to be recognized as italicized by the code, and test file 2 代码无法识别任何斜体管道字符的地方。

我认为简短的回答是您正在寻找 有效 字体(字符格式),而 run.italic 只会给您 显式(直接应用)字体。

这里有一些讨论可以帮助您更好地理解正在发生的事情。简而言之,字符格式由 样式层次结构 决定,在概念上类似于级联样式表 (CSS) 在 HTML 中的工作方式。您可以通过搜索 python-docx effective fontpython-docx style hierarchy.

找到有关此主题的更多信息

如果您查看 test_file_.docx 中第一段的 XML:

  <w:body>
    <w:p w14:paraId="12B2FDB3" w14:textId="685EC091" w:rsidR="00F54C1D" w:rsidRPr="008E07F1" w:rsidRDefault="00F54C1D" w:rsidP="00491AE4">
      <w:pPr>
        <w:spacing w:after="0"/>
        <w:rPr>
          <w:rStyle w:val="SchwacheHervorhebung"/>
        </w:rPr>
      </w:pPr>
      <w:r w:rsidRPr="008E07F1">
        <w:rPr>
          <w:rStyle w:val="SchwacheHervorhebung"/>
        </w:rPr>
        <w:t>|</w:t>
      </w:r>
      <w:r w:rsidR="00A20FF1" w:rsidRPr="008E07F1">
        <w:rPr>
          <w:rStyle w:val="SchwacheHervorhebung"/>
        </w:rPr>
        <w:t xml:space="preserve"> Titelblatt</w:t>
      </w:r>
    </w:p>

您可以看到所有运行都分配了字符样式 "SchwacheHervohebung"(“弱突出显示”)。我希望如果您检查该样式,您会发现它是斜体字符格式的来源。

第二个文档大体上是相同的,只是它偶尔会在某些行和某些段落中应用明确的斜体格式:

    <w:p w14:paraId="3855D66E" w14:textId="7473C028" w:rsidR="006F7489" w:rsidRDefault="001D1280" w:rsidP="006F7489">
      <w:pPr>
        <w:rPr>
          <w:rStyle w:val="SchwacheHervorhebung"/>
          <w:i w:val="0"/>
          <w:iCs w:val="0"/>
        </w:rPr>
      </w:pPr>
      <w:r>
        <w:rPr>
          <w:rStyle w:val="SchwacheHervorhebung"/>
          <w:iCs w:val="0"/>
        </w:rPr>
        <w:t xml:space="preserve">| | </w:t>
      </w:r>
      <w:r w:rsidR="00F93AA1">
        <w:rPr>
          <w:rStyle w:val="SchwacheHervorhebung"/>
          <w:i w:val="0"/>
          <w:iCs w:val="0"/>
        </w:rPr>
        <w:t>Frühsozialismus</w:t>
      </w:r>
    </w:p>

w:p/w:pPr/w:rPr/w:i 处应用的斜体格式是 默认段落格式 并且将应用于段落中没有明确与之矛盾的运行。这里因为它是 <w:i w:val="0"/>0 等同于“false”),所以它“关闭”该段落中没有斜体的任何运行的样式影响的斜体格式。在这种情况下,两次运行 关闭斜体,因此它们的设置有效(即使它与最近的祖先设置相同)。