mirror of
https://github.com/eyre-rs/eyre.git
synced 2025-10-03 15:56:37 +00:00

* Use `<span>` instead of `<font>` in documentation The `<font>` tag was deprecated in [HTML 4.01]. Let's use the verbose but standardized `<span>` tag with discouraged but supported inline styles instead. (I was wrong when I said it was deprecated before I was born; though [HTML 4]'s spec was published in 1997, about 6 months before I was born, `<font>` was only deprecated in HTML 4.01, published 2 years later when I was about 16 months old.) [HTML 4]: https://www.w3.org/TR/REC-html40-971218/ [HTML 4.01]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/font * Add script to convert `<span>` to `<font>` in docs ``` $ ./scripts/fix_html_examples.py --help usage: fix_html_examples.py [-h] file [file ...] Convert HTML from Gnome terminal's 'Copy as HTML' feature to use modern <span> tags and inline CSS. This script is idempotent, i.e. multiple invocations will not change the output past the first invocation. positional arguments: file Rust file to update <pre> blocks in. optional arguments: -h, --help show this help message and exit $ ./scripts/fix_html_examples.py src/*.rs Nothing to fix in src/config.rs Nothing to fix in src/handler.rs Updated example colored output in src/lib.rs Nothing to fix in src/private.rs Nothing to fix in src/writers.rs $ ./scripts/fix_html_examples.py src/*.rs Nothing to fix in src/config.rs Nothing to fix in src/handler.rs Nothing to fix in src/lib.rs Nothing to fix in src/private.rs Nothing to fix in src/writers.rs ``` Co-authored-by: Rebecca Turner <rturner@linkedin.com>
127 lines
3.7 KiB
Python
Executable File
127 lines
3.7 KiB
Python
Executable File
#! /usr/bin/env python3.8
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from argparse import FileType, ArgumentParser
|
|
import enum
|
|
import sys
|
|
|
|
from bs4 import BeautifulSoup, Tag
|
|
|
|
|
|
class LineType(enum.Enum):
|
|
OUTER_DOC = enum.auto()
|
|
INNER_DOC = enum.auto()
|
|
SOURCE = enum.auto()
|
|
|
|
@classmethod
|
|
def from_line(cls, line: str) -> (LineType, str):
|
|
if line.startswith("//!"):
|
|
return (cls.OUTER_DOC, line[len("//!") :])
|
|
elif line.startswith("///"):
|
|
return (cls.INNER_DOC, line[len("///") :])
|
|
else:
|
|
return (cls.SOURCE, line)
|
|
|
|
def prefix(self) -> str:
|
|
if self == LineType.OUTER_DOC:
|
|
return "//!"
|
|
elif self == LineType.INNER_DOC:
|
|
return "///"
|
|
else:
|
|
return ""
|
|
|
|
|
|
def fix_gnome_html(fh: file) -> str:
|
|
"""Tweaks for fixing "Copy as HTML" output from gnome-terminal
|
|
|
|
Reads source from a Rust file.
|
|
"""
|
|
|
|
anything_changed = False
|
|
line_type = LineType.SOURCE
|
|
|
|
# Lines of current HTML <pre> chunk
|
|
pre_chunk = []
|
|
# Lines of processed file
|
|
ret = []
|
|
|
|
for (line_type, stripped_line), line in map(
|
|
lambda line: (LineType.from_line(line), line), fh.readlines()
|
|
):
|
|
if line_type == LineType.SOURCE:
|
|
ret.append(line)
|
|
elif stripped_line.lstrip().startswith("<pre"):
|
|
pre_chunk = [stripped_line]
|
|
elif stripped_line.rstrip().endswith("</pre>"):
|
|
pre_chunk.append(stripped_line)
|
|
if any("<font" in line for line in pre_chunk):
|
|
joined_chunk = "".join(pre_chunk)
|
|
fixed_chunk = fix_pre(joined_chunk, prefix=line_type.prefix())
|
|
anything_changed = joined_chunk != fixed_chunk
|
|
ret.append(fixed_chunk)
|
|
pre_chunk = []
|
|
else:
|
|
prefix = line_type.prefix()
|
|
ret.extend(line_type.prefix() + line for line in pre_chunk)
|
|
elif pre_chunk:
|
|
pre_chunk.append(stripped_line)
|
|
else:
|
|
ret.append(line)
|
|
|
|
return "".join(ret) if anything_changed else None
|
|
|
|
|
|
def fix_pre(html: str, prefix: str = "") -> str:
|
|
"""Fixes an individual <pre> tag from Gnome.
|
|
|
|
Optionally prepends a given prefix to each line in the returned output.
|
|
"""
|
|
soup = BeautifulSoup(html, "html.parser")
|
|
|
|
for pre in soup.find_all("pre"):
|
|
for tag in pre.find_all("font"):
|
|
# <font color=xxx> -> <span style="color: xxx">
|
|
tag.name = "span"
|
|
color = tag.attrs.pop("color")
|
|
tag["style"] = f"color: {color}"
|
|
|
|
return "".join(prefix + line for line in str(soup).splitlines(keepends=True))
|
|
|
|
|
|
def main():
|
|
parser = ArgumentParser(
|
|
description="""Convert HTML from Gnome terminal's 'Copy as HTML' feature
|
|
to use modern <span> tags and inline CSS.
|
|
|
|
This script is idempotent, i.e. multiple invocations will not change
|
|
the output past the first invocation."""
|
|
)
|
|
parser.add_argument(
|
|
"file",
|
|
nargs="+",
|
|
type=FileType("r+", encoding="utf-8"),
|
|
help="""Rust file to update <pre> blocks in.""",
|
|
)
|
|
args = parser.parse_args()
|
|
for fh in args.file:
|
|
if not fh.name.endswith(".rs"):
|
|
print(
|
|
"This script only fixes Rust source files; you probably didn't mean to include",
|
|
fh.name,
|
|
"so I'll skip processing it.",
|
|
)
|
|
new_content = fix_gnome_html(fh)
|
|
if new_content is not None:
|
|
print("Updated example colored output in", fh.name)
|
|
fh.seek(0)
|
|
fh.write(new_content)
|
|
else:
|
|
print("Nothing to fix in", fh.name)
|
|
fh.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|