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.
- docx/__init__.py +68 -0
- docx/api.py +37 -0
- docx/blkcntnr.py +101 -0
- docx/comments.py +163 -0
- docx/dml/__init__.py +0 -0
- docx/dml/color.py +112 -0
- docx/document.py +275 -0
- docx/drawing/__init__.py +59 -0
- docx/enum/__init__.py +0 -0
- docx/enum/base.py +150 -0
- docx/enum/dml.py +103 -0
- docx/enum/section.py +86 -0
- docx/enum/shape.py +19 -0
- docx/enum/style.py +452 -0
- docx/enum/table.py +136 -0
- docx/enum/text.py +367 -0
- docx/exceptions.py +18 -0
- docx/image/__init__.py +23 -0
- docx/image/bmp.py +43 -0
- docx/image/constants.py +172 -0
- docx/image/exceptions.py +13 -0
- docx/image/gif.py +38 -0
- docx/image/helpers.py +86 -0
- docx/image/image.py +234 -0
- docx/image/jpeg.py +425 -0
- docx/image/png.py +253 -0
- docx/image/tiff.py +289 -0
- docx/opc/__init__.py +0 -0
- docx/opc/constants.py +306 -0
- docx/opc/coreprops.py +142 -0
- docx/opc/exceptions.py +12 -0
- docx/opc/oxml.py +247 -0
- docx/opc/package.py +219 -0
- docx/opc/packuri.py +109 -0
- docx/opc/part.py +247 -0
- docx/opc/parts/__init__.py +0 -0
- docx/opc/parts/coreprops.py +48 -0
- docx/opc/phys_pkg.py +119 -0
- docx/opc/pkgreader.py +254 -0
- docx/opc/pkgwriter.py +115 -0
- docx/opc/rel.py +153 -0
- docx/opc/shared.py +31 -0
- docx/opc/spec.py +24 -0
- docx/oxml/__init__.py +261 -0
- docx/oxml/comments.py +124 -0
- docx/oxml/coreprops.py +298 -0
- docx/oxml/document.py +88 -0
- docx/oxml/drawing.py +11 -0
- docx/oxml/exceptions.py +10 -0
- docx/oxml/ns.py +109 -0
- docx/oxml/numbering.py +109 -0
- docx/oxml/parser.py +62 -0
- docx/oxml/section.py +537 -0
- docx/oxml/settings.py +138 -0
- docx/oxml/shape.py +299 -0
- docx/oxml/shared.py +52 -0
- docx/oxml/simpletypes.py +434 -0
- docx/oxml/styles.py +341 -0
- docx/oxml/table.py +977 -0
- docx/oxml/text/__init__.py +0 -0
- docx/oxml/text/font.py +333 -0
- docx/oxml/text/hyperlink.py +45 -0
- docx/oxml/text/pagebreak.py +278 -0
- docx/oxml/text/paragraph.py +106 -0
- docx/oxml/text/parfmt.py +392 -0
- docx/oxml/text/run.py +307 -0
- docx/oxml/xmlchemy.py +696 -0
- docx/package.py +110 -0
- docx/parts/__init__.py +0 -0
- docx/parts/comments.py +51 -0
- docx/parts/document.py +182 -0
- docx/parts/hdrftr.py +53 -0
- docx/parts/image.py +80 -0
- docx/parts/numbering.py +32 -0
- docx/parts/settings.py +50 -0
- docx/parts/story.py +95 -0
- docx/parts/styles.py +42 -0
- docx/parts/theme.py +53 -0
- docx/py.typed +0 -0
- docx/section.py +479 -0
- docx/settings.py +35 -0
- docx/shape.py +103 -0
- docx/shared.py +382 -0
- docx/styles/__init__.py +40 -0
- docx/styles/latent.py +198 -0
- docx/styles/style.py +264 -0
- docx/styles/styles.py +147 -0
- docx/table.py +537 -0
- docx/templates/default-comments.xml +12 -0
- docx/templates/default-docx-template/[Content_Types].xml +17 -0
- docx/templates/default-docx-template/_rels/.rels +7 -0
- docx/templates/default-docx-template/customXml/_rels/item1.xml.rels +4 -0
- docx/templates/default-docx-template/customXml/item1.xml +2 -0
- docx/templates/default-docx-template/customXml/itemProps1.xml +6 -0
- docx/templates/default-docx-template/docProps/app.xml +36 -0
- docx/templates/default-docx-template/docProps/core.xml +13 -0
- docx/templates/default-docx-template/docProps/thumbnail.jpeg +0 -0
- docx/templates/default-docx-template/word/_rels/document.xml.rels +11 -0
- docx/templates/default-docx-template/word/document.xml +11 -0
- docx/templates/default-docx-template/word/fontTable.xml +61 -0
- docx/templates/default-docx-template/word/numbering.xml +201 -0
- docx/templates/default-docx-template/word/settings.xml +53 -0
- docx/templates/default-docx-template/word/styles.xml +11844 -0
- docx/templates/default-docx-template/word/stylesWithEffects.xml +11800 -0
- docx/templates/default-docx-template/word/theme/theme1.xml +318 -0
- docx/templates/default-docx-template/word/webSettings.xml +5 -0
- docx/templates/default-footer.xml +27 -0
- docx/templates/default-header.xml +27 -0
- docx/templates/default-settings.xml +26 -0
- docx/templates/default-styles.xml +190 -0
- docx/templates/default.docx +0 -0
- docx/text/__init__.py +0 -0
- docx/text/font.py +472 -0
- docx/text/hyperlink.py +121 -0
- docx/text/pagebreak.py +104 -0
- docx/text/paragraph.py +173 -0
- docx/text/parfmt.py +286 -0
- docx/text/run.py +257 -0
- docx/text/tabstops.py +123 -0
- docx/theme.py +67 -0
- docx/types.py +34 -0
- ps_python_docx-1.3.0.dist-info/METADATA +77 -0
- ps_python_docx-1.3.0.dist-info/RECORD +126 -0
- ps_python_docx-1.3.0.dist-info/WHEEL +5 -0
- ps_python_docx-1.3.0.dist-info/licenses/LICENSE +20 -0
- ps_python_docx-1.3.0.dist-info/top_level.txt +1 -0
docx/enum/text.py
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
"""Enumerations related to text in WordprocessingML files."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import enum
|
|
6
|
+
|
|
7
|
+
from docx.enum.base import BaseXmlEnum
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class WD_PARAGRAPH_ALIGNMENT(BaseXmlEnum):
|
|
11
|
+
"""Alias: **WD_ALIGN_PARAGRAPH**
|
|
12
|
+
|
|
13
|
+
Specifies paragraph justification type.
|
|
14
|
+
|
|
15
|
+
Example::
|
|
16
|
+
|
|
17
|
+
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
18
|
+
|
|
19
|
+
paragraph = document.add_paragraph()
|
|
20
|
+
paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
LEFT = (0, "left", "Left-aligned")
|
|
24
|
+
"""Left-aligned"""
|
|
25
|
+
|
|
26
|
+
CENTER = (1, "center", "Center-aligned.")
|
|
27
|
+
"""Center-aligned."""
|
|
28
|
+
|
|
29
|
+
RIGHT = (2, "right", "Right-aligned.")
|
|
30
|
+
"""Right-aligned."""
|
|
31
|
+
|
|
32
|
+
JUSTIFY = (3, "both", "Fully justified.")
|
|
33
|
+
"""Fully justified."""
|
|
34
|
+
|
|
35
|
+
DISTRIBUTE = (
|
|
36
|
+
4,
|
|
37
|
+
"distribute",
|
|
38
|
+
"Paragraph characters are distributed to fill entire width of paragraph.",
|
|
39
|
+
)
|
|
40
|
+
"""Paragraph characters are distributed to fill entire width of paragraph."""
|
|
41
|
+
|
|
42
|
+
JUSTIFY_MED = (
|
|
43
|
+
5,
|
|
44
|
+
"mediumKashida",
|
|
45
|
+
"Justified with a medium character compression ratio.",
|
|
46
|
+
)
|
|
47
|
+
"""Justified with a medium character compression ratio."""
|
|
48
|
+
|
|
49
|
+
JUSTIFY_HI = (
|
|
50
|
+
7,
|
|
51
|
+
"highKashida",
|
|
52
|
+
"Justified with a high character compression ratio.",
|
|
53
|
+
)
|
|
54
|
+
"""Justified with a high character compression ratio."""
|
|
55
|
+
|
|
56
|
+
JUSTIFY_LOW = (8, "lowKashida", "Justified with a low character compression ratio.")
|
|
57
|
+
"""Justified with a low character compression ratio."""
|
|
58
|
+
|
|
59
|
+
THAI_JUSTIFY = (
|
|
60
|
+
9,
|
|
61
|
+
"thaiDistribute",
|
|
62
|
+
"Justified according to Thai formatting layout.",
|
|
63
|
+
)
|
|
64
|
+
"""Justified according to Thai formatting layout."""
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
WD_ALIGN_PARAGRAPH = WD_PARAGRAPH_ALIGNMENT
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class WD_BREAK_TYPE(enum.Enum):
|
|
71
|
+
"""Corresponds to WdBreakType enumeration.
|
|
72
|
+
|
|
73
|
+
http://msdn.microsoft.com/en-us/library/office/ff195905.aspx.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
COLUMN = 8
|
|
77
|
+
LINE = 6
|
|
78
|
+
LINE_CLEAR_LEFT = 9
|
|
79
|
+
LINE_CLEAR_RIGHT = 10
|
|
80
|
+
LINE_CLEAR_ALL = 11 # -- added for consistency, not in MS version --
|
|
81
|
+
PAGE = 7
|
|
82
|
+
SECTION_CONTINUOUS = 3
|
|
83
|
+
SECTION_EVEN_PAGE = 4
|
|
84
|
+
SECTION_NEXT_PAGE = 2
|
|
85
|
+
SECTION_ODD_PAGE = 5
|
|
86
|
+
TEXT_WRAPPING = 11
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
WD_BREAK = WD_BREAK_TYPE
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class WD_COLOR_INDEX(BaseXmlEnum):
|
|
93
|
+
"""Specifies a standard preset color to apply.
|
|
94
|
+
|
|
95
|
+
Used for font highlighting and perhaps other applications.
|
|
96
|
+
|
|
97
|
+
* MS API name: `WdColorIndex`
|
|
98
|
+
* URL: https://msdn.microsoft.com/EN-US/library/office/ff195343.aspx
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
INHERITED = (-1, None, "Color is inherited from the style hierarchy.")
|
|
102
|
+
"""Color is inherited from the style hierarchy."""
|
|
103
|
+
|
|
104
|
+
AUTO = (0, "default", "Automatic color. Default; usually black.")
|
|
105
|
+
"""Automatic color. Default; usually black."""
|
|
106
|
+
|
|
107
|
+
BLACK = (1, "black", "Black color.")
|
|
108
|
+
"""Black color."""
|
|
109
|
+
|
|
110
|
+
BLUE = (2, "blue", "Blue color")
|
|
111
|
+
"""Blue color"""
|
|
112
|
+
|
|
113
|
+
BRIGHT_GREEN = (4, "green", "Bright green color.")
|
|
114
|
+
"""Bright green color."""
|
|
115
|
+
|
|
116
|
+
DARK_BLUE = (9, "darkBlue", "Dark blue color.")
|
|
117
|
+
"""Dark blue color."""
|
|
118
|
+
|
|
119
|
+
DARK_RED = (13, "darkRed", "Dark red color.")
|
|
120
|
+
"""Dark red color."""
|
|
121
|
+
|
|
122
|
+
DARK_YELLOW = (14, "darkYellow", "Dark yellow color.")
|
|
123
|
+
"""Dark yellow color."""
|
|
124
|
+
|
|
125
|
+
GRAY_25 = (16, "lightGray", "25% shade of gray color.")
|
|
126
|
+
"""25% shade of gray color."""
|
|
127
|
+
|
|
128
|
+
GRAY_50 = (15, "darkGray", "50% shade of gray color.")
|
|
129
|
+
"""50% shade of gray color."""
|
|
130
|
+
|
|
131
|
+
GREEN = (11, "darkGreen", "Green color.")
|
|
132
|
+
"""Green color."""
|
|
133
|
+
|
|
134
|
+
PINK = (5, "magenta", "Pink color.")
|
|
135
|
+
"""Pink color."""
|
|
136
|
+
|
|
137
|
+
RED = (6, "red", "Red color.")
|
|
138
|
+
"""Red color."""
|
|
139
|
+
|
|
140
|
+
TEAL = (10, "darkCyan", "Teal color.")
|
|
141
|
+
"""Teal color."""
|
|
142
|
+
|
|
143
|
+
TURQUOISE = (3, "cyan", "Turquoise color.")
|
|
144
|
+
"""Turquoise color."""
|
|
145
|
+
|
|
146
|
+
VIOLET = (12, "darkMagenta", "Violet color.")
|
|
147
|
+
"""Violet color."""
|
|
148
|
+
|
|
149
|
+
WHITE = (8, "white", "White color.")
|
|
150
|
+
"""White color."""
|
|
151
|
+
|
|
152
|
+
YELLOW = (7, "yellow", "Yellow color.")
|
|
153
|
+
"""Yellow color."""
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
WD_COLOR = WD_COLOR_INDEX
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class WD_LINE_SPACING(BaseXmlEnum):
|
|
160
|
+
"""Specifies a line spacing format to be applied to a paragraph.
|
|
161
|
+
|
|
162
|
+
Example::
|
|
163
|
+
|
|
164
|
+
from docx.enum.text import WD_LINE_SPACING
|
|
165
|
+
|
|
166
|
+
paragraph = document.add_paragraph()
|
|
167
|
+
paragraph.line_spacing_rule = WD_LINE_SPACING.EXACTLY
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
MS API name: `WdLineSpacing`
|
|
171
|
+
|
|
172
|
+
URL: http://msdn.microsoft.com/en-us/library/office/ff844910.aspx
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
SINGLE = (0, "UNMAPPED", "Single spaced (default).")
|
|
176
|
+
"""Single spaced (default)."""
|
|
177
|
+
|
|
178
|
+
ONE_POINT_FIVE = (1, "UNMAPPED", "Space-and-a-half line spacing.")
|
|
179
|
+
"""Space-and-a-half line spacing."""
|
|
180
|
+
|
|
181
|
+
DOUBLE = (2, "UNMAPPED", "Double spaced.")
|
|
182
|
+
"""Double spaced."""
|
|
183
|
+
|
|
184
|
+
AT_LEAST = (
|
|
185
|
+
3,
|
|
186
|
+
"atLeast",
|
|
187
|
+
"Minimum line spacing is specified amount. Amount is specified separately.",
|
|
188
|
+
)
|
|
189
|
+
"""Minimum line spacing is specified amount. Amount is specified separately."""
|
|
190
|
+
|
|
191
|
+
EXACTLY = (
|
|
192
|
+
4,
|
|
193
|
+
"exact",
|
|
194
|
+
"Line spacing is exactly specified amount. Amount is specified separately.",
|
|
195
|
+
)
|
|
196
|
+
"""Line spacing is exactly specified amount. Amount is specified separately."""
|
|
197
|
+
|
|
198
|
+
MULTIPLE = (
|
|
199
|
+
5,
|
|
200
|
+
"auto",
|
|
201
|
+
"Line spacing is specified as multiple of line heights. Changing font size"
|
|
202
|
+
" will change line spacing proportionately.",
|
|
203
|
+
)
|
|
204
|
+
"""Line spacing is specified as multiple of line heights. Changing font size will
|
|
205
|
+
change the line spacing proportionately."""
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class WD_TAB_ALIGNMENT(BaseXmlEnum):
|
|
209
|
+
"""Specifies the tab stop alignment to apply.
|
|
210
|
+
|
|
211
|
+
MS API name: `WdTabAlignment`
|
|
212
|
+
|
|
213
|
+
URL: https://msdn.microsoft.com/EN-US/library/office/ff195609.aspx
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
LEFT = (0, "left", "Left-aligned.")
|
|
217
|
+
"""Left-aligned."""
|
|
218
|
+
|
|
219
|
+
CENTER = (1, "center", "Center-aligned.")
|
|
220
|
+
"""Center-aligned."""
|
|
221
|
+
|
|
222
|
+
RIGHT = (2, "right", "Right-aligned.")
|
|
223
|
+
"""Right-aligned."""
|
|
224
|
+
|
|
225
|
+
DECIMAL = (3, "decimal", "Decimal-aligned.")
|
|
226
|
+
"""Decimal-aligned."""
|
|
227
|
+
|
|
228
|
+
BAR = (4, "bar", "Bar-aligned.")
|
|
229
|
+
"""Bar-aligned."""
|
|
230
|
+
|
|
231
|
+
LIST = (6, "list", "List-aligned. (deprecated)")
|
|
232
|
+
"""List-aligned. (deprecated)"""
|
|
233
|
+
|
|
234
|
+
CLEAR = (101, "clear", "Clear an inherited tab stop.")
|
|
235
|
+
"""Clear an inherited tab stop."""
|
|
236
|
+
|
|
237
|
+
END = (102, "end", "Right-aligned. (deprecated)")
|
|
238
|
+
"""Right-aligned. (deprecated)"""
|
|
239
|
+
|
|
240
|
+
NUM = (103, "num", "Left-aligned. (deprecated)")
|
|
241
|
+
"""Left-aligned. (deprecated)"""
|
|
242
|
+
|
|
243
|
+
START = (104, "start", "Left-aligned. (deprecated)")
|
|
244
|
+
"""Left-aligned. (deprecated)"""
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
class WD_TAB_LEADER(BaseXmlEnum):
|
|
248
|
+
"""Specifies the character to use as the leader with formatted tabs.
|
|
249
|
+
|
|
250
|
+
MS API name: `WdTabLeader`
|
|
251
|
+
|
|
252
|
+
URL: https://msdn.microsoft.com/en-us/library/office/ff845050.aspx
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
SPACES = (0, "none", "Spaces. Default.")
|
|
256
|
+
"""Spaces. Default."""
|
|
257
|
+
|
|
258
|
+
DOTS = (1, "dot", "Dots.")
|
|
259
|
+
"""Dots."""
|
|
260
|
+
|
|
261
|
+
DASHES = (2, "hyphen", "Dashes.")
|
|
262
|
+
"""Dashes."""
|
|
263
|
+
|
|
264
|
+
LINES = (3, "underscore", "Double lines.")
|
|
265
|
+
"""Double lines."""
|
|
266
|
+
|
|
267
|
+
HEAVY = (4, "heavy", "A heavy line.")
|
|
268
|
+
"""A heavy line."""
|
|
269
|
+
|
|
270
|
+
MIDDLE_DOT = (5, "middleDot", "A vertically-centered dot.")
|
|
271
|
+
"""A vertically-centered dot."""
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class WD_UNDERLINE(BaseXmlEnum):
|
|
275
|
+
"""Specifies the style of underline applied to a run of characters.
|
|
276
|
+
|
|
277
|
+
MS API name: `WdUnderline`
|
|
278
|
+
|
|
279
|
+
URL: http://msdn.microsoft.com/en-us/library/office/ff822388.aspx
|
|
280
|
+
"""
|
|
281
|
+
|
|
282
|
+
INHERITED = (-1, None, "Inherit underline setting from containing paragraph.")
|
|
283
|
+
"""Inherit underline setting from containing paragraph."""
|
|
284
|
+
|
|
285
|
+
NONE = (
|
|
286
|
+
0,
|
|
287
|
+
"none",
|
|
288
|
+
"No underline.\n\nThis setting overrides any inherited underline value, so can"
|
|
289
|
+
" be used to remove underline from a run that inherits underlining from its"
|
|
290
|
+
" containing paragraph. Note this is not the same as assigning |None| to"
|
|
291
|
+
" Run.underline. |None| is a valid assignment value, but causes the run to"
|
|
292
|
+
" inherit its underline value. Assigning `WD_UNDERLINE.NONE` causes"
|
|
293
|
+
" underlining to be unconditionally turned off.",
|
|
294
|
+
)
|
|
295
|
+
"""No underline.
|
|
296
|
+
|
|
297
|
+
This setting overrides any inherited underline value, so can be used to remove
|
|
298
|
+
underline from a run that inherits underlining from its containing paragraph. Note
|
|
299
|
+
this is not the same as assigning |None| to Run.underline. |None| is a valid
|
|
300
|
+
assignment value, but causes the run to inherit its underline value. Assigning
|
|
301
|
+
``WD_UNDERLINE.NONE`` causes underlining to be unconditionally turned off.
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
SINGLE = (
|
|
305
|
+
1,
|
|
306
|
+
"single",
|
|
307
|
+
"A single line.\n\nNote that this setting is write-only in the sense that"
|
|
308
|
+
" |True| (rather than `WD_UNDERLINE.SINGLE`) is returned for a run having"
|
|
309
|
+
" this setting.",
|
|
310
|
+
)
|
|
311
|
+
"""A single line.
|
|
312
|
+
|
|
313
|
+
Note that this setting is write-only in the sense that |True|
|
|
314
|
+
(rather than ``WD_UNDERLINE.SINGLE``) is returned for a run having this setting.
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
WORDS = (2, "words", "Underline individual words only.")
|
|
318
|
+
"""Underline individual words only."""
|
|
319
|
+
|
|
320
|
+
DOUBLE = (3, "double", "A double line.")
|
|
321
|
+
"""A double line."""
|
|
322
|
+
|
|
323
|
+
DOTTED = (4, "dotted", "Dots.")
|
|
324
|
+
"""Dots."""
|
|
325
|
+
|
|
326
|
+
THICK = (6, "thick", "A single thick line.")
|
|
327
|
+
"""A single thick line."""
|
|
328
|
+
|
|
329
|
+
DASH = (7, "dash", "Dashes.")
|
|
330
|
+
"""Dashes."""
|
|
331
|
+
|
|
332
|
+
DOT_DASH = (9, "dotDash", "Alternating dots and dashes.")
|
|
333
|
+
"""Alternating dots and dashes."""
|
|
334
|
+
|
|
335
|
+
DOT_DOT_DASH = (10, "dotDotDash", "An alternating dot-dot-dash pattern.")
|
|
336
|
+
"""An alternating dot-dot-dash pattern."""
|
|
337
|
+
|
|
338
|
+
WAVY = (11, "wave", "A single wavy line.")
|
|
339
|
+
"""A single wavy line."""
|
|
340
|
+
|
|
341
|
+
DOTTED_HEAVY = (20, "dottedHeavy", "Heavy dots.")
|
|
342
|
+
"""Heavy dots."""
|
|
343
|
+
|
|
344
|
+
DASH_HEAVY = (23, "dashedHeavy", "Heavy dashes.")
|
|
345
|
+
"""Heavy dashes."""
|
|
346
|
+
|
|
347
|
+
DOT_DASH_HEAVY = (25, "dashDotHeavy", "Alternating heavy dots and heavy dashes.")
|
|
348
|
+
"""Alternating heavy dots and heavy dashes."""
|
|
349
|
+
|
|
350
|
+
DOT_DOT_DASH_HEAVY = (
|
|
351
|
+
26,
|
|
352
|
+
"dashDotDotHeavy",
|
|
353
|
+
"An alternating heavy dot-dot-dash pattern.",
|
|
354
|
+
)
|
|
355
|
+
"""An alternating heavy dot-dot-dash pattern."""
|
|
356
|
+
|
|
357
|
+
WAVY_HEAVY = (27, "wavyHeavy", "A heavy wavy line.")
|
|
358
|
+
"""A heavy wavy line."""
|
|
359
|
+
|
|
360
|
+
DASH_LONG = (39, "dashLong", "Long dashes.")
|
|
361
|
+
"""Long dashes."""
|
|
362
|
+
|
|
363
|
+
WAVY_DOUBLE = (43, "wavyDouble", "A double wavy line.")
|
|
364
|
+
"""A double wavy line."""
|
|
365
|
+
|
|
366
|
+
DASH_LONG_HEAVY = (55, "dashLongHeavy", "Long heavy dashes.")
|
|
367
|
+
"""Long heavy dashes."""
|
docx/exceptions.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Exceptions used with python-docx.
|
|
2
|
+
|
|
3
|
+
The base exception class is PythonDocxError.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PythonDocxError(Exception):
|
|
8
|
+
"""Generic error class."""
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InvalidSpanError(PythonDocxError):
|
|
12
|
+
"""Raised when an invalid merge region is specified in a request to merge table
|
|
13
|
+
cells."""
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InvalidXmlError(PythonDocxError):
|
|
17
|
+
"""Raised when invalid XML is encountered, such as on attempt to access a missing
|
|
18
|
+
required child element."""
|
docx/image/__init__.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Provides objects that can characterize image streams.
|
|
2
|
+
|
|
3
|
+
That characterization is as to content type and size, as a required step in including
|
|
4
|
+
them in a document.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from docx.image.bmp import Bmp
|
|
8
|
+
from docx.image.gif import Gif
|
|
9
|
+
from docx.image.jpeg import Exif, Jfif
|
|
10
|
+
from docx.image.png import Png
|
|
11
|
+
from docx.image.tiff import Tiff
|
|
12
|
+
|
|
13
|
+
SIGNATURES = (
|
|
14
|
+
# class, offset, signature_bytes
|
|
15
|
+
(Png, 0, b"\x89PNG\x0d\x0a\x1a\x0a"),
|
|
16
|
+
(Jfif, 6, b"JFIF"),
|
|
17
|
+
(Exif, 6, b"Exif"),
|
|
18
|
+
(Gif, 0, b"GIF87a"),
|
|
19
|
+
(Gif, 0, b"GIF89a"),
|
|
20
|
+
(Tiff, 0, b"MM\x00*"), # big-endian (Motorola) TIFF
|
|
21
|
+
(Tiff, 0, b"II*\x00"), # little-endian (Intel) TIFF
|
|
22
|
+
(Bmp, 0, b"BM"),
|
|
23
|
+
)
|
docx/image/bmp.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from .constants import MIME_TYPE
|
|
2
|
+
from .helpers import LITTLE_ENDIAN, StreamReader
|
|
3
|
+
from .image import BaseImageHeader
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Bmp(BaseImageHeader):
|
|
7
|
+
"""Image header parser for BMP images."""
|
|
8
|
+
|
|
9
|
+
@classmethod
|
|
10
|
+
def from_stream(cls, stream):
|
|
11
|
+
"""Return |Bmp| instance having header properties parsed from the BMP image in
|
|
12
|
+
`stream`."""
|
|
13
|
+
stream_rdr = StreamReader(stream, LITTLE_ENDIAN)
|
|
14
|
+
|
|
15
|
+
px_width = stream_rdr.read_long(0x12)
|
|
16
|
+
px_height = stream_rdr.read_long(0x16)
|
|
17
|
+
|
|
18
|
+
horz_px_per_meter = stream_rdr.read_long(0x26)
|
|
19
|
+
vert_px_per_meter = stream_rdr.read_long(0x2A)
|
|
20
|
+
|
|
21
|
+
horz_dpi = cls._dpi(horz_px_per_meter)
|
|
22
|
+
vert_dpi = cls._dpi(vert_px_per_meter)
|
|
23
|
+
|
|
24
|
+
return cls(px_width, px_height, horz_dpi, vert_dpi)
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def content_type(self):
|
|
28
|
+
"""MIME content type for this image, unconditionally `image/bmp` for BMP
|
|
29
|
+
images."""
|
|
30
|
+
return MIME_TYPE.BMP
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def default_ext(self):
|
|
34
|
+
"""Default filename extension, always 'bmp' for BMP images."""
|
|
35
|
+
return "bmp"
|
|
36
|
+
|
|
37
|
+
@staticmethod
|
|
38
|
+
def _dpi(px_per_meter):
|
|
39
|
+
"""Return the integer pixels per inch from `px_per_meter`, defaulting to 96 if
|
|
40
|
+
`px_per_meter` is zero."""
|
|
41
|
+
if px_per_meter == 0:
|
|
42
|
+
return 96
|
|
43
|
+
return int(round(px_per_meter * 0.0254))
|
docx/image/constants.py
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"""Constants specific the the image sub-package."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class JPEG_MARKER_CODE:
|
|
5
|
+
"""JPEG marker codes."""
|
|
6
|
+
|
|
7
|
+
TEM = b"\x01"
|
|
8
|
+
DHT = b"\xc4"
|
|
9
|
+
DAC = b"\xcc"
|
|
10
|
+
JPG = b"\xc8"
|
|
11
|
+
|
|
12
|
+
SOF0 = b"\xc0"
|
|
13
|
+
SOF1 = b"\xc1"
|
|
14
|
+
SOF2 = b"\xc2"
|
|
15
|
+
SOF3 = b"\xc3"
|
|
16
|
+
SOF5 = b"\xc5"
|
|
17
|
+
SOF6 = b"\xc6"
|
|
18
|
+
SOF7 = b"\xc7"
|
|
19
|
+
SOF9 = b"\xc9"
|
|
20
|
+
SOFA = b"\xca"
|
|
21
|
+
SOFB = b"\xcb"
|
|
22
|
+
SOFD = b"\xcd"
|
|
23
|
+
SOFE = b"\xce"
|
|
24
|
+
SOFF = b"\xcf"
|
|
25
|
+
|
|
26
|
+
RST0 = b"\xd0"
|
|
27
|
+
RST1 = b"\xd1"
|
|
28
|
+
RST2 = b"\xd2"
|
|
29
|
+
RST3 = b"\xd3"
|
|
30
|
+
RST4 = b"\xd4"
|
|
31
|
+
RST5 = b"\xd5"
|
|
32
|
+
RST6 = b"\xd6"
|
|
33
|
+
RST7 = b"\xd7"
|
|
34
|
+
|
|
35
|
+
SOI = b"\xd8"
|
|
36
|
+
EOI = b"\xd9"
|
|
37
|
+
SOS = b"\xda"
|
|
38
|
+
DQT = b"\xdb" # Define Quantization Table(s)
|
|
39
|
+
DNL = b"\xdc"
|
|
40
|
+
DRI = b"\xdd"
|
|
41
|
+
DHP = b"\xde"
|
|
42
|
+
EXP = b"\xdf"
|
|
43
|
+
|
|
44
|
+
APP0 = b"\xe0"
|
|
45
|
+
APP1 = b"\xe1"
|
|
46
|
+
APP2 = b"\xe2"
|
|
47
|
+
APP3 = b"\xe3"
|
|
48
|
+
APP4 = b"\xe4"
|
|
49
|
+
APP5 = b"\xe5"
|
|
50
|
+
APP6 = b"\xe6"
|
|
51
|
+
APP7 = b"\xe7"
|
|
52
|
+
APP8 = b"\xe8"
|
|
53
|
+
APP9 = b"\xe9"
|
|
54
|
+
APPA = b"\xea"
|
|
55
|
+
APPB = b"\xeb"
|
|
56
|
+
APPC = b"\xec"
|
|
57
|
+
APPD = b"\xed"
|
|
58
|
+
APPE = b"\xee"
|
|
59
|
+
APPF = b"\xef"
|
|
60
|
+
|
|
61
|
+
STANDALONE_MARKERS = (TEM, SOI, EOI, RST0, RST1, RST2, RST3, RST4, RST5, RST6, RST7)
|
|
62
|
+
|
|
63
|
+
SOF_MARKER_CODES = (
|
|
64
|
+
SOF0,
|
|
65
|
+
SOF1,
|
|
66
|
+
SOF2,
|
|
67
|
+
SOF3,
|
|
68
|
+
SOF5,
|
|
69
|
+
SOF6,
|
|
70
|
+
SOF7,
|
|
71
|
+
SOF9,
|
|
72
|
+
SOFA,
|
|
73
|
+
SOFB,
|
|
74
|
+
SOFD,
|
|
75
|
+
SOFE,
|
|
76
|
+
SOFF,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
marker_names = {
|
|
80
|
+
b"\x00": "UNKNOWN",
|
|
81
|
+
b"\xc0": "SOF0",
|
|
82
|
+
b"\xc2": "SOF2",
|
|
83
|
+
b"\xc4": "DHT",
|
|
84
|
+
b"\xda": "SOS", # start of scan
|
|
85
|
+
b"\xd8": "SOI", # start of image
|
|
86
|
+
b"\xd9": "EOI", # end of image
|
|
87
|
+
b"\xdb": "DQT",
|
|
88
|
+
b"\xe0": "APP0",
|
|
89
|
+
b"\xe1": "APP1",
|
|
90
|
+
b"\xe2": "APP2",
|
|
91
|
+
b"\xed": "APP13",
|
|
92
|
+
b"\xee": "APP14",
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@classmethod
|
|
96
|
+
def is_standalone(cls, marker_code):
|
|
97
|
+
return marker_code in cls.STANDALONE_MARKERS
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MIME_TYPE:
|
|
101
|
+
"""Image content types."""
|
|
102
|
+
|
|
103
|
+
BMP = "image/bmp"
|
|
104
|
+
GIF = "image/gif"
|
|
105
|
+
JPEG = "image/jpeg"
|
|
106
|
+
PNG = "image/png"
|
|
107
|
+
TIFF = "image/tiff"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class PNG_CHUNK_TYPE:
|
|
111
|
+
"""PNG chunk type names."""
|
|
112
|
+
|
|
113
|
+
IHDR = "IHDR"
|
|
114
|
+
pHYs = "pHYs"
|
|
115
|
+
IEND = "IEND"
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class TIFF_FLD_TYPE:
|
|
119
|
+
"""Tag codes for TIFF Image File Directory (IFD) entries."""
|
|
120
|
+
|
|
121
|
+
BYTE = 1
|
|
122
|
+
ASCII = 2
|
|
123
|
+
SHORT = 3
|
|
124
|
+
LONG = 4
|
|
125
|
+
RATIONAL = 5
|
|
126
|
+
|
|
127
|
+
field_type_names = {
|
|
128
|
+
1: "BYTE",
|
|
129
|
+
2: "ASCII char",
|
|
130
|
+
3: "SHORT",
|
|
131
|
+
4: "LONG",
|
|
132
|
+
5: "RATIONAL",
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
TIFF_FLD = TIFF_FLD_TYPE
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class TIFF_TAG:
|
|
140
|
+
"""Tag codes for TIFF Image File Directory (IFD) entries."""
|
|
141
|
+
|
|
142
|
+
IMAGE_WIDTH = 0x0100
|
|
143
|
+
IMAGE_LENGTH = 0x0101
|
|
144
|
+
X_RESOLUTION = 0x011A
|
|
145
|
+
Y_RESOLUTION = 0x011B
|
|
146
|
+
RESOLUTION_UNIT = 0x0128
|
|
147
|
+
|
|
148
|
+
tag_names = {
|
|
149
|
+
0x00FE: "NewSubfileType",
|
|
150
|
+
0x0100: "ImageWidth",
|
|
151
|
+
0x0101: "ImageLength",
|
|
152
|
+
0x0102: "BitsPerSample",
|
|
153
|
+
0x0103: "Compression",
|
|
154
|
+
0x0106: "PhotometricInterpretation",
|
|
155
|
+
0x010E: "ImageDescription",
|
|
156
|
+
0x010F: "Make",
|
|
157
|
+
0x0110: "Model",
|
|
158
|
+
0x0111: "StripOffsets",
|
|
159
|
+
0x0112: "Orientation",
|
|
160
|
+
0x0115: "SamplesPerPixel",
|
|
161
|
+
0x0117: "StripByteCounts",
|
|
162
|
+
0x011A: "XResolution",
|
|
163
|
+
0x011B: "YResolution",
|
|
164
|
+
0x011C: "PlanarConfiguration",
|
|
165
|
+
0x0128: "ResolutionUnit",
|
|
166
|
+
0x0131: "Software",
|
|
167
|
+
0x0132: "DateTime",
|
|
168
|
+
0x0213: "YCbCrPositioning",
|
|
169
|
+
0x8769: "ExifTag",
|
|
170
|
+
0x8825: "GPS IFD",
|
|
171
|
+
0xC4A5: "PrintImageMatching",
|
|
172
|
+
}
|
docx/image/exceptions.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Exceptions specific the the image sub-package."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class InvalidImageStreamError(Exception):
|
|
5
|
+
"""The recognized image stream appears to be corrupted."""
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UnexpectedEndOfFileError(Exception):
|
|
9
|
+
"""EOF was unexpectedly encountered while reading an image stream."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class UnrecognizedImageError(Exception):
|
|
13
|
+
"""The provided image stream could not be recognized."""
|
docx/image/gif.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from struct import Struct
|
|
2
|
+
|
|
3
|
+
from .constants import MIME_TYPE
|
|
4
|
+
from .image import BaseImageHeader
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Gif(BaseImageHeader):
|
|
8
|
+
"""Image header parser for GIF images.
|
|
9
|
+
|
|
10
|
+
Note that the GIF format does not support resolution (DPI) information. Both
|
|
11
|
+
horizontal and vertical DPI default to 72.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
@classmethod
|
|
15
|
+
def from_stream(cls, stream):
|
|
16
|
+
"""Return |Gif| instance having header properties parsed from GIF image in
|
|
17
|
+
`stream`."""
|
|
18
|
+
px_width, px_height = cls._dimensions_from_stream(stream)
|
|
19
|
+
return cls(px_width, px_height, 72, 72)
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def content_type(self):
|
|
23
|
+
"""MIME content type for this image, unconditionally `image/gif` for GIF
|
|
24
|
+
images."""
|
|
25
|
+
return MIME_TYPE.GIF
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def default_ext(self):
|
|
29
|
+
"""Default filename extension, always 'gif' for GIF images."""
|
|
30
|
+
return "gif"
|
|
31
|
+
|
|
32
|
+
@classmethod
|
|
33
|
+
def _dimensions_from_stream(cls, stream):
|
|
34
|
+
stream.seek(6)
|
|
35
|
+
bytes_ = stream.read(4)
|
|
36
|
+
struct = Struct("<HH")
|
|
37
|
+
px_width, px_height = struct.unpack(bytes_)
|
|
38
|
+
return px_width, px_height
|