round-4 bisection: no-validate / shared-hf-parts / mini-28fields probes
This commit is contained in:
@@ -16,6 +16,10 @@ feature family:
|
||||
05 first8 - body truncated after the 8th section boundary
|
||||
06 no_images - drawing paragraphs removed
|
||||
|
||||
19 no_validate - +w:doNotValidateAgainstSchema in settings.xml
|
||||
20 shared_hf_parts - every section points at section 1's 6 header/footer parts
|
||||
21 mini_28fields - the MINI book with the TOC entry replicated to 28 fields
|
||||
|
||||
Open each in Word; whichever show the error dialog pinpoint the feature
|
||||
family at fault.
|
||||
"""
|
||||
@@ -54,6 +58,9 @@ NAMES = [
|
||||
'bisect_16_no_titles.docx',
|
||||
'bisect_17_page_fields.docx',
|
||||
'bisect_18_no_dirty.docx',
|
||||
'bisect_19_no_validate.docx',
|
||||
'bisect_20_shared_hf_parts.docx',
|
||||
'bisect_21_mini_28fields.docx',
|
||||
]
|
||||
|
||||
|
||||
@@ -285,6 +292,72 @@ def make_no_dirty(doc):
|
||||
rpr.remove(d)
|
||||
|
||||
|
||||
def make_no_validate(doc):
|
||||
"""Add <w:doNotValidateAgainstSchema/> to settings: Word skips schema
|
||||
validation on open. If the full book then opens, the failure is a
|
||||
schema-level violation hit during the dirty-field update/repagination
|
||||
pass, not a content issue."""
|
||||
settings = doc.settings.element
|
||||
el = etree.Element(qn('w:doNotValidateAgainstSchema'))
|
||||
# canonical CT_Settings order: ... savePreviewPicture,
|
||||
# doNotValidateAgainstSchema, saveInvalidXml, ... compat, rsids, mathPr
|
||||
anchor = None
|
||||
for tag in ('w:compat', 'w:rsids', 'w:mathPr'):
|
||||
anchor = settings.find(qn(tag))
|
||||
if anchor is not None:
|
||||
break
|
||||
if anchor is not None:
|
||||
anchor.addprevious(el)
|
||||
else:
|
||||
settings.append(el)
|
||||
|
||||
|
||||
def make_shared_hf_parts(doc):
|
||||
"""Point every section at the first section's 6 header/footer parts, so
|
||||
the 216 part *package* collapses to 6 referenced parts while keeping the
|
||||
36-section body structure and dirty fields."""
|
||||
first = None
|
||||
for sectPr in doc.element.body.iter(qn('w:sectPr')):
|
||||
if sectPr.getparent().tag == qn('w:pPr'):
|
||||
first = sectPr
|
||||
break
|
||||
if first is None:
|
||||
return
|
||||
mapping = {}
|
||||
for ref in first:
|
||||
if ref.tag in (qn('w:headerReference'), qn('w:footerReference')):
|
||||
mapping[(ref.tag, ref.get(qn('w:type')))] = ref.get(qn('r:id'))
|
||||
for sectPr in doc.element.body.iter(qn('w:sectPr')):
|
||||
if sectPr is first:
|
||||
continue
|
||||
for ref in list(sectPr):
|
||||
if ref.tag in (qn('w:headerReference'), qn('w:footerReference')):
|
||||
key = (ref.tag, ref.get(qn('w:type')))
|
||||
if key in mapping:
|
||||
ref.set(qn('r:id'), mapping[key])
|
||||
|
||||
|
||||
def make_mini_28fields(doc):
|
||||
"""Return a copy of the MINI book (which opens in Word with 3 dirty
|
||||
PAGEREF fields) with the first TOC entry paragraph replicated 25 more
|
||||
times -> 28 dirty fields in the mini shell. Tests pure field density:
|
||||
if this fails while the 3-field mini opens, the trigger is field count
|
||||
interacting with something, not the full shell."""
|
||||
mini = Document(os.path.join(HERE, 'word_test_output.docx'))
|
||||
body = mini.element.body
|
||||
first_entry = None
|
||||
for p in body.iter(qn('w:p')):
|
||||
if p.find(".//" + qn('w:instrText')) is not None:
|
||||
first_entry = p
|
||||
break
|
||||
if first_entry is None:
|
||||
return mini
|
||||
idx = list(body).index(first_entry)
|
||||
for k in range(25):
|
||||
body.insert(idx + 1 + k, deepcopy(first_entry))
|
||||
return mini
|
||||
|
||||
|
||||
MAKERS = [
|
||||
make_no_running,
|
||||
make_no_oddpage,
|
||||
@@ -304,6 +377,9 @@ MAKERS = [
|
||||
make_no_titles,
|
||||
make_page_fields,
|
||||
make_no_dirty,
|
||||
make_no_validate,
|
||||
make_shared_hf_parts,
|
||||
make_mini_28fields,
|
||||
]
|
||||
|
||||
|
||||
@@ -314,7 +390,7 @@ def main():
|
||||
"Regenerate it via the API first, or pass its path as argv[1].")
|
||||
for maker, name in zip(MAKERS, NAMES):
|
||||
doc = Document(base)
|
||||
maker(doc)
|
||||
doc = maker(doc) or doc
|
||||
path = _save(doc, name)
|
||||
# sanity: it must still open via python-docx
|
||||
Document(path)
|
||||
|
||||
Reference in New Issue
Block a user