{html.escape(m.group(1))}"), text)
+ text = html.escape(text, quote=False)
+ text = LINK.sub(
+ lambda m: f'{m.group(1)}', text
+ )
+ text = BOLD.sub(r"\1", text)
+ text = EM.sub(r"\1", text)
+ for i, rendered in enumerate(slots):
+ text = text.replace(f"\x00{i}\x00", rendered)
+ return text
+
+
+def split_frontmatter(source: str) -> tuple[dict, str]:
+ if not source.startswith("---\n"):
+ return {}, source
+ end = source.index("\n---\n", 4)
+ meta = {}
+ for line in source[4:end].splitlines():
+ if ":" in line and not line.startswith((" ", "-")):
+ key, _, value = line.partition(":")
+ meta[key.strip()] = value.strip().strip('"')
+ return meta, source[end + 5 :]
+
+
+def parse_table(lines: list[str], start: int) -> tuple[list[list[str]], int]:
+ rows, i = [], start
+ while i < len(lines) and lines[i].lstrip().startswith("|"):
+ cells = [c.strip() for c in lines[i].strip().strip("|").split("|")]
+ if not all(set(c) <= set("-: ") for c in cells):
+ rows.append(cells)
+ i += 1
+ return rows, i
+
+
+# --- table renderers -------------------------------------------------------
+
+
+def render_ladder(rows: list[list[str]]) -> str:
+ """A level table becomes a stepped scale. Colour depth encodes strength."""
+ body = rows[1:]
+ plane = LEVEL_CELL.match(body[0][0]).group(1)
+ names = {
+ "I": "Identity", "A": "Authorization", "E": "Enforcement",
+ "P": "Placement", "R": "Retention",
+ }
+ rungs = []
+ for cells in body:
+ match = LEVEL_CELL.match(cells[0])
+ if not match:
+ continue
+ n = int(match.group(2))
+ text = cells[1] if len(cells) > 1 else ""
+ rungs.append(
+ f'{html.escape(chr(10).join(block))}")
+ i += 1
+ continue
+
+ if stripped.startswith(">"):
+ quote = []
+ while i < len(lines) and lines[i].strip().startswith(">"):
+ quote.append(lines[i].strip().lstrip(">").strip())
+ i += 1
+ out.append(f'{inline(" ".join(quote))}
{inline(decision.group(1))}' + f"{inline(decision.group(2))}
" + ) + else: + out.append(f"{inline(text)}
") + + close_ladders() + if open_section: + out.append("") + return "\n".join(out), rail + + +def main() -> int: + ap = argparse.ArgumentParser() + ap.add_argument("source", type=pathlib.Path) + ap.add_argument("--output", required=True, type=pathlib.Path) + ap.add_argument("--title", default=None) + ap.add_argument("--subtitle", default="") + args = ap.parse_args() + + meta, markdown = split_frontmatter(args.source.read_text()) + body, rail = render_body(markdown) + + title = args.title or meta.get("title", args.source.stem) + display = title.split(":")[0].strip() + eyebrow = " ".join( + f"{html.escape(v)}" + for k, v in ( + ("id", meta.get("id", "")), + ("status", f"{meta.get('status', '')} · {meta.get('revision', '')}".strip(" ·")), + ("date", meta.get("date", "")), + ) + if v + ) + rail_html = "".join( + f'{html.escape(args.subtitle)}
' if args.subtitle else "") + + '