Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
expected_paragraphs = [u'Custom Doc Properties',
u'Text: Foo Bar',
u'Number: 123',
u'Boolean: Y',
u'Date: 11.06.2019',
u'Float: 1.1']
actual_paragraphs = [paragraph.text for paragraph in document.paragraphs]
assert actual_paragraphs == expected_paragraphs
CustomProperties(document).dissolve_fields("Number Property")
actual_paragraphs = [paragraph.text for paragraph in document.paragraphs]
assert actual_paragraphs == expected_paragraphs
properties = xpath(document.element.body, './/w:instrText')
assert 4 == len(properties),\
'only 4 fields should remain after removal of one'
def test_removes_simple_field_but_keeps_value(self):
document = Document(docx_path('outdated_docproperty_with_umlauts.docx'))
assert 1 == len(document.paragraphs), 'input file should contain 1 paragraph'
fields = xpath(
document.element.body,
simple_field_expression(u"F\xfc\xfc"))
assert 1 == len(fields), 'should contain one simple field docproperty'
assert u'Hie chund ds property: ' == document.paragraphs[0].text
assert u'xxx' == fields[0].text
CustomProperties(document).dissolve_fields(u"F\xfc\xfc")
fields = xpath(
document.element.body,
simple_field_expression(u"F\xfc\xfc"))
assert 0 == len(fields), 'should not contain any docproperties anymore'
# when simple field is removed, the value is moved one up in the hierarchy
assert u'Hie chund ds property: xxx' == document.paragraphs[0].text
def test_abstractnums_from_styles_are_not_duplicated(multiple_numberings):
anums = xpath(
multiple_numberings.doc.part.numbering_part.element,
'.//w:abstractNum[.//w:pStyle]')
assert len(anums) == 2
def add(self, name, value):
"""Add a property."""
pids = [int(pid) for pid in xpath(self._element, u'.//cp:property/@pid')]
if pids:
pid = max(pids) + 1
else:
pid = MIN_PID
prop = parse_xml(''.format(NS['cp']))
prop.set('fmtid', CUSTOM_PROPERTY_FMTID)
prop.set('name', name)
prop.set('pid', text_type(pid))
value_el = value2vt(value)
prop.append(value_el)
self._element.append(prop)
self._update_part()
def restart_first_numbering(self, doc, element):
if not self.restart_numbering:
return
style_id = xpath(element, './/w:pStyle/@w:val')
if not style_id:
return
style_id = self.mapped_style_id(style_id[0])
if style_id in self._numbering_restarted:
return
style_element = self.doc.styles.element.get_by_id(style_id)
if style_element is None:
return
outline_lvl = xpath(style_element, './/w:outlineLvl')
if outline_lvl:
# Styles with an outline level are probably headings.
# Do not restart numbering of headings
return
# if there is a numId referenced from the paragraph, that numId is
# relevant, otherwise fall back to the style's numId
local_num_id = xpath(element, './/w:numPr/w:numId/@w:val')
if local_num_id:
num_id = local_num_id[0]
else:
style_num_id = xpath(style_element, './/w:numId/@w:val')
if not style_num_id:
return
num_id = style_num_id[0]
def __delitem__(self, key):
"""Delete a property."""
props = xpath(
self._element,
u'.//cp:property[@name="{}"]'.format(key))
if not props:
raise KeyError(key)
props[0].getparent().remove(props[0])
# Renumber pids
pid = MIN_PID
for prop in self._element:
prop.set('pid', text_type(pid))
pid += 1
self._update_part()
def get_separate_run(self):
"""The ooxml format standard says that the separate node is optional,
so we check whether we find one in our complex field, otherwise
we return None."""
separates = xpath(self.w_r, self.XPATH_FOLLOWING_SEPARATES)
if not separates:
return None
separate = separates[0]
if not self.w_p.index(separate) < self.w_p.index(self.end_run):
return None
return separate
def nullify(self, key):
"""Delete key for non text-properties, set key to empty string for
text.
"""
props = xpath(
self._element,
u'.//cp:property[@name="{}"]'.format(key))
if not props:
raise KeyError(key)
if is_text_property(props[0][0]):
self[key] = ''
else:
del self[key]
def __getitem__(self, key):
"""Get the value of a property."""
props = xpath(
self._element,
u'.//cp:property[@name="{}"]'.format(key))
if not props:
raise KeyError(key)
return vt2value(props[0][0])
self.doc.styles.element.append(deepcopy(
our_linked_style))
else:
# Create a mapping for abstractNumIds used in existing styles
# This is used when adding numberings to avoid having multiple
# elements for the same style.
style_element = doc.styles.element.get_by_id(style_id)
if style_element is not None:
num_ids = xpath(style_element, './/w:numId/@w:val')
if num_ids:
anum_ids = xpath(
doc.part.numbering_part.element,
'.//w:num[@w:numId="%s"]/w:abstractNumId/@w:val' % num_ids[0])
if anum_ids:
our_style_element = self.doc.styles.element.get_by_id(our_style_id)
our_num_ids = xpath(our_style_element, './/w:numId/@w:val')
if our_num_ids:
numbering_part = self.numbering_part()
our_anum_ids = xpath(
numbering_part.element,
'.//w:num[@w:numId="%s"]/w:abstractNumId/@w:val' % our_num_ids[0])
if our_anum_ids:
self.anum_id_mapping[int(anum_ids[0])] = int(our_anum_ids[0])
# Replace language-specific style id with our style id
if our_style_id != style_id and our_style_id is not None:
style_elements = xpath(
element,
'.//w:tblStyle[@w:val="%(styleid)s"]|'
'.//w:pStyle[@w:val="%(styleid)s"]|'
'.//w:rStyle[@w:val="%(styleid)s"]' % dict(styleid=style_id))
for el in style_elements: