ps-python-docx 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. docx/__init__.py +68 -0
  2. docx/api.py +37 -0
  3. docx/blkcntnr.py +101 -0
  4. docx/comments.py +163 -0
  5. docx/dml/__init__.py +0 -0
  6. docx/dml/color.py +112 -0
  7. docx/document.py +275 -0
  8. docx/drawing/__init__.py +59 -0
  9. docx/enum/__init__.py +0 -0
  10. docx/enum/base.py +150 -0
  11. docx/enum/dml.py +103 -0
  12. docx/enum/section.py +86 -0
  13. docx/enum/shape.py +19 -0
  14. docx/enum/style.py +452 -0
  15. docx/enum/table.py +136 -0
  16. docx/enum/text.py +367 -0
  17. docx/exceptions.py +18 -0
  18. docx/image/__init__.py +23 -0
  19. docx/image/bmp.py +43 -0
  20. docx/image/constants.py +172 -0
  21. docx/image/exceptions.py +13 -0
  22. docx/image/gif.py +38 -0
  23. docx/image/helpers.py +86 -0
  24. docx/image/image.py +234 -0
  25. docx/image/jpeg.py +425 -0
  26. docx/image/png.py +253 -0
  27. docx/image/tiff.py +289 -0
  28. docx/opc/__init__.py +0 -0
  29. docx/opc/constants.py +306 -0
  30. docx/opc/coreprops.py +142 -0
  31. docx/opc/exceptions.py +12 -0
  32. docx/opc/oxml.py +247 -0
  33. docx/opc/package.py +219 -0
  34. docx/opc/packuri.py +109 -0
  35. docx/opc/part.py +247 -0
  36. docx/opc/parts/__init__.py +0 -0
  37. docx/opc/parts/coreprops.py +48 -0
  38. docx/opc/phys_pkg.py +119 -0
  39. docx/opc/pkgreader.py +254 -0
  40. docx/opc/pkgwriter.py +115 -0
  41. docx/opc/rel.py +153 -0
  42. docx/opc/shared.py +31 -0
  43. docx/opc/spec.py +24 -0
  44. docx/oxml/__init__.py +261 -0
  45. docx/oxml/comments.py +124 -0
  46. docx/oxml/coreprops.py +298 -0
  47. docx/oxml/document.py +88 -0
  48. docx/oxml/drawing.py +11 -0
  49. docx/oxml/exceptions.py +10 -0
  50. docx/oxml/ns.py +109 -0
  51. docx/oxml/numbering.py +109 -0
  52. docx/oxml/parser.py +62 -0
  53. docx/oxml/section.py +537 -0
  54. docx/oxml/settings.py +138 -0
  55. docx/oxml/shape.py +299 -0
  56. docx/oxml/shared.py +52 -0
  57. docx/oxml/simpletypes.py +434 -0
  58. docx/oxml/styles.py +341 -0
  59. docx/oxml/table.py +977 -0
  60. docx/oxml/text/__init__.py +0 -0
  61. docx/oxml/text/font.py +333 -0
  62. docx/oxml/text/hyperlink.py +45 -0
  63. docx/oxml/text/pagebreak.py +278 -0
  64. docx/oxml/text/paragraph.py +106 -0
  65. docx/oxml/text/parfmt.py +392 -0
  66. docx/oxml/text/run.py +307 -0
  67. docx/oxml/xmlchemy.py +696 -0
  68. docx/package.py +110 -0
  69. docx/parts/__init__.py +0 -0
  70. docx/parts/comments.py +51 -0
  71. docx/parts/document.py +182 -0
  72. docx/parts/hdrftr.py +53 -0
  73. docx/parts/image.py +80 -0
  74. docx/parts/numbering.py +32 -0
  75. docx/parts/settings.py +50 -0
  76. docx/parts/story.py +95 -0
  77. docx/parts/styles.py +42 -0
  78. docx/parts/theme.py +53 -0
  79. docx/py.typed +0 -0
  80. docx/section.py +479 -0
  81. docx/settings.py +35 -0
  82. docx/shape.py +103 -0
  83. docx/shared.py +382 -0
  84. docx/styles/__init__.py +40 -0
  85. docx/styles/latent.py +198 -0
  86. docx/styles/style.py +264 -0
  87. docx/styles/styles.py +147 -0
  88. docx/table.py +537 -0
  89. docx/templates/default-comments.xml +12 -0
  90. docx/templates/default-docx-template/[Content_Types].xml +17 -0
  91. docx/templates/default-docx-template/_rels/.rels +7 -0
  92. docx/templates/default-docx-template/customXml/_rels/item1.xml.rels +4 -0
  93. docx/templates/default-docx-template/customXml/item1.xml +2 -0
  94. docx/templates/default-docx-template/customXml/itemProps1.xml +6 -0
  95. docx/templates/default-docx-template/docProps/app.xml +36 -0
  96. docx/templates/default-docx-template/docProps/core.xml +13 -0
  97. docx/templates/default-docx-template/docProps/thumbnail.jpeg +0 -0
  98. docx/templates/default-docx-template/word/_rels/document.xml.rels +11 -0
  99. docx/templates/default-docx-template/word/document.xml +11 -0
  100. docx/templates/default-docx-template/word/fontTable.xml +61 -0
  101. docx/templates/default-docx-template/word/numbering.xml +201 -0
  102. docx/templates/default-docx-template/word/settings.xml +53 -0
  103. docx/templates/default-docx-template/word/styles.xml +11844 -0
  104. docx/templates/default-docx-template/word/stylesWithEffects.xml +11800 -0
  105. docx/templates/default-docx-template/word/theme/theme1.xml +318 -0
  106. docx/templates/default-docx-template/word/webSettings.xml +5 -0
  107. docx/templates/default-footer.xml +27 -0
  108. docx/templates/default-header.xml +27 -0
  109. docx/templates/default-settings.xml +26 -0
  110. docx/templates/default-styles.xml +190 -0
  111. docx/templates/default.docx +0 -0
  112. docx/text/__init__.py +0 -0
  113. docx/text/font.py +472 -0
  114. docx/text/hyperlink.py +121 -0
  115. docx/text/pagebreak.py +104 -0
  116. docx/text/paragraph.py +173 -0
  117. docx/text/parfmt.py +286 -0
  118. docx/text/run.py +257 -0
  119. docx/text/tabstops.py +123 -0
  120. docx/theme.py +67 -0
  121. docx/types.py +34 -0
  122. ps_python_docx-1.3.0.dist-info/METADATA +77 -0
  123. ps_python_docx-1.3.0.dist-info/RECORD +126 -0
  124. ps_python_docx-1.3.0.dist-info/WHEEL +5 -0
  125. ps_python_docx-1.3.0.dist-info/licenses/LICENSE +20 -0
  126. ps_python_docx-1.3.0.dist-info/top_level.txt +1 -0
