Skip to content

Commit 752af0d

Browse files
author
Steve Canny
committed
oxml: use templating for CT_Inline.new()
1 parent 8866284 commit 752af0d

File tree

4 files changed

+57
-44
lines changed

4 files changed

+57
-44
lines changed

docx/oxml/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def OxmlElement(nsptag_str, attrs=None, nsdecls=None):
8383
register_element_cls('pic:nvPicPr', CT_PictureNonVisual)
8484
register_element_cls('pic:pic', CT_Picture)
8585
register_element_cls('pic:spPr', CT_ShapeProperties)
86+
register_element_cls('wp:docPr', CT_NonVisualDrawingProps)
8687
register_element_cls('wp:extent', CT_PositiveSize2D)
8788
register_element_cls('wp:inline', CT_Inline)
8889

docx/oxml/shape.py

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
Custom element classes for shape-related elements like ``<w:inline>``
55
"""
66

7-
from . import OxmlElement, parse_xml
8-
from .ns import nsdecls, nsmap, nspfxmap
7+
from . import parse_xml
8+
from .ns import nsdecls
99
from .simpletypes import (
1010
ST_Coordinate, ST_DrawingElementId, ST_PositiveCoordinate,
1111
ST_RelationshipId, XsdString, XsdToken
@@ -40,12 +40,6 @@ class CT_GraphicalObject(BaseOxmlElement):
4040
"""
4141
graphicData = OneAndOnlyOne('a:graphicData')
4242

43-
@classmethod
44-
def new(cls, uri, pic):
45-
graphic = OxmlElement('a:graphic')
46-
graphic.append(CT_GraphicalObjectData.new(uri, pic))
47-
return graphic
48-
4943

5044
class CT_GraphicalObjectData(BaseOxmlElement):
5145
"""
@@ -54,19 +48,13 @@ class CT_GraphicalObjectData(BaseOxmlElement):
5448
pic = ZeroOrOne('pic:pic')
5549
uri = RequiredAttribute('uri', XsdToken)
5650

57-
@classmethod
58-
def new(cls, uri, pic):
59-
graphicData = OxmlElement('a:graphicData')
60-
graphicData.uri = uri
61-
graphicData._insert_pic(pic)
62-
return graphicData
63-
6451

6552
class CT_Inline(BaseOxmlElement):
6653
"""
6754
``<w:inline>`` element, container for an inline shape.
6855
"""
6956
extent = OneAndOnlyOne('wp:extent')
57+
docPr = OneAndOnlyOne('wp:docPr')
7058
graphic = OneAndOnlyOne('a:graphic')
7159

7260
@classmethod
@@ -75,17 +63,32 @@ def new(cls, cx, cy, shape_id, pic):
7563
Return a new ``<wp:inline>`` element populated with the values passed
7664
as parameters.
7765
"""
78-
name = 'Picture %d' % shape_id
79-
uri = nsmap['pic']
80-
81-
inline = OxmlElement('wp:inline', nsdecls=nspfxmap('wp', 'r'))
82-
inline.append(CT_PositiveSize2D.new('wp:extent', cx, cy))
83-
inline.append(CT_NonVisualDrawingProps.new(
84-
'wp:docPr', shape_id, name
85-
))
86-
inline.append(CT_GraphicalObject.new(uri, pic))
66+
inline = parse_xml(cls._inline_xml())
67+
inline.extent.cx = cx
68+
inline.extent.cy = cy
69+
inline.docPr.id = shape_id
70+
inline.docPr.name = 'Picture %d' % shape_id
71+
inline.graphic.graphicData.uri = (
72+
'http://schemas.openxmlformats.org/drawingml/2006/picture'
73+
)
74+
inline.graphic.graphicData._insert_pic(pic)
8775
return inline
8876

77+
@classmethod
78+
def _inline_xml(cls):
79+
return (
80+
'<wp:inline %s>\n'
81+
' <wp:extent cx="914400" cy="914400"/>\n'
82+
' <wp:docPr id="666" name="unnamed"/>\n'
83+
' <wp:cNvGraphicFramePr>\n'
84+
' <a:graphicFrameLocks noChangeAspect="1"/>\n'
85+
' </wp:cNvGraphicFramePr>\n'
86+
' <a:graphic>\n'
87+
' <a:graphicData uri="URI not set"/>\n'
88+
' </a:graphic>\n'
89+
'</wp:inline>' % nsdecls('wp', 'a', 'pic', 'r')
90+
)
91+
8992

9093
class CT_NonVisualDrawingProps(BaseOxmlElement):
9194
"""
@@ -95,13 +98,6 @@ class CT_NonVisualDrawingProps(BaseOxmlElement):
9598
id = RequiredAttribute('id', ST_DrawingElementId)
9699
name = RequiredAttribute('name', XsdString)
97100

98-
@classmethod
99-
def new(cls, nsptagname_str, shape_id, name):
100-
elm = OxmlElement(nsptagname_str)
101-
elm.set('id', str(shape_id))
102-
elm.set('name', name)
103-
return elm
104-
105101

106102
class CT_NonVisualPictureProperties(BaseOxmlElement):
107103
"""
@@ -182,13 +178,6 @@ class CT_PositiveSize2D(BaseOxmlElement):
182178
cx = RequiredAttribute('cx', ST_PositiveCoordinate)
183179
cy = RequiredAttribute('cy', ST_PositiveCoordinate)
184180

