"""Shared helpers: build a tiny Pelican site for one fixture case. Each case is a directory under tests/fixtures holding the Markdown input and the expected page. The test theme renders a Mews page skeleton that includes the plugin's mews/head.html partial. """ from __future__ import annotations from pathlib import Path import shutil from lxml import etree from pelican import Pelican from pelican.settings import read_settings TESTS = Path(__file__).parent FIXTURES = TESTS / "fixtures" THEME = TESTS / "theme" BASE_SETTINGS = { "ARTICLE_PATHS": [], # Tables and definition lists are both in the Mews subset, and both need # an extension turned on before python-markdown will emit them. "MARKDOWN": { "output_format": "xhtml", "extension_configs": { "markdown.extensions.tables": {}, "markdown.extensions.def_list": {}, }, }, "PAGE_PATHS": ["pages"], "PAGE_SAVE_AS": "{slug}.xhtml", "PAGE_URL": "{slug}.xhtml", "PLUGINS": ["pelican.plugins.mews"], "SITEURL": "", "STATIC_PATHS": [], "TIMEZONE": "UTC", } def build_case(case: str, root: Path, **override) -> Path: """Build the fixture site for one case; return its output directory.""" pages = root / "content" / "pages" pages.mkdir(parents=True) shutil.copy(FIXTURES / case / "input.md", pages / "input.md") settings = read_settings( override={ **BASE_SETTINGS, "PATH": str(root / "content"), "OUTPUT_PATH": str(root / "output"), "THEME": str(THEME), **override, } ) Pelican(settings).run() return root / "output" def normalize(data: bytes) -> str: """Canonical form of a Mews page, indifferent to whitespace.""" return etree.canonicalize(xml_data=data.decode("utf-8"), strip_text=True)