docx/oxml/text/run.py ADDED
@@ -0,0 +1,307 @@
1
+ """Custom element classes related to text runs (CT_R)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING, Callable, Iterator, List, cast
6
+
7
+ from docx.oxml.drawing import CT_Drawing
8
+ from docx.oxml.ns import qn
9
+ from docx.oxml.parser import OxmlElement
10
+ from docx.oxml.simpletypes import ST_BrClear, ST_BrType
11
+ from docx.oxml.text.font import CT_RPr
12
+ from docx.oxml.xmlchemy import BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne
13
+ from docx.shared import TextAccumulator
14
+
15
+ if TYPE_CHECKING:
16
+ from docx.oxml.shape import CT_Anchor, CT_Inline
17
+ from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak
18
+ from docx.oxml.text.parfmt import CT_TabStop
19
+
20
+ # ------------------------------------------------------------------------------------
21
+ # Run-level elements
22
+
23
+
24
+ class CT_R(BaseOxmlElement):
25
+ """`<w:r>` element, containing the properties and text for a run."""
26
+
27
+ add_br: Callable[[], CT_Br]
28
+ add_tab: Callable[[], CT_TabStop]
29
+ get_or_add_rPr: Callable[[], CT_RPr]
30
+ _add_drawing: Callable[[], CT_Drawing]
31
+ _add_t: Callable[..., CT_Text]
32
+
33
+ rPr: CT_RPr | None = ZeroOrOne("w:rPr") # pyright: ignore[reportAssignmentType]
34
+ br = ZeroOrMore("w:br")
35
+ cr = ZeroOrMore("w:cr")
36
+ drawing = ZeroOrMore("w:drawing")
37
+ t = ZeroOrMore("w:t")
38
+ tab = ZeroOrMore("w:tab")
39
+
40
+ def add_t(self, text: str) -> CT_Text:
41
+ """Return a newly added `<w:t>` element containing `text`."""
42
+ t = self._add_t(text=text)
43
+ if len(text.strip()) < len(text):
44
+ t.set(qn("xml:space"), "preserve")
45
+ return t
46
+
47
+ def add_drawing(self, inline_or_anchor: CT_Inline | CT_Anchor) -> CT_Drawing:
48
+ """Return newly appended `CT_Drawing` (`w:drawing`) child element.
49
+
50
+ The `w:drawing` element has `inline_or_anchor` as its child.
51
+ """
52
+ drawing = self._add_drawing()
53
+ drawing.append(inline_or_anchor)
54
+ return drawing
55
+
56
+ def clear_content(self) -> None:
57
+ """Remove all child elements except a `w:rPr` element if present."""
58
+ # -- remove all run inner-content except a `w:rPr` when present. --
59
+ for e in self.xpath("./*[not(self::w:rPr)]"):
60
+ self.remove(e)
61
+
62
+ @property
63
+ def inner_content_items(self) -> List[str | CT_Drawing | CT_LastRenderedPageBreak]:
64
+ """Text of run, possibly punctuated by `w:lastRenderedPageBreak` elements."""
65
+ from docx.oxml.text.pagebreak import CT_LastRenderedPageBreak
66
+
67
+ accum = TextAccumulator()
68
+
69
+ def iter_items() -> Iterator[str | CT_Drawing | CT_LastRenderedPageBreak]:
70
+ for e in self.xpath(
71
+ "w:br"
72
+ " | w:cr"
73
+ " | w:drawing"
74
+ " | w:lastRenderedPageBreak"
75
+ " | w:noBreakHyphen"
76
+ " | w:ptab"
77
+ " | w:t"
78
+ " | w:tab"
79
+ ):
80
+ if isinstance(e, (CT_Drawing, CT_LastRenderedPageBreak)):
81
+ yield from accum.pop()
82
+ yield e
83
+ else:
84
+ accum.push(str(e))
85
+
86
+ # -- don't forget the "tail" string --
87
+ yield from accum.pop()
88
+
89
+ return list(iter_items())
90
+
91
+ def insert_comment_range_end_and_reference_below(self, comment_id: int) -> None:
92
+ """Insert a `w:commentRangeEnd` and `w:commentReference` element after this run.
93
+
94
+ The `w:commentRangeEnd` element is the immediate sibling of this `w:r` and is followed by
95
+ a `w:r` containing the `w:commentReference` element.
96
+ """
97
+ self.addnext(self._new_comment_reference_run(comment_id))
98
+ self.addnext(OxmlElement("w:commentRangeEnd", attrs={qn("w:id"): str(comment_id)}))
99
+
100
+ def insert_comment_range_start_above(self, comment_id: int) -> None:
101
+ """Insert a `w:commentRangeStart` element with `comment_id` before this run."""
102
+ self.addprevious(OxmlElement("w:commentRangeStart", attrs={qn("w:id"): str(comment_id)}))
103
+
104
+ @property
105
+ def lastRenderedPageBreaks(self) -> List[CT_LastRenderedPageBreak]:
106
+ """All `w:lastRenderedPageBreaks` descendants of this run."""
107
+ return self.xpath("./w:lastRenderedPageBreak")
108
+
109
+ @property
110
+ def style(self) -> str | None:
111
+ """String contained in `w:val` attribute of `w:rStyle` grandchild.
112
+
113
+ |None| if that element is not present.
114
+ """
115
+ rPr = self.rPr
116
+ if rPr is None:
117
+ return None
118
+ return rPr.style
119
+
120
+ @style.setter
121
+ def style(self, style: str | None):
122
+ """Set character style of this `w:r` element to `style`.
123
+
124
+ If `style` is None, remove the style element.
125
+ """
126
+ rPr = self.get_or_add_rPr()
127
+ rPr.style = style
128
+
129
+ @property
130
+ def text(self) -> str:
131
+ """The textual content of this run.
132
+
133
+ Inner-content child elements like `w:tab` are translated to their text
134
+ equivalent.
135
+ """
136
+ return "".join(
137
+ str(e) for e in self.xpath("w:br | w:cr | w:noBreakHyphen | w:ptab | w:t | w:tab")
138
+ )
139
+
140
+ @text.setter
141
+ def text(self, text: str): # pyright: ignore[reportIncompatibleMethodOverride]
142
+ self.clear_content()
143
+ _RunContentAppender.append_to_run_from_text(self, text)
144
+
145
+ def _insert_rPr(self, rPr: CT_RPr) -> CT_RPr:
146
+ self.insert(0, rPr)
147
+ return rPr
148
+
149
+ def _new_comment_reference_run(self, comment_id: int) -> CT_R:
150
+ """Return a new `w:r` element with `w:commentReference` referencing `comment_id`.
151
+
152
+ Should look like this:
153
+
154
+ <w:r>
155
+ <w:rPr><w:rStyle w:val="CommentReference"/></w:rPr>
156
+ <w:commentReference w:id="0"/>
157
+ </w:r>
158
+
159
+ """
160
+ r = cast(CT_R, OxmlElement("w:r"))
161
+ rPr = r.get_or_add_rPr()
162
+ rPr.style = "CommentReference"
163
+ r.append(OxmlElement("w:commentReference", attrs={qn("w:id"): str(comment_id)}))
164
+ return r
165
+
166
+
167
+ # ------------------------------------------------------------------------------------
168
+ # Run inner-content elements
169
+
170
+
171
+ class CT_Br(BaseOxmlElement):
172
+ """`<w:br>` element, indicating a line, page, or column break in a run."""
173
+
174
+ type: str | None = OptionalAttribute( # pyright: ignore[reportAssignmentType]
175
+ "w:type", ST_BrType, default="textWrapping"
176
+ )
177
+ clear: str | None = OptionalAttribute("w:clear", ST_BrClear) # pyright: ignore
178
+
179
+ def __str__(self) -> str:
180
+ """Text equivalent of this element. Actual value depends on break type.
181
+
182
+ A line break is translated as "\n". Column and page breaks produce the empty
183
+ string ("").
184
+
185
+ This allows the text of run inner-content to be accessed in a consistent way
186
+ for all run inner-context text elements.
187
+ """
188
+ return "\n" if self.type == "textWrapping" else ""
189
+
190
+
191
+ class CT_Cr(BaseOxmlElement):
192
+ """`<w:cr>` element, representing a carriage-return (0x0D) character within a run.
193
+
194
+ In Word, this represents a "soft carriage-return" in the sense that it does not end
195
+ the paragraph the way pressing Enter (aka. Return) on the keyboard does. Here the
196
+ text equivalent is considered to be newline ("\n") since in plain-text that's the
197
+ closest Python equivalent.
198
+
199
+ NOTE: this complex-type name does not exist in the schema, where `w:tab` maps to
200
+ `CT_Empty`. This name was added to give it distinguished behavior. CT_Empty is used
201
+ for many elements.
202
+ """
203
+
204
+ def __str__(self) -> str:
205
+ """Text equivalent of this element, a single newline ("\n")."""
206
+ return "\n"
207
+
208
+
209
+ class CT_NoBreakHyphen(BaseOxmlElement):
210
+ """`<w:noBreakHyphen>` element, a hyphen ineligible for a line-wrap position.
211
+
212
+ This maps to a plain-text dash ("-").
213
+
214
+ NOTE: this complex-type name does not exist in the schema, where `w:noBreakHyphen`
215
+ maps to `CT_Empty`. This name was added to give it behavior distinguished from the
216
+ many other elements represented in the schema by CT_Empty.
217
+ """
218
+
219
+ def __str__(self) -> str:
220
+ """Text equivalent of this element, a single dash character ("-")."""
221
+ return "-"
222
+
223
+
224
+ class CT_PTab(BaseOxmlElement):
225
+ """`<w:ptab>` element, representing an absolute-position tab character within a run.
226
+
227
+ This character advances the rendering position to the specified position regardless
228
+ of any tab-stops, perhaps for layout of a table-of-contents (TOC) or similar.
229
+ """
230
+
231
+ def __str__(self) -> str:
232
+ """Text equivalent of this element, a single tab ("\t") character.
233
+
234
+ This allows the text of run inner-content to be accessed in a consistent way
235
+ for all run inner-context text elements.
236
+ """
237
+ return "\t"
238
+
239
+
240
+ # -- CT_Tab functionality is provided by CT_TabStop which also uses `w:tab` tag. That
241
+ # -- element class provides the __str__() method for this empty element, unconditionally
242
+ # -- returning "\t".
243
+
244
+
245
+ class CT_Text(BaseOxmlElement):
246
+ """`<w:t>` element, containing a sequence of characters within a run."""
247
+
248
+ def __str__(self) -> str:
249
+ """Text contained in this element, the empty string if it has no content.
250
+
251
+ This property allows this run inner-content element to be queried for its text
252
+ the same way as other run-content elements are. In particular, this never
253
+ returns None, as etree._Element does when there is no content.
254
+ """
255
+ return self.text or ""
256
+
257
+
258
+ # ------------------------------------------------------------------------------------
259
+ # Utility
260
+
261
+
262
+ class _RunContentAppender:
263
+ """Translates a Python string into run content elements appended in a `w:r` element.
264
+
265
+ Contiguous sequences of regular characters are appended in a single `<w:t>` element.
266
+ Each tab character ('\t') causes a `<w:tab/>` element to be appended. Likewise a
267
+ newline or carriage return character ('\n', '\r') causes a `<w:cr>` element to be
268
+ appended.
269
+ """
270
+
271
+ def __init__(self, r: CT_R):
272
+ self._r = r
273
+ self._bfr: List[str] = []
274
+
275
+ @classmethod
276
+ def append_to_run_from_text(cls, r: CT_R, text: str):
277
+ """Append inner-content elements for `text` to `r` element."""
278
+ appender = cls(r)
279
+ appender.add_text(text)
280
+
281
+ def add_text(self, text: str):
282
+ """Append inner-content elements for `text` to the `w:r` element."""
283
+ for char in text:
284
+ self.add_char(char)
285
+ self.flush()
286
+
287
+ def add_char(self, char: str):
288
+ """Process next character of input through finite state maching (FSM).
289
+
290
+ There are two possible states, buffer pending and not pending, but those are
291
+ hidden behind the `.flush()` method which must be called at the end of text to
292
+ ensure any pending `<w:t>` element is written.
293
+ """
294
+ if char == "\t":
295
+ self.flush()
296
+ self._r.add_tab()
297
+ elif char in "\r\n":
298
+ self.flush()
299
+ self._r.add_br()
300
+ else:
301
+ self._bfr.append(char)
302
+
303
+ def flush(self):
304
+ text = "".join(self._bfr)
305
+ if text:
306
+ self._r.add_t(text)
307
+ self._bfr.clear()