Skip to content

Commit c4ba0bd

Browse files
author
Steve Canny
committed
font: add Font.name getter
1 parent 234cc0f commit c4ba0bd

File tree

6 files changed

+62
-5
lines changed

6 files changed

+62
-5
lines changed

docx/oxml/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
142142
register_element_cls('w:pPr', CT_PPr)
143143
register_element_cls('w:pStyle', CT_String)
144144

145-
from .text.run import CT_Br, CT_R, CT_RPr, CT_Text, CT_Underline
145+
from .text.run import CT_Br, CT_Fonts, CT_R, CT_RPr, CT_Text, CT_Underline
146146
register_element_cls('w:b', CT_OnOff)
147147
register_element_cls('w:bCs', CT_OnOff)
148148
register_element_cls('w:br', CT_Br)
@@ -157,6 +157,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
157157
register_element_cls('w:oMath', CT_OnOff)
158158
register_element_cls('w:outline', CT_OnOff)
159159
register_element_cls('w:r', CT_R)
160+
register_element_cls('w:rFonts', CT_Fonts)
160161
register_element_cls('w:rPr', CT_RPr)
161162
register_element_cls('w:rStyle', CT_String)
162163
register_element_cls('w:rtl', CT_OnOff)

docx/oxml/styles.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ class CT_Style(BaseOxmlElement):
4444
name = ZeroOrOne('w:name', successors=_tag_seq[1:])
4545
basedOn = ZeroOrOne('w:basedOn', successors=_tag_seq[3:])
4646
pPr = ZeroOrOne('w:pPr', successors=_tag_seq[17:])
47+
rPr = ZeroOrOne('w:rPr', successors=_tag_seq[18:])
48+
del _tag_seq
49+
4750
type = OptionalAttribute('w:type', WD_STYLE_TYPE)
4851
styleId = OptionalAttribute('w:styleId', ST_String)
4952
default = OptionalAttribute('w:default', ST_OnOff)
5053
customStyle = OptionalAttribute('w:customStyle', ST_OnOff)
51-
del _tag_seq
5254

5355
@property
5456
def basedOn_val(self):

docx/oxml/text/run.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from ...enum.text import WD_UNDERLINE
88
from ..ns import qn
9-
from ..simpletypes import ST_BrClear, ST_BrType
9+
from ..simpletypes import ST_BrClear, ST_BrType, ST_String
1010
from ..xmlchemy import (
1111
BaseOxmlElement, OptionalAttribute, ZeroOrMore, ZeroOrOne
1212
)
@@ -20,6 +20,14 @@ class CT_Br(BaseOxmlElement):
2020
clear = OptionalAttribute('w:clear', ST_BrClear)
2121

2222

23+
class CT_Fonts(BaseOxmlElement):
24+
"""
25+
``<w:rFonts>`` element, specifying typeface name for the various language
26+
types.
27+
"""
28+
ascii = OptionalAttribute('w:ascii', ST_String)
29+
30+
2331
class CT_R(BaseOxmlElement):
2432
"""
2533
``<w:r>`` element, containing the properties and text for a run.
@@ -135,6 +143,7 @@ class CT_RPr(BaseOxmlElement):
135143
'w:eastAsianLayout', 'w:specVanish', 'w:oMath'
136144
)
137145
rStyle = ZeroOrOne('w:rStyle', successors=_tag_seq[1:])
146+
rFonts = ZeroOrOne('w:rFonts', successors=_tag_seq[2:])
138147
b = ZeroOrOne('w:b', successors=_tag_seq[3:])
139148
bCs = ZeroOrOne('w:bCs', successors=_tag_seq[4:])
140149
i = ZeroOrOne('w:i', successors=_tag_seq[5:])
@@ -158,6 +167,19 @@ class CT_RPr(BaseOxmlElement):
158167
oMath = ZeroOrOne('w:oMath', successors=_tag_seq[39:])
159168
del _tag_seq
160169

170+
@property
171+
def rFonts_ascii(self):
172+
"""
173+
The value of `w:rFonts/@w:ascii` or |None| if not present. Represents
174+
the assigned typeface name. The rFonts element also specifies other
175+
special-case typeface names; this method handles the case where just
176+
the common name is required.
177+
"""
178+
rFonts = self.rFonts
179+
if rFonts is None:
180+
return None
181+
return rFonts.ascii
182+
161183
@property
162184
def style(self):
163185
"""

docx/text/run.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,19 @@ class Font(ElementProxy):
381381

382382
__slots__ = ()
383383

384+
@property
385+
def name(self):
386+
"""
387+
Get or set the typeface name for this |Font| instance, causing the
388+
text it controls to appear in the named font, if a matching font is
389+
found. |None| indicates the typeface is inherited from the style
390+
hierarchy.
391+
"""
392+
rPr = self._element.rPr
393+
if rPr is None:
394+
return None
395+
return rPr.rFonts_ascii
396+
384397

385398
class _Text(object):
386399
"""

features/txt-font-props.feature

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ Feature: Get or set font properties
44
I need a set of read/write properties on the Font object
55

66

7-
@wip
87
Scenario Outline: Get typeface name
98
Given a font having typeface name <name>
109
Then font.name is <value>

tests/text/test_run.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from docx.parts.document import InlineShapes
1313
from docx.shape import InlineShape
1414
from docx.text.paragraph import Paragraph
15-
from docx.text.run import Run
15+
from docx.text.run import Font, Run
1616

1717
import pytest
1818

@@ -366,3 +366,23 @@ def picture_(self, request):
366366
@pytest.fixture
367367
def Text_(self, request):
368368
return class_mock(request, 'docx.text.run._Text')
369+
370+
371+
class DescribeFont(object):
372+
373+
def it_knows_its_typeface_name(self, name_get_fixture):
374+
font, expected_value = name_get_fixture
375+
assert font.name == expected_value
376+
377+
# fixtures -------------------------------------------------------
378+
379+
@pytest.fixture(params=[
380+
('w:r', None),
381+
('w:r/w:rPr', None),
382+
('w:r/w:rPr/w:rFonts', None),
383+
('w:r/w:rPr/w:rFonts{w:ascii=Arial}', 'Arial'),
384+
])
385+
def name_get_fixture(self, request):
386+
r_cxml, expected_value = request.param
387+
font = Font(element(r_cxml))
388+
return font, expected_value

0 commit comments

Comments
 (0)