|
|
|
|
|
"""Block item container, used by body, cell, header, etc. |
|
|
|
Block level items are things like paragraph and table, although there are a few other |
|
specialized ones like structured document tags. |
|
""" |
|
|
|
from __future__ import annotations |
|
|
|
from typing import TYPE_CHECKING, Iterator |
|
|
|
from typing_extensions import TypeAlias |
|
|
|
from docx.oxml.table import CT_Tbl |
|
from docx.oxml.text.paragraph import CT_P |
|
from docx.shared import StoryChild |
|
from docx.text.paragraph import Paragraph |
|
|
|
if TYPE_CHECKING: |
|
import docx.types as t |
|
from docx.oxml.document import CT_Body |
|
from docx.oxml.section import CT_HdrFtr |
|
from docx.oxml.table import CT_Tc |
|
from docx.shared import Length |
|
from docx.styles.style import ParagraphStyle |
|
from docx.table import Table |
|
|
|
BlockItemElement: TypeAlias = "CT_Body | CT_HdrFtr | CT_Tc" |
|
|
|
|
|
class BlockItemContainer(StoryChild): |
|
"""Base class for proxy objects that can contain block items. |
|
|
|
These containers include _Body, _Cell, header, footer, footnote, endnote, comment, |
|
and text box objects. Provides the shared functionality to add a block item like a |
|
paragraph or table. |
|
""" |
|
|
|
def __init__(self, element: BlockItemElement, parent: t.ProvidesStoryPart): |
|
super(BlockItemContainer, self).__init__(parent) |
|
self._element = element |
|
|
|
def add_paragraph(self, text: str = "", style: str | ParagraphStyle | None = None) -> Paragraph: |
|
"""Return paragraph newly added to the end of the content in this container. |
|
|
|
The paragraph has `text` in a single run if present, and is given paragraph |
|
style `style`. |
|
|
|
If `style` is |None|, no paragraph style is applied, which has the same effect |
|
as applying the 'Normal' style. |
|
""" |
|
paragraph = self._add_paragraph() |
|
if text: |
|
paragraph.add_run(text) |
|
if style is not None: |
|
paragraph.style = style |
|
return paragraph |
|
|
|
def add_table(self, rows: int, cols: int, width: Length) -> Table: |
|
"""Return table of `width` having `rows` rows and `cols` columns. |
|
|
|
The table is appended appended at the end of the content in this container. |
|
|
|
`width` is evenly distributed between the table columns. |
|
""" |
|
from docx.table import Table |
|
|
|
tbl = CT_Tbl.new_tbl(rows, cols, width) |
|
self._element._insert_tbl(tbl) |
|
return Table(tbl, self) |
|
|
|
def iter_inner_content(self) -> Iterator[Paragraph | Table]: |
|
"""Generate each `Paragraph` or `Table` in this container in document order.""" |
|
from docx.table import Table |
|
|
|
for element in self._element.inner_content_elements: |
|
yield (Paragraph(element, self) if isinstance(element, CT_P) else Table(element, self)) |
|
|
|
@property |
|
def paragraphs(self): |
|
"""A list containing the paragraphs in this container, in document order. |
|
|
|
Read-only. |
|
""" |
|
return [Paragraph(p, self) for p in self._element.p_lst] |
|
|
|
@property |
|
def tables(self): |
|
"""A list containing the tables in this container, in document order. |
|
|
|
Read-only. |
|
""" |
|
from docx.table import Table |
|
|
|
return [Table(tbl, self) for tbl in self._element.tbl_lst] |
|
|
|
def _add_paragraph(self): |
|
"""Return paragraph newly added to the end of the content in this container.""" |
|
return Paragraph(self._element.add_p(), self) |
|
|