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/document.py ADDED
@@ -0,0 +1,275 @@
1
+ # pyright: reportImportCycles=false
2
+ # pyright: reportPrivateUsage=false
3
+
4
+ """|Document| and closely related objects."""
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import IO, TYPE_CHECKING, Iterator, List, Sequence
9
+
10
+ from docx.blkcntnr import BlockItemContainer
11
+ from docx.enum.section import WD_SECTION
12
+ from docx.enum.text import WD_BREAK
13
+ from docx.section import Section, Sections
14
+ from docx.shared import ElementProxy, Emu, Inches, Length
15
+ from docx.text.run import Run
16
+
17
+ if TYPE_CHECKING:
18
+ import docx.types as t
19
+ from docx.comments import Comment, Comments
20
+ from docx.oxml.document import CT_Body, CT_Document
21
+ from docx.parts.document import DocumentPart
22
+ from docx.settings import Settings
23
+ from docx.styles.style import ParagraphStyle, _TableStyle
24
+ from docx.table import Table
25
+ from docx.text.paragraph import Paragraph
26
+ from docx.theme import ThemeFonts
27
+
28
+
29
+ class Document(ElementProxy):
30
+ """WordprocessingML (WML) document.
31
+
32
+ Not intended to be constructed directly. Use :func:`docx.Document` to open or create
33
+ a document.
34
+ """
35
+
36
+ def __init__(self, element: CT_Document, part: DocumentPart):
37
+ super(Document, self).__init__(element)
38
+ self._element = element
39
+ self._part = part
40
+ self.__body = None
41
+
42
+ def add_comment(
43
+ self,
44
+ runs: Run | Sequence[Run],
45
+ text: str | None = "",
46
+ author: str = "",
47
+ initials: str | None = "",
48
+ ) -> Comment:
49
+ """Add a comment to the document, anchored to the specified runs.
50
+
51
+ `runs` can be a single `Run` object or a non-empty sequence of `Run` objects. Only the
52
+ first and last run of a sequence are used, it's just more convenient to pass a whole
53
+ sequence when that's what you have handy, like `paragraph.runs` for example. When `runs`
54
+ contains a single `Run` object, that run serves as both the first and last run.
55
+
56
+ A comment can be anchored only on an even run boundary, meaning the text the comment
57
+ "references" must be a non-zero integer number of consecutive runs. The runs need not be
58
+ _contiguous_ per se, like the first can be in one paragraph and the last in the next
59
+ paragraph, but all runs between the first and the last will be included in the reference.
60
+
61
+ The comment reference range is delimited by placing a `w:commentRangeStart` element before
62
+ the first run and a `w:commentRangeEnd` element after the last run. This is why only the
63
+ first and last run are required and why a single run can serve as both first and last.
64
+ Word works out which text to highlight in the UI based on these range markers.
65
+
66
+ `text` allows the contents of a simple comment to be provided in the call, providing for
67
+ the common case where a comment is a single phrase or sentence without special formatting
68
+ such as bold or italics. More complex comments can be added using the returned `Comment`
69
+ object in much the same way as a `Document` or (table) `Cell` object, using methods like
70
+ `.add_paragraph()`, .add_run()`, etc.
71
+
72
+ The `author` and `initials` parameters allow that metadata to be set for the comment.
73
+ `author` is a required attribute on a comment and is the empty string by default.
74
+ `initials` is optional on a comment and may be omitted by passing |None|, but Word adds an
75
+ `initials` attribute by default and we follow that convention by using the empty string
76
+ when no `initials` argument is provided.
77
+ """
78
+ # -- normalize `runs` to a sequence of runs --
79
+ runs = [runs] if isinstance(runs, Run) else runs
80
+ first_run = runs[0]
81
+ last_run = runs[-1]
82
+
83
+ # -- Note that comments can only appear in the document part --
84
+ comment = self.comments.add_comment(text=text, author=author, initials=initials)
85
+
86
+ # -- let the first run orchestrate placement of the comment range start and end --
87
+ first_run.mark_comment_range(last_run, comment.comment_id)
88
+
89
+ return comment
90
+
91
+ def add_heading(self, text: str = "", level: int = 1):
92
+ """Return a heading paragraph newly added to the end of the document.
93
+
94
+ The heading paragraph will contain `text` and have its paragraph style
95
+ determined by `level`. If `level` is 0, the style is set to `Title`. If `level`
96
+ is 1 (or omitted), `Heading 1` is used. Otherwise the style is set to `Heading
97
+ {level}`. Raises |ValueError| if `level` is outside the range 0-9.
98
+ """
99
+ if not 0 <= level <= 9:
100
+ raise ValueError("level must be in range 0-9, got %d" % level)
101
+ style = "Title" if level == 0 else "Heading %d" % level
102
+ return self.add_paragraph(text, style)
103
+
104
+ def add_page_break(self):
105
+ """Return newly |Paragraph| object containing only a page break."""
106
+ paragraph = self.add_paragraph()
107
+ paragraph.add_run().add_break(WD_BREAK.PAGE)
108
+ return paragraph
109
+
110
+ def add_paragraph(self, text: str = "", style: str | ParagraphStyle | None = None) -> Paragraph:
111
+ """Return paragraph newly added to the end of the document.
112
+
113
+ The paragraph is populated with `text` and having paragraph style `style`.
114
+
115
+ `text` can contain tab (``\\t``) characters, which are converted to the
116
+ appropriate XML form for a tab. `text` can also include newline (``\\n``) or
117
+ carriage return (``\\r``) characters, each of which is converted to a line
118
+ break.
119
+ """
120
+ return self._body.add_paragraph(text, style)
121
+
122
+ def add_picture(
123
+ self,
124
+ image_path_or_stream: str | IO[bytes],
125
+ width: int | Length | None = None,
126
+ height: int | Length | None = None,
127
+ ):
128
+ """Return new picture shape added in its own paragraph at end of the document.
129
+
130
+ The picture contains the image at `image_path_or_stream`, scaled based on
131
+ `width` and `height`. If neither width nor height is specified, the picture
132
+ appears at its native size. If only one is specified, it is used to compute a
133
+ scaling factor that is then applied to the unspecified dimension, preserving the
134
+ aspect ratio of the image. The native size of the picture is calculated using
135
+ the dots-per-inch (dpi) value specified in the image file, defaulting to 72 dpi
136
+ if no value is specified, as is often the case.
137
+ """
138
+ run = self.add_paragraph().add_run()
139
+ return run.add_picture(image_path_or_stream, width, height)
140
+
141
+ def add_section(self, start_type: WD_SECTION = WD_SECTION.NEW_PAGE):
142
+ """Return a |Section| object newly added at the end of the document.
143
+
144
+ The optional `start_type` argument must be a member of the :ref:`WdSectionStart`
145
+ enumeration, and defaults to ``WD_SECTION.NEW_PAGE`` if not provided.
146
+ """
147
+ new_sectPr = self._element.body.add_section_break()
148
+ new_sectPr.start_type = start_type
149
+ return Section(new_sectPr, self._part)
150
+
151
+ def add_table(self, rows: int, cols: int, style: str | _TableStyle | None = None):
152
+ """Add a table having row and column counts of `rows` and `cols` respectively.
153
+
154
+ `style` may be a table style object or a table style name. If `style` is |None|,
155
+ the table inherits the default table style of the document.
156
+ """
157
+ table = self._body.add_table(rows, cols, self._block_width)
158
+ table.style = style
159
+ return table
160
+
161
+ @property
162
+ def comments(self) -> Comments:
163
+ """A |Comments| object providing access to comments added to the document."""
164
+ return self._part.comments
165
+
166
+ @property
167
+ def core_properties(self):
168
+ """A |CoreProperties| object providing Dublin Core properties of document."""
169
+ return self._part.core_properties
170
+
171
+ @property
172
+ def inline_shapes(self):
173
+ """The |InlineShapes| collection for this document.
174
+
175
+ An inline shape is a graphical object, such as a picture, contained in a run of
176
+ text and behaving like a character glyph, being flowed like other text in a
177
+ paragraph.
178
+ """
179
+ return self._part.inline_shapes
180
+
181
+ def iter_inner_content(self) -> Iterator[Paragraph | Table]:
182
+ """Generate each `Paragraph` or `Table` in this document in document order."""
183
+ return self._body.iter_inner_content()
184
+
185
+ @property
186
+ def paragraphs(self) -> List[Paragraph]:
187
+ """The |Paragraph| instances in the document, in document order.
188
+
189
+ Note that paragraphs within revision marks such as ``<w:ins>`` or ``<w:del>`` do
190
+ not appear in this list.
191
+ """
192
+ return self._body.paragraphs
193
+
194
+ @property
195
+ def part(self) -> DocumentPart:
196
+ """The |DocumentPart| object of this document."""
197
+ return self._part
198
+
199
+ def save(self, path_or_stream: str | IO[bytes]):
200
+ """Save this document to `path_or_stream`.
201
+
202
+ `path_or_stream` can be either a path to a filesystem location (a string) or a
203
+ file-like object.
204
+ """
205
+ self._part.save(path_or_stream)
206
+
207
+ @property
208
+ def sections(self) -> Sections:
209
+ """|Sections| object providing access to each section in this document."""
210
+ return Sections(self._element, self._part)
211
+
212
+ @property
213
+ def settings(self) -> Settings:
214
+ """A |Settings| object providing access to the document-level settings."""
215
+ return self._part.settings
216
+
217
+ @property
218
+ def styles(self):
219
+ """A |Styles| object providing access to the styles in this document."""
220
+ return self._part.styles
221
+
222
+ @property
223
+ def theme_fonts(self) -> ThemeFonts:
224
+ """The document's |ThemeFonts| scheme.
225
+
226
+ Creates a default theme if the document has none. Raises |ValueError| if
227
+ an existing theme is malformed or lacks a complete font scheme.
228
+ """
229
+ return self._part.theme_fonts
230
+
231
+ @property
232
+ def tables(self) -> List[Table]:
233
+ """All |Table| instances in the document, in document order.
234
+
235
+ Note that only tables appearing at the top level of the document appear in this
236
+ list; a table nested inside a table cell does not appear. A table within
237
+ revision marks such as ``<w:ins>`` or ``<w:del>`` will also not appear in the
238
+ list.
239
+ """
240
+ return self._body.tables
241
+
242
+ @property
243
+ def _block_width(self) -> Length:
244
+ """A |Length| object specifying the space between margins in last section."""
245
+ section = self.sections[-1]
246
+ page_width = section.page_width or Inches(8.5)
247
+ left_margin = section.left_margin or Inches(1)
248
+ right_margin = section.right_margin or Inches(1)
249
+ return Emu(page_width - left_margin - right_margin)
250
+
251
+ @property
252
+ def _body(self) -> _Body:
253
+ """The |_Body| instance containing the content for this document."""
254
+ if self.__body is None:
255
+ self.__body = _Body(self._element.body, self)
256
+ return self.__body
257
+
258
+
259
+ class _Body(BlockItemContainer):
260
+ """Proxy for `<w:body>` element in this document.
261
+
262
+ It's primary role is a container for document content.
263
+ """
264
+
265
+ def __init__(self, body_elm: CT_Body, parent: t.ProvidesStoryPart):
266
+ super(_Body, self).__init__(body_elm, parent)
267
+ self._body = body_elm
268
+
269
+ def clear_content(self) -> _Body:
270
+ """Return this |_Body| instance after clearing it of all content.
271
+
272
+ Section properties for the main document story, if present, are preserved.
273
+ """
274
+ self._body.clear_content()
275
+ return self
@@ -0,0 +1,59 @@
1
+ """DrawingML-related objects are in this subpackage."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from docx.oxml.drawing import CT_Drawing
8
+ from docx.shared import Parented
9
+
10
+ if TYPE_CHECKING:
11
+ import docx.types as t
12
+ from docx.image.image import Image
13
+
14
+
15
+ class Drawing(Parented):
16
+ """Container for a DrawingML object."""
17
+
18
+ def __init__(self, drawing: CT_Drawing, parent: t.ProvidesStoryPart):
19
+ super().__init__(parent)
20
+ self._parent = parent
21
+ self._drawing = self._element = drawing
22
+
23
+ @property
24
+ def has_picture(self) -> bool:
25
+ """True when `drawing` contains an embedded picture.
26
+
27
+ A drawing can contain a picture, but it can also contain a chart, SmartArt, or a
28
+ drawing canvas. Methods related to a picture, like `.image`, will raise when the drawing
29
+ does not contain a picture. Use this value to determine whether image methods will succeed.
30
+
31
+ This value is `False` when a linked picture is present. This should be relatively rare and
32
+ the image would only be retrievable from the filesystem.
33
+
34
+ Note this does not distinguish between inline and floating images. The presence of either
35
+ one will cause this value to be `True`.
36
+ """
37
+ xpath_expr = (
38
+ # -- an inline picture --
39
+ "./wp:inline/a:graphic/a:graphicData/pic:pic"
40
+ # -- a floating picture --
41
+ " | ./wp:anchor/a:graphic/a:graphicData/pic:pic"
42
+ )
43
+ # -- xpath() will return a list, empty if there are no matches --
44
+ return bool(self._drawing.xpath(xpath_expr))
45
+
46
+ @property
47
+ def image(self) -> Image:
48
+ """An `Image` proxy object for the image in this (picture) drawing.
49
+
50
+ Raises `ValueError` when this drawing does contains something other than a picture. Use
51
+ `.has_picture` to qualify drawing objects before using this property.
52
+ """
53
+ picture_rIds = self._drawing.xpath(".//pic:blipFill/a:blip/@r:embed")
54
+ if not picture_rIds:
55
+ raise ValueError("drawing does not contain a picture")
56
+ rId = picture_rIds[0]
57
+ doc_part = self.part
58
+ image_part = doc_part.related_parts[rId]
59
+ return image_part.image
docx/enum/__init__.py ADDED
File without changes
docx/enum/base.py ADDED
@@ -0,0 +1,150 @@
1
+ """Base classes and other objects used by enumerations."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import enum
6
+ import textwrap
7
+ from typing import TYPE_CHECKING, Any, Dict, Type, TypeVar
8
+
9
+ if TYPE_CHECKING:
10
+ from typing_extensions import Self
11
+
12
+ _T = TypeVar("_T", bound="BaseXmlEnum")
13
+
14
+
15
+ class BaseEnum(int, enum.Enum):
16
+ """Base class for Enums that do not map XML attr values.
17
+
18
+ The enum's value will be an integer, corresponding to the integer assigned the
19
+ corresponding member in the MS API enum of the same name.
20
+ """
21
+
22
+ def __new__(cls, ms_api_value: int, docstr: str):
23
+ self = int.__new__(cls, ms_api_value)
24
+ self._value_ = ms_api_value
25
+ self.__doc__ = docstr.strip()
26
+ return self
27
+
28
+ def __str__(self):
29
+ """The symbolic name and string value of this member, e.g. 'MIDDLE (3)'."""
30
+ return f"{self.name} ({self.value})"
31
+
32
+
33
+ class BaseXmlEnum(int, enum.Enum):
34
+ """Base class for Enums that also map XML attr values.
35
+
36
+ The enum's value will be an integer, corresponding to the integer assigned the
37
+ corresponding member in the MS API enum of the same name.
38
+ """
39
+
40
+ xml_value: str | None
41
+
42
+ def __new__(cls, ms_api_value: int, xml_value: str | None, docstr: str):
43
+ self = int.__new__(cls, ms_api_value)
44
+ self._value_ = ms_api_value
45
+ self.xml_value = xml_value
46
+ self.__doc__ = docstr.strip()
47
+ return self
48
+
49
+ def __str__(self):
50
+ """The symbolic name and string value of this member, e.g. 'MIDDLE (3)'."""
51
+ return f"{self.name} ({self.value})"
52
+
53
+ @classmethod
54
+ def from_xml(cls, xml_value: str | None) -> Self:
55
+ """Enumeration member corresponding to XML attribute value `xml_value`.
56
+
57
+ Example::
58
+
59
+ >>> WD_PARAGRAPH_ALIGNMENT.from_xml("center")
60
+ WD_PARAGRAPH_ALIGNMENT.CENTER
61
+
62
+ """
63
+ member = next((member for member in cls if member.xml_value == xml_value), None)
64
+ if member is None:
65
+ raise ValueError(f"{cls.__name__} has no XML mapping for '{xml_value}'")
66
+ return member
67
+
68
+ @classmethod
69
+ def to_xml(cls: Type[_T], value: int | _T | None) -> str | None:
70
+ """XML value of this enum member, generally an XML attribute value."""
71
+ # -- presence of multi-arg `__new__()` method fools type-checker, but getting a
72
+ # -- member by its value using EnumCls(val) works as usual.
73
+ member = cls(value)
74
+ xml_value = member.xml_value
75
+ if not xml_value:
76
+ raise ValueError(f"{cls.__name__}.{member.name} has no XML representation")
77
+ return xml_value
78
+
79
+
80
+ class DocsPageFormatter:
81
+ """Generate an .rst doc page for an enumeration.
82
+
83
+ Formats a RestructuredText documention page (string) for the enumeration class parts
84
+ passed to the constructor. An immutable one-shot service object.
85
+ """
86
+
87
+ def __init__(self, clsname: str, clsdict: Dict[str, Any]):
88
+ self._clsname = clsname
89
+ self._clsdict = clsdict
90
+
91
+ @property
92
+ def page_str(self):
93
+ """The RestructuredText documentation page for the enumeration.
94
+
95
+ This is the only API member for the class.
96
+ """
97
+ tmpl = ".. _%s:\n\n%s\n\n%s\n\n----\n\n%s"
98
+ components = (
99
+ self._ms_name,
100
+ self._page_title,
101
+ self._intro_text,
102
+ self._member_defs,
103
+ )
104
+ return tmpl % components
105
+
106
+ @property
107
+ def _intro_text(self):
108
+ """Docstring of the enumeration, formatted for documentation page."""
109
+ try:
110
+ cls_docstring = self._clsdict["__doc__"]
111
+ except KeyError:
112
+ cls_docstring = ""
113
+
114
+ if cls_docstring is None:
115
+ return ""
116
+
117
+ return textwrap.dedent(cls_docstring).strip()
118
+
119
+ def _member_def(self, member: BaseEnum | BaseXmlEnum):
120
+ """Return an individual member definition formatted as an RST glossary entry,
121
+ wrapped to fit within 78 columns."""
122
+ assert member.__doc__ is not None
123
+ member_docstring = textwrap.dedent(member.__doc__).strip()
124
+ member_docstring = textwrap.fill(
125
+ member_docstring,
126
+ width=78,
127
+ initial_indent=" " * 4,
128
+ subsequent_indent=" " * 4,
129
+ )
130
+ return "%s\n%s\n" % (member.name, member_docstring)
131
+
132
+ @property
133
+ def _member_defs(self):
134
+ """A single string containing the aggregated member definitions section of the
135
+ documentation page."""
136
+ members = self._clsdict["__members__"]
137
+ member_defs = [self._member_def(member) for member in members if member.name is not None]
138
+ return "\n".join(member_defs)
139
+
140
+ @property
141
+ def _ms_name(self):
142
+ """The Microsoft API name for this enumeration."""
143
+ return self._clsdict["__ms_name__"]
144
+
145
+ @property
146
+ def _page_title(self):
147
+ """The title for the documentation page, formatted as code (surrounded in
148
+ double-backtics) and underlined with '=' characters."""
149
+ title_underscore = "=" * (len(self._clsname) + 4)
150
+ return "``%s``\n%s" % (self._clsname, title_underscore)
docx/enum/dml.py ADDED
@@ -0,0 +1,103 @@
1
+ """Enumerations used by DrawingML objects."""
2
+
3
+ from .base import BaseEnum, BaseXmlEnum
4
+
5
+
6
+ class MSO_COLOR_TYPE(BaseEnum):
7
+ """Specifies the color specification scheme.
8
+
9
+ Example::
10
+
11
+ from docx.enum.dml import MSO_COLOR_TYPE
12
+
13
+ assert font.color.type == MSO_COLOR_TYPE.SCHEME
14
+
15
+ MS API name: `MsoColorType`
16
+
17
+ http://msdn.microsoft.com/en-us/library/office/ff864912(v=office.15).aspx
18
+ """
19
+
20
+ RGB = (1, "Color is specified by an |RGBColor| value.")
21
+ """Color is specified by an |RGBColor| value."""
22
+
23
+ THEME = (2, "Color is one of the preset theme colors.")
24
+ """Color is one of the preset theme colors."""
25
+
26
+ AUTO = (101, "Color is determined automatically by the application.")
27
+ """Color is determined automatically by the application."""
28
+
29
+
30
+ class MSO_THEME_COLOR_INDEX(BaseXmlEnum):
31
+ """Indicates the Office theme color, one of those shown in the color gallery on the
32
+ formatting ribbon.
33
+
34
+ Alias: ``MSO_THEME_COLOR``
35
+
36
+ Example::
37
+
38
+ from docx.enum.dml import MSO_THEME_COLOR
39
+
40
+ font.color.theme_color = MSO_THEME_COLOR.ACCENT_1
41
+
42
+ MS API name: `MsoThemeColorIndex`
43
+
44
+ http://msdn.microsoft.com/en-us/library/office/ff860782(v=office.15).aspx
45
+ """
46
+
47
+ NOT_THEME_COLOR = (0, "UNMAPPED", "Indicates the color is not a theme color.")
48
+ """Indicates the color is not a theme color."""
49
+
50
+ ACCENT_1 = (5, "accent1", "Specifies the Accent 1 theme color.")
51
+ """Specifies the Accent 1 theme color."""
52
+
53
+ ACCENT_2 = (6, "accent2", "Specifies the Accent 2 theme color.")
54
+ """Specifies the Accent 2 theme color."""
55
+
56
+ ACCENT_3 = (7, "accent3", "Specifies the Accent 3 theme color.")
57
+ """Specifies the Accent 3 theme color."""
58
+
59
+ ACCENT_4 = (8, "accent4", "Specifies the Accent 4 theme color.")
60
+ """Specifies the Accent 4 theme color."""
61
+
62
+ ACCENT_5 = (9, "accent5", "Specifies the Accent 5 theme color.")
63
+ """Specifies the Accent 5 theme color."""
64
+
65
+ ACCENT_6 = (10, "accent6", "Specifies the Accent 6 theme color.")
66
+ """Specifies the Accent 6 theme color."""
67
+
68
+ BACKGROUND_1 = (14, "background1", "Specifies the Background 1 theme color.")
69
+ """Specifies the Background 1 theme color."""
70
+
71
+ BACKGROUND_2 = (16, "background2", "Specifies the Background 2 theme color.")
72
+ """Specifies the Background 2 theme color."""
73
+
74
+ DARK_1 = (1, "dark1", "Specifies the Dark 1 theme color.")
75
+ """Specifies the Dark 1 theme color."""
76
+
77
+ DARK_2 = (3, "dark2", "Specifies the Dark 2 theme color.")
78
+ """Specifies the Dark 2 theme color."""
79
+
80
+ FOLLOWED_HYPERLINK = (
81
+ 12,
82
+ "followedHyperlink",
83
+ "Specifies the theme color for a clicked hyperlink.",
84
+ )
85
+ """Specifies the theme color for a clicked hyperlink."""
86
+
87
+ HYPERLINK = (11, "hyperlink", "Specifies the theme color for a hyperlink.")
88
+ """Specifies the theme color for a hyperlink."""
89
+
90
+ LIGHT_1 = (2, "light1", "Specifies the Light 1 theme color.")
91
+ """Specifies the Light 1 theme color."""
92
+
93
+ LIGHT_2 = (4, "light2", "Specifies the Light 2 theme color.")
94
+ """Specifies the Light 2 theme color."""
95
+
96
+ TEXT_1 = (13, "text1", "Specifies the Text 1 theme color.")
97
+ """Specifies the Text 1 theme color."""
98
+
99
+ TEXT_2 = (15, "text2", "Specifies the Text 2 theme color.")
100
+ """Specifies the Text 2 theme color."""
101
+
102
+
103
+ MSO_THEME_COLOR = MSO_THEME_COLOR_INDEX
docx/enum/section.py ADDED
@@ -0,0 +1,86 @@
1
+ """Enumerations related to the main document in WordprocessingML files."""
2
+
3
+ from .base import BaseXmlEnum
4
+
5
+
6
+ class WD_HEADER_FOOTER_INDEX(BaseXmlEnum):
7
+ """Alias: **WD_HEADER_FOOTER**
8
+
9
+ Specifies one of the three possible header/footer definitions for a section.
10
+
11
+ For internal use only; not part of the python-docx API.
12
+
13
+ MS API name: `WdHeaderFooterIndex`
14
+ URL: https://docs.microsoft.com/en-us/office/vba/api/word.wdheaderfooterindex
15
+ """
16
+
17
+ PRIMARY = (1, "default", "Header for odd pages or all if no even header.")
18
+ """Header for odd pages or all if no even header."""
19
+
20
+ FIRST_PAGE = (2, "first", "Header for first page of section.")
21
+ """Header for first page of section."""
22
+
23
+ EVEN_PAGE = (3, "even", "Header for even pages of recto/verso section.")
24
+ """Header for even pages of recto/verso section."""
25
+
26
+
27
+ WD_HEADER_FOOTER = WD_HEADER_FOOTER_INDEX
28
+
29
+
30
+ class WD_ORIENTATION(BaseXmlEnum):
31
+ """Alias: **WD_ORIENT**
32
+
33
+ Specifies the page layout orientation.
34
+
35
+ Example::
36
+
37
+ from docx.enum.section import WD_ORIENT
38
+
39
+ section = document.sections[-1] section.orientation = WD_ORIENT.LANDSCAPE
40
+
41
+ MS API name: `WdOrientation`
42
+ MS API URL: http://msdn.microsoft.com/en-us/library/office/ff837902.aspx
43
+ """
44
+
45
+ PORTRAIT = (0, "portrait", "Portrait orientation.")
46
+ """Portrait orientation."""
47
+
48
+ LANDSCAPE = (1, "landscape", "Landscape orientation.")
49
+ """Landscape orientation."""
50
+
51
+
52
+ WD_ORIENT = WD_ORIENTATION
53
+
54
+
55
+ class WD_SECTION_START(BaseXmlEnum):
56
+ """Alias: **WD_SECTION**
57
+
58
+ Specifies the start type of a section break.
59
+
60
+ Example::
61
+
62
+ from docx.enum.section import WD_SECTION
63
+
64
+ section = document.sections[0] section.start_type = WD_SECTION.NEW_PAGE
65
+
66
+ MS API name: `WdSectionStart`
67
+ MS API URL: http://msdn.microsoft.com/en-us/library/office/ff840975.aspx
68
+ """
69
+
70
+ CONTINUOUS = (0, "continuous", "Continuous section break.")
71
+ """Continuous section break."""
72
+
73
+ NEW_COLUMN = (1, "nextColumn", "New column section break.")
74
+ """New column section break."""
75
+
76
+ NEW_PAGE = (2, "nextPage", "New page section break.")
77
+ """New page section break."""
78
+
79
+ EVEN_PAGE = (3, "evenPage", "Even pages section break.")
80
+ """Even pages section break."""
81
+
82
+ ODD_PAGE = (4, "oddPage", "Section begins on next odd page.")
83
+ """Section begins on next odd page."""
84
+
85
+
86
+ WD_SECTION = WD_SECTION_START