185-
@classmethod
186-
def new(cls, nsptagname_str, cx, cy):
187-
elm = OxmlElement(nsptagname_str)
188-
elm.cx = cx
189-
elm.cy = cy
190-
return elm
191-
192181

193182
class CT_PresetGeometry2D(BaseOxmlElement):
194183
"""

tests/oxml/unitdata/dml.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ class CT_GraphicalObjectDataBuilder(BaseBuilder):
3737
__attrs__ = ('uri',)
3838

3939

40+
class CT_GraphicalObjectFrameLockingBuilder(BaseBuilder):
41+
__tag__ = 'a:graphicFrameLocks'
42+
__nspfxs__ = ('a',)
43+
__attrs__ = ('noChangeAspect',)
44+
45+
4046
class CT_InlineBuilder(BaseBuilder):
4147
__tag__ = 'wp:inline'
4248
__nspfxs__ = ('wp',)
@@ -52,6 +58,12 @@ def __init__(self, tag):
5258
super(CT_NonVisualDrawingPropsBuilder, self).__init__()
5359

5460

61+
class CT_NonVisualGraphicFramePropertiesBuilder(BaseBuilder):
62+
__tag__ = 'wp:cNvGraphicFramePr'
63+
__nspfxs__ = ('wp',)
64+
__attrs__ = ()
65+
66+
5567
class CT_NonVisualPicturePropertiesBuilder(BaseBuilder):
5668
__tag__ = 'pic:cNvPicPr'
5769
__nspfxs__ = ('pic',)
@@ -123,6 +135,10 @@ def a_blipFill():
123135
return CT_BlipFillPropertiesBuilder()
124136

125137

138+
def a_cNvGraphicFramePr():
139+
return CT_NonVisualGraphicFramePropertiesBuilder()
140+
141+
126142
def a_cNvPicPr():
127143
return CT_NonVisualPicturePropertiesBuilder()
128144

@@ -151,6 +167,10 @@ def a_graphicData():
151167
return CT_GraphicalObjectDataBuilder()
152168

153169

170+
def a_graphicFrameLocks():
171+
return CT_GraphicalObjectFrameLockingBuilder()
172+
173+
154174
def a_pic():
155175
return CT_PictureBuilder()
156176

tests/test_shape.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
from docx.shared import Length
1616

1717
from .oxml.unitdata.dml import (
18-
a_blip, a_blipFill, a_cNvPr, a_cNvPicPr, a_docPr, a_fillRect, a_graphic,
19-
a_graphicData, a_pic, a_prstGeom, a_stretch, an_ext, an_extent,
20-
an_inline, an_nvPicPr, an_off, an_spPr, an_xfrm
18+
a_blip, a_blipFill, a_cNvGraphicFramePr, a_cNvPr, a_cNvPicPr, a_docPr,
19+
a_fillRect, a_graphic, a_graphicData, a_graphicFrameLocks, a_pic,
20+
a_prstGeom, a_stretch, an_ext, an_extent, an_inline, an_nvPicPr, an_off,
21+
an_spPr, an_xfrm
2122
)
2223
from .oxml.unitdata.text import an_r
2324
from .unitutil import instance_mock
@@ -98,10 +99,12 @@ def new_picture_fixture(self, request, image_part_, image_params):
9899
name = 'Picture %d' % shape_id
99100
uri = nsmap['pic']
100101
expected_inline = (
101-
an_inline().with_nsdecls('r', 'wp', 'w').with_child(
102+
an_inline().with_nsdecls('wp', 'a', 'pic', 'r', 'w').with_child(
102103
an_extent().with_cx(cx).with_cy(cy)).with_child(
103104
a_docPr().with_id(shape_id).with_name(name)).with_child(
104-
a_graphic().with_nsdecls().with_child(
105+
a_cNvGraphicFramePr().with_child(
106+
a_graphicFrameLocks().with_noChangeAspect(1))).with_child(
107+
a_graphic().with_child(
105108
a_graphicData().with_uri(uri).with_child(
106109
self._pic_bldr(filename, rId, cx, cy))))
107110
).element
@@ -176,7 +179,7 @@ def _inline_with_uri(self, uri):
176179

177180
def _pic_bldr(self, name, rId, cx, cy):
178181
return (
179-
a_pic().with_nsdecls().with_child(
182+
a_pic().with_child(
180183
an_nvPicPr().with_child(
181184
a_cNvPr().with_id(0).with_name(name)).with_child(
182185
a_cNvPicPr())).with_child(

0 commit comments

Comments
 (0)