5
5
from typing import TYPE_CHECKING , Callable
6
6
7
7
from docx .enum .dml import MSO_THEME_COLOR
8
- from docx .enum .text import WD_COLOR , WD_UNDERLINE
9
- from docx .oxml .ns import nsdecls , qn
8
+ from docx .enum .text import WD_COLOR_INDEX , WD_UNDERLINE
9
+ from docx .oxml .ns import nsdecls
10
10
from docx .oxml .parser import parse_xml
11
11
from docx .oxml .simpletypes import (
12
12
ST_HexColor ,
23
23
24
24
if TYPE_CHECKING :
25
25
from docx .oxml .shared import CT_OnOff , CT_String
26
+ from docx .shared import Length
26
27
27
28
28
29
class CT_Color (BaseOxmlElement ):
@@ -33,32 +34,50 @@ class CT_Color(BaseOxmlElement):
33
34
34
35
35
36
class CT_Fonts (BaseOxmlElement ):
36
- """``<w:rFonts>`` element, specifying typeface name for the various language
37
- types."""
37
+ """`<w:rFonts>` element.
38
38
39
- ascii = OptionalAttribute ("w:ascii" , ST_String )
40
- hAnsi = OptionalAttribute ("w:hAnsi" , ST_String )
39
+ Specifies typeface name for the various language types.
40
+ """
41
+
42
+ ascii : str | None = OptionalAttribute ( # pyright: ignore[reportGeneralTypeIssues]
43
+ "w:ascii" , ST_String
44
+ )
45
+ hAnsi : str | None = OptionalAttribute ( # pyright: ignore[reportGeneralTypeIssues]
46
+ "w:hAnsi" , ST_String
47
+ )
41
48
42
49
43
50
class CT_Highlight (BaseOxmlElement ):
44
51
"""`w:highlight` element, specifying font highlighting/background color."""
45
52
46
- val = RequiredAttribute ("w:val" , WD_COLOR )
53
+ val : WD_COLOR_INDEX = RequiredAttribute ( # pyright: ignore[reportGeneralTypeIssues]
54
+ "w:val" , WD_COLOR_INDEX
55
+ )
47
56
48
57
49
58
class CT_HpsMeasure (BaseOxmlElement ):
50
- """Used for `` <w:sz>` ` element and others, specifying font size in half-points."""
59
+ """Used for `<w:sz>` element and others, specifying font size in half-points."""
51
60
52
- val = RequiredAttribute ("w:val" , ST_HpsMeasure )
61
+ val : Length = RequiredAttribute ( # pyright: ignore[reportGeneralTypeIssues]
62
+ "w:val" , ST_HpsMeasure
63
+ )
53
64
54
65
55
66
class CT_RPr (BaseOxmlElement ):
56
- """`` <w:rPr>` ` element, containing the properties for a run."""
67
+ """`<w:rPr>` element, containing the properties for a run."""
57
68
58
- _add_u : Callable [[], CT_Underline ]
69
+ get_or_add_highlight : Callable [[], CT_Highlight ]
70
+ get_or_add_rFonts : Callable [[], CT_Fonts ]
71
+ get_or_add_sz : Callable [[], CT_HpsMeasure ]
72
+ get_or_add_vertAlign : Callable [[], CT_VerticalAlignRun ]
59
73
_add_rStyle : Callable [..., CT_String ]
60
- _remove_u : Callable [[], None ]
74
+ _add_u : Callable [[], CT_Underline ]
75
+ _remove_highlight : Callable [[], None ]
76
+ _remove_rFonts : Callable [[], None ]
61
77
_remove_rStyle : Callable [[], None ]
78
+ _remove_sz : Callable [[], None ]
79
+ _remove_u : Callable [[], None ]
80
+ _remove_vertAlign : Callable [[], None ]
62
81
63
82
_tag_seq = (
64
83
"w:rStyle" ,
@@ -104,7 +123,9 @@ class CT_RPr(BaseOxmlElement):
104
123
rStyle : CT_String | None = ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
105
124
"w:rStyle" , successors = _tag_seq [1 :]
106
125
)
107
- rFonts = ZeroOrOne ("w:rFonts" , successors = _tag_seq [2 :])
126
+ rFonts : CT_Fonts | None = ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
127
+ "w:rFonts" , successors = _tag_seq [2 :]
128
+ )
108
129
b : CT_OnOff | None = ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
109
130
"w:b" , successors = _tag_seq [3 :]
110
131
)
@@ -124,12 +145,22 @@ class CT_RPr(BaseOxmlElement):
124
145
vanish = ZeroOrOne ("w:vanish" , successors = _tag_seq [17 :])
125
146
webHidden = ZeroOrOne ("w:webHidden" , successors = _tag_seq [18 :])
126
147
color = ZeroOrOne ("w:color" , successors = _tag_seq [19 :])
127
- sz = ZeroOrOne ("w:sz" , successors = _tag_seq [24 :])
128
- highlight = ZeroOrOne ("w:highlight" , successors = _tag_seq [26 :])
148
+ sz : CT_HpsMeasure | None = ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
149
+ "w:sz" , successors = _tag_seq [24 :]
150
+ )
151
+ highlight : CT_Highlight | None = (
152
+ ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
153
+ "w:highlight" , successors = _tag_seq [26 :]
154
+ )
155
+ )
129
156
u : CT_Underline | None = ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
130
157
"w:u" , successors = _tag_seq [27 :]
131
158
)
132
- vertAlign = ZeroOrOne ("w:vertAlign" , successors = _tag_seq [32 :])
159
+ vertAlign : CT_VerticalAlignRun | None = (
160
+ ZeroOrOne ( # pyright: ignore[reportGeneralTypeIssues]
161
+ "w:vertAlign" , successors = _tag_seq [32 :]
162
+ )
163
+ )
133
164
rtl = ZeroOrOne ("w:rtl" , successors = _tag_seq [33 :])
134
165
cs = ZeroOrOne ("w:cs" , successors = _tag_seq [34 :])
135
166
specVanish = ZeroOrOne ("w:specVanish" , successors = _tag_seq [38 :])
@@ -141,24 +172,26 @@ def _new_color(self):
141
172
return parse_xml ('<w:color %s w:val="000000"/>' % nsdecls ("w" ))
142
173
143
174
@property
144
- def highlight_val (self ):
145
- """Value of `w:highlight/@val` attribute, specifying a font's highlight color,
146
- or `None` if the text is not highlighted."""
175
+ def highlight_val (self ) -> WD_COLOR_INDEX | None :
E0E7
176
+ """Value of `./w:highlight/@val`.
177
+
178
+ Specifies font's highlight color, or `None` if the text is not highlighted.
179
+ """
147
180
highlight = self .highlight
148
181
if highlight is None :
149
182
return None
150
183
return highlight .val
151
184
152
185
@highlight_val .setter
153
- def highlight_val (self , value ) :
186
+ def highlight_val (self , value : WD_COLOR_INDEX | None ) -> None :
154
187
if value is None :
155
188
self ._remove_highlight ()
156
189
return
157
190
highlight = self .get_or_add_highlight ()
158
191
highlight .val = value
159
192
160
193
@property
161
- def rFonts_ascii (self ):
194
+ def rFonts_ascii (self ) -> str | None :
162
195
"""The value of `w:rFonts/@w:ascii` or |None| if not present.
163
196
164
197
Represents the assigned typeface name. The rFonts element also specifies other
@@ -171,23 +204,23 @@ def rFonts_ascii(self):
171
204
return rFonts .ascii
172
205
173
206
@rFonts_ascii .setter
174
- def rFonts_ascii (self , value ) :
207
+ def rFonts_ascii (self , value : str | None ) -> None :
175
208
if value is None :
176
209
self ._remove_rFonts ()
177
210
return
178
211
rFonts = self .get_or_add_rFonts ()
179
212
rFonts .ascii = value
180
213
181
214
@property
182
- def rFonts_hAnsi (self ):
215
+ def rFonts_hAnsi (self ) -> str | None :
183
216
"""The value of `w:rFonts/@w:hAnsi` or |None| if not present."""
184
217
rFonts = self .rFonts
185
218
if rFonts is None :
186
219
return None
187
220
return rFonts .hAnsi
188
221
189
222
@rFonts_hAnsi .setter
190
- def rFonts_hAnsi (self , value ):
223
+ def rFonts_hAnsi (self , value : str | None ):
191
224
if value is None and self .rFonts is None :
192
225
return
193
226
rFonts = self .get_or_add_rFonts ()
@@ -215,8 +248,8 @@ def style(self, style: str | None) -> None:
215
248
self .rStyle .val = style
216
249
217
250
@property
218
- def subscript (self ):
219
- """|True| if `w:vertAlign/@w:val` is ' subscript' .
251
+ def subscript (self ) -> bool | None :
252
+ """|True| if `./ w:vertAlign/@w:val` is " subscript" .
220
253
221
254
|False| if `w:vertAlign/@w:val` contains any other value. |None| if
222
255
`w:vertAlign` is not present.
@@ -229,18 +262,20 @@ def subscript(self):
229
262
return False
230
263
231
264
@subscript .setter
232
- def subscript (self , value ) :
265
+ def subscript (self , value : bool | None ) -> None :
233
266
if value is None :
234
267
self ._remove_vertAlign ()
235
268
elif bool (value ) is True :
236
269
self .get_or_add_vertAlign ().val = ST_VerticalAlignRun .SUBSCRIPT
237
- elif self .vertAlign is None :
238
- return
239
- elif self .vertAlign .val == ST_VerticalAlignRun .SUBSCRIPT :
270
+ # -- assert bool(value) is False --
271
+ elif (
272
+ self .vertAlign is not None
273
+ and self .vertAlign .val == ST_VerticalAlignRun .SUBSCRIPT
274
+ ):
240
275
self ._remove_vertAlign ()
241
276
242
277
@property
243
- def superscript (self ):
278
+ def superscript (self ) -> bool | None :
244
279
"""|True| if `w:vertAlign/@w:val` is 'superscript'.
245
280
246
281
|False| if `w:vertAlign/@w:val` contains any other value. |None| if
@@ -254,34 +289,36 @@ def superscript(self):
254
289
return False
255
290
256
291
@superscript .setter
257
- def superscript (self , value ):
292
+ def superscript (self , value : bool | None ):
258
293
if value is None :
259
294
self ._remove_vertAlign ()
260
295
elif bool (value ) is True :
261
296
self .get_or_add_vertAlign ().val = ST_VerticalAlignRun .SUPERSCRIPT
262
- elif self .vertAlign is None :
263
- return
264
- elif self .vertAlign .val == ST_VerticalAlignRun .SUPERSCRIPT :
297
+ # -- assert bool(value) is False --
298
+ elif (
299
+ self .vertAlign is not None
300
+ and self .vertAlign .val == ST_VerticalAlignRun .SUPERSCRIPT
301
+ ):
265
302
self ._remove_vertAlign ()
266
303
267
304
@property
268
- def sz_val (self ):
305
+ def sz_val (self ) -> Length | None :
269
306
"""The value of `w:sz/@w:val` or |None| if not present."""
270
307
sz = self .sz
271
308
if sz is None :
272
309
return None
273
310
return sz .val
274
311
275
312
@sz_val .setter
276
- def sz_val (self , value ):
313
+ def sz_val (self , value : Length | None ):
277
314
if value is None :
278
315
self ._remove_sz ()
279
316
return
280
317
sz = self .get_or_add_sz ()
281
318
sz .val = value
282
319
283
320
@property
284
- def u_val (self ) -> bool | WD_UNDERLINE | None :
321
+ def u_val (self ) -> WD_UNDERLINE | None :
285
322
"""Value of `w:u/@val`, or None if not present.
286
323
287
324
Values `WD_UNDERLINE.SINGLE` and `WD_UNDERLINE.NONE` are mapped to `True` and
@@ -293,7 +330,7 @@ def u_val(self) -> bool | WD_UNDERLINE | None:
293
330
return u .val
294
331
295
332
@u_val .setter
296
- def u_val (self , value : bool | WD_UNDERLINE | None ):
333
+ def u_val (self , value : WD_UNDERLINE | None ):
297
334
self ._remove_u ()
298
335
if value is not None :
299
336
self ._add_u ().val = value
@@ -314,38 +351
3BFD
,18 @@ def _set_bool_val(self, name: str, value: bool | None):
314
351
315
352
316
353
class CT_Underline (BaseOxmlElement ):
317
- """`` <w:u>` ` element, specifying the underlining style for a run."""
354
+ """`<w:u>` element, specifying the underlining style for a run."""
318
355
319
- @property
320
- def val (self ) -> bool | WD_UNDERLINE | None :
321
- """The underline type corresponding to the ``w:val`` attr
F438
ibute value."""
322
- val = self .get (qn ("w:val" ))
323
- underline = WD_UNDERLINE .from_xml (val )
324
- return (
325
- None
326
- if underline == WD_UNDERLINE .INHERITED
327
- else True
328
- if underline == WD_UNDERLINE .SINGLE
329
- else False
330
- if underline == WD_UNDERLINE .NONE
331
- else underline
356
+ val : WD_UNDERLINE | None = (
357
+ OptionalAttribute ( # pyright: ignore[reportGeneralTypeIssues]
358
+ "w:val" , WD_UNDERLINE
332
359
)
333
-
334
- @val .setter
335
- def val (self , value : bool | WD_UNDERLINE | None ):
336
- # works fine without these two mappings, but only because True == 1
337
- # and False == 0, which happen to match the mapping for WD_UNDERLINE
338
- # .SINGLE and .NONE respectively.
339
- if value is True :
340
- value = WD_UNDERLINE .SINGLE
341
- elif value is False :
342
- value = WD_UNDERLINE .NONE
343
-
344
- val = WD_UNDERLINE .to_xml (value )
345
- self .set (qn ("w:val" ), val )
360
+ )
346
361
347
362
348
363
class CT_VerticalAlignRun (BaseOxmlElement ):
349
- """`` <w:vertAlign>` ` element, specifying subscript or superscript."""
364
+ """`<w:vertAlign>` element, specifying subscript or superscript."""
350
365
351
- val = RequiredAttribute ("w:val" , ST_VerticalAlignRun )
366
+ val : str = RequiredAttribute ( # pyright: ignore[reportGeneralTypeIssues]
367
+ "w:val" , ST_VerticalAlignRun
368
+ )
0 commit comments