Skip to content

Commit

Permalink
oxml: add .inner_content_elements props
Browse files Browse the repository at this point in the history
  • Loading branch information
scanny committed Nov 3, 2023
1 parent f46751f commit 24e4c1b
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/docx/oxml/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,12 @@ def clear_content(self):
"""
for content_elm in self.xpath("./*[not(self::w:sectPr)]"):
self.remove(content_elm)

@property
def inner_content_elements(self) -> List[CT_P | CT_Tbl]:
"""Generate all `w:p` and `w:tbl` elements in this document-body.
Elements appear in document order. Elements shaded by nesting in a `w:ins` or
other "wrapper" element will not be included.
"""
return self.xpath("./w:p | ./w:tbl")
9 changes: 9 additions & 0 deletions src/docx/oxml/section.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ class CT_HdrFtr(BaseOxmlElement):
p = ZeroOrMore("w:p", successors=())
tbl = ZeroOrMore("w:tbl", successors=())

@property
def inner_content_elements(self) -> List[CT_P | CT_Tbl]:
"""Generate all `w:p` and `w:tbl` elements in this header or footer.
Elements appear in document order. Elements shaded by nesting in a `w:ins` or
other "wrapper" element will not be included.
"""
return self.xpath("./w:p | ./w:tbl")


class CT_HdrFtrRef(BaseOxmlElement):
"""`w:headerReference` and `w:footerReference` elements."""
Expand Down
9 changes: 9 additions & 0 deletions src/docx/oxml/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,15 @@ def grid_span(self, value):
tcPr = self.get_or_add_tcPr()
tcPr.grid_span = value

@property
def inner_content_elements(self) -> List[CT_P | CT_Tbl]:
"""Generate all `w:p` and `w:tbl` elements in this document-body.
Elements appear in document order. Elements shaded by nesting in a `w:ins` or
other "wrapper" element will not be included.
"""
return self.xpath("./w:p | ./w:tbl")

def iter_block_items(self):
"""Generate a reference to each of the block-level content elements in this
cell, in the order they appear."""
Expand Down
19 changes: 19 additions & 0 deletions tests/oxml/test_document.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Unit-test suite for `docx.oxml.document` module."""

from __future__ import annotations

from typing import cast

from docx.oxml.document import CT_Body
from docx.oxml.table import CT_Tbl
from docx.oxml.text.paragraph import CT_P

from ..unitutil.cxml import element


class DescribeCT_Body:
"""Unit-test suite for selected units of `docx.oxml.document.CT_Body`."""

def it_knows_its_inner_content_block_item_elements(self):
body = cast(CT_Body, element("w:body/(w:tbl, w:p,w:p)"))
assert [type(e) for e in body.inner_content_elements] == [CT_Tbl, CT_P, CT_P]
19 changes: 19 additions & 0 deletions tests/oxml/test_section.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Unit-test suite for `docx.oxml.section` module."""

from __future__ import annotations

from typing import cast

from docx.oxml.section import CT_HdrFtr
from docx.oxml.table import CT_Tbl
from docx.oxml.text.paragraph import CT_P

from ..unitutil.cxml import element


class DescribeCT_HdrFtr:
"""Unit-test suite for selected units of `docx.oxml.section.CT_HdrFtr`."""

def it_knows_its_inner_content_block_item_elements(self):
hdr = cast(CT_HdrFtr, element("w:hdr/(w:tbl,w:tbl,w:p)"))
assert [type(e) for e in hdr.inner_content_elements] == [CT_Tbl, CT_Tbl, CT_P]
9 changes: 8 additions & 1 deletion tests/oxml/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

from __future__ import annotations

from typing import cast

import pytest

from docx.exceptions import InvalidSpanError
from docx.oxml.parser import parse_xml
from docx.oxml.table import CT_Row, CT_Tc
from docx.oxml.table import CT_Row, CT_Tbl, CT_Tc
from docx.oxml.text.paragraph import CT_P

from ..unitutil.cxml import element, xml
from ..unitutil.file import snippet_seq
Expand Down Expand Up @@ -102,6 +105,10 @@ def it_can_extend_its_horz_span_to_help_merge(
]
assert tc.vMerge == vMerge

def it_knows_its_inner_content_block_item_elements(self):
tc = cast(CT_Tc, element("w:tc/(w:p,w:tbl,w:p)"))
assert [type(e) for e in tc.inner_content_elements] == [CT_P, CT_Tbl, CT_P]

def it_can_swallow_the_next_tc_help_merge(self, swallow_fixture):
tc, grid_width, top_tc, tr, expected_xml = swallow_fixture
tc._swallow_next_tc(grid_width, top_tc)
Expand Down

0 comments on commit 24e4c1b

Please sign in to comment.