Skip to content

Commit 19175ad

Browse files
committed
comments: add Comment.paragraphs
Actual implementation is primarily inherited from `BlockItemContainer`, but support for those operations must be present in `CT_Comment` and it's worth testing explicitly.
1 parent cfb87e7 commit 19175ad

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

features/cmt-props.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ Feature: Get comment properties
2424
Then comment.timestamp is the date and time the comment was authored
2525

2626

27-
@wip
2827
Scenario: Comment.paragraphs[0].text
2928
Given a Comment object
3029
When I assign para_text = comment.paragraphs[0].text

src/docx/oxml/comments.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
from __future__ import annotations
44

55
import datetime as dt
6+
from typing import TYPE_CHECKING, Callable
67

78
from docx.oxml.simpletypes import ST_DateTime, ST_DecimalNumber, ST_String
89
from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, RequiredAttribute, ZeroOrMore
910

11+
if TYPE_CHECKING:
12+
from docx.oxml.table import CT_Tbl
13+
from docx.oxml.text.paragraph import CT_P
14+
1015

1116
class CT_Comments(BaseOxmlElement):
1217
"""`w:comments` element, the root element for the comments part.
@@ -36,6 +41,7 @@ class CT_Comment(BaseOxmlElement):
3641
content, including multiple rich-text paragraphs, hyperlinks, images, and tables.
3742
"""
3843

44+
# -- attributes on `w:comment` --
3945
id: int = RequiredAttribute("w:id", ST_DecimalNumber) # pyright: ignore[reportAssignmentType]
4046
author: str = RequiredAttribute("w:author", ST_String) # pyright: ignore[reportAssignmentType]
4147
initials: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
@@ -44,3 +50,20 @@ class CT_Comment(BaseOxmlElement):
4450
date: dt.datetime | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
4551
"w:date", ST_DateTime
4652
)
53+
54+
# -- children --
55+
56+
p = ZeroOrMore("w:p", successors=())
57+
tbl = ZeroOrMore("w:tbl", successors=())
58+
59+
# -- type-declarations for methods added by metaclass --
60+
61+
add_p: Callable[[], CT_P]
62+
p_lst: list[CT_P]
63+
tbl_lst: list[CT_Tbl]
64+
_insert_tbl: Callable[[CT_Tbl], CT_Tbl]
65+
66+
@property
67+
def inner_content_elements(self) -> list[CT_P | CT_Tbl]:
68+
"""Generate all `w:p` and `w:tbl` elements in this comment."""
69+
return self.xpath("./w:p | ./w:tbl")

tests/test_comments.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,18 @@ def it_knows_the_date_and_time_it_was_authored(self, comments_part_: Mock):
123123

124124
assert comment.timestamp == dt.datetime(2023, 10, 1, 12, 34, 56, tzinfo=dt.timezone.utc)
125125

126+
def it_provides_access_to_the_paragraphs_it_contains(self, comments_part_: Mock):
127+
comment_elm = cast(
128+
CT_Comment,
129+
element('w:comment{w:id=42}/(w:p/w:r/w:t"First para",w:p/w:r/w:t"Second para")'),
130+
)
131+
comment = Comment(comment_elm, comments_part_)
132+
133+
paragraphs = comment.paragraphs
134+
135+
assert len(paragraphs) == 2
136+
assert [para.text for para in paragraphs] == ["First para", "Second para"]
137+
126138
# -- fixtures --------------------------------------------------------------------------------
127139

128140
@pytest.fixture

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy