"""Pick the slide-XML schema errors PowerPoint refuses the file over. A denylist over lxml's messages, so an unrecognised error class is a miss rather than a false alarm. """ from __future__ import annotations import re SLIDE_PART_RE = re.compile( r"ppt/(slides|slideLayouts|slideMasters|notesSlides|notesMasters|handoutMasters)" r"/[^/]+\.xml" ) FATAL_SLIDE_ERRORS: tuple[tuple[re.Pattern[str], str], ...] = ( ( re.compile(r"\}tableStyleId': This element is not expected"), "two in one (the schema allows one)", ), ( re.compile(r"\}srgbClr', attribute 'val'"), "a colour that is not six hex digits", ), ( re.compile(r"\}txBody': Missing child element"), "a with no children", ), ( re.compile(r"\}miter', attribute 'lim'"), 'a line join with lim="NaN"', ), ( re.compile(r"\}uLnTx': This element is not expected"), " in a position the schema forbids", ), ( re.compile(r"\}overrideClrMapping': This element is not expected"), " in a position the schema forbids", ), ( re.compile(r"\}nvGrpSpPr': Missing child element"), "a with no children", ), ) def is_schema_verdict(error: str) -> bool: return error.startswith("Element ") def fatal_slide_errors(errors: set[str]) -> list[str]: out = [] for error in sorted(errors): for pattern, meaning in FATAL_SLIDE_ERRORS: if pattern.search(error): out.append(f"{meaning}: {error}") break return out