#!/usr/bin/env python """Check mews-0.1.dtd against the XHTML Mobile 1.2 driver and the spec. The Mews DTD is maintained by hand. It cannot be generated by stripping xhtml-mobile12.dtd: that file is a driver which declares no elements (the declarations live in the W3C and OMA module files it points to), DTD attribute lists only ever add, a re-declared element is an error rather than an override, and the rules that define Mews (the head model of SPEC.md 3.3, the body variant classes of 5.3, the ban on nested tables of 4.2, and lang and dir) do not exist in XHTML-MP to be kept. This script verifies what the driver and the spec can check: - the driver is the expected XHTML Mobile 1.2 driver, with event attributes included and bidi ignored, so lang and dir are Mews extensions (SPEC.md 3); - the DTD declares exactly the elements SPEC.md 4.1 permits; - the DTD keeps the driver's pre content model verbatim; - the DTD keeps the li value and ol start attributes the driver adds. Run with: uv run check_dtd.py """ import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parent DRIVER_PATH = ROOT / "xhtml-mobile12.dtd" DTD_PATH = ROOT / "mews-0.1.dtd" DRIVER_FPI = "-//OMA//DTD XHTML Mobile 1.2//EN" # The Mews element set (SPEC.md 4.1). KEPT_ELEMENTS = ( "html head title body " "h1 h2 h3 h4 h5 h6 " "p blockquote pre address hr " "em strong b i code kbd samp var q cite abbr dfn br " "a " "ul ol li dl dt dd " "table caption tr th td " "img " "form fieldset label input select option optgroup textarea " "meta link" ).split() def entity(text, name): match = re.search(r"', text, re.DOTALL) return re.sub(r"\s+", " ", match.group(1)) if match else None def attlist(text, element): match = re.search(r"", text, re.DOTALL) return match.group(1) if match else None def main(): driver = DRIVER_PATH.read_text(encoding="utf-8") dtd = DTD_PATH.read_text(encoding="utf-8") errors = [] def check(condition, message): if not condition: errors.append(message) check(entity(driver, "XHTML.version") == DRIVER_FPI, "driver is not XHTML Mobile 1.2") check( entity(driver, "xhtml-events.module") == "INCLUDE", "driver must include event attributes; Mews drops them", ) check( entity(driver, "XHTML.bidi") == "IGNORE", "driver must ignore bidi, so dir is a Mews extension", ) declared = set(re.findall(r"