joeylib2/scripts/lib/checkDocsCode.py

46 lines
1.5 KiB
Python
Executable file

#!/usr/bin/env python3
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
#
"""checkDocsCode.py - fail when the built manual shows source code with a
character that is not ASCII.
Asciidoctor's replacements turn `->` into an arrow, `...` into an ellipsis and
a backtick next to an apostrophe into a curly quote, even inside a backtick
code span, so code the reader copies out of the manual would not compile.
Write such a span as `+text+`, which Asciidoctor leaves as it is.
Usage: scripts/lib/checkDocsCode.py MANUAL.html
Exit: 0 every code span and block is ASCII; 1 otherwise (each one listed).
"""
import html
import re
import sys
CODE = re.compile(r"<(code|pre)\b[^>]*>(.*?)</\1>", re.S)
TAG = re.compile(r"<[^>]+>")
SAMPLE_CHARS = 70
def main():
if len(sys.argv) != 2:
print(__doc__.strip().split("\n\n")[-1], file=sys.stderr)
return 2
page = open(sys.argv[1], encoding="utf-8").read()
bad = 0
for match in CODE.finditer(page):
text = html.unescape(TAG.sub("", match.group(2)))
glyphs = sorted({ch for ch in text if ord(ch) > 127})
if glyphs:
bad += 1
names = " ".join(f"U+{ord(ch):04X}" for ch in glyphs)
print(f"checkDocsCode: {names} in <{match.group(1)}>: {text[:SAMPLE_CHARS]!r}", file=sys.stderr)
if bad:
print(f"checkDocsCode: {bad} code span(s) or block(s) not ASCII; write them as `+text+`", file=sys.stderr)
return 1
return 0
sys.exit(main())