46 lines
1.5 KiB
Python
Executable file
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())
|