doc: Introduce pre-processor for adding anchors to text

It is now possible to use the following syntax to insert anchors into the text:

    []{#anchor-name}

The anchor will allow linking to the location it is placed by appending #anchor-name to the URL.

Additionally, it is possible to create a link pointing to its own location by adding text between the square brackets:

    [`--add-root`]{#opt-add-root}
This commit is contained in:
Jan Tojnar 2022-05-25 18:51:04 +02:00
parent 4f98bc29ff
commit 4de84e095d
3 changed files with 60 additions and 1 deletions

56
doc/manual/anchors.py Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env python3
import argparse
import json
import re
import sys
empty_anchor_regex = re.compile(r"\[\]\{#(?P<anchor>[^\}]+?)\}")
anchor_regex = re.compile(r"\[(?P<text>[^\]]+?)\]\{#(?P<anchor>[^\}]+?)\}")
def transform_anchors_html(content):
content = empty_anchor_regex.sub(r'<a name="\g<anchor>"></a>', content)
content = anchor_regex.sub(r'<a href="#\g<anchor>" id="\g<anchor>">\g<text></a>', content)
return content
def transform_anchors_strip(content):
content = empty_anchor_regex.sub(r'', content)
content = anchor_regex.sub(r'\g<text>', content)
return content
def map_contents_recursively(transformer, chapter):
chapter["Chapter"]["content"] = transformer(chapter["Chapter"]["content"])
for sub_item in chapter["Chapter"]["sub_items"]:
map_contents_recursively(transformer, sub_item)
def supports_command(args):
sys.exit(0)
def process_command(args):
context, book = json.load(sys.stdin)
transformer = transform_anchors_html if context["renderer"] == "html" else transform_anchors_strip
for section in book["sections"]:
map_contents_recursively(transformer, section)
print(json.dumps(book))
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="mdBook preprocessor adding anchors."
)
parser.set_defaults(command=process_command)
subparsers = parser.add_subparsers()
supports_parser = subparsers.add_parser("supports", help="Check if given renderer is supported")
supports_parser.add_argument("renderer", type=str)
supports_parser.set_defaults(command=supports_command)
args = parser.parse_args()
args.command(args)

View file

@ -1,2 +1,5 @@
[output.html] [output.html]
additional-css = ["custom.css"] additional-css = ["custom.css"]
[preprocessor.anchors]
command = "python3 doc/manual/anchors.py"

View file

@ -97,7 +97,7 @@ doc/manual/generated/man1/nix3-manpages: $(d)/src/command-ref/new-cli
done done
@touch $@ @touch $@
$(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/command-ref/new-cli $(d)/src/command-ref/conf-file.md $(d)/src/expressions/builtins.md $(call rwildcard, $(d)/src, *.md) $(docdir)/manual/index.html: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.py $(d)/custom.css $(d)/src/SUMMARY.md $(d)/src/command-ref/new-cli $(d)/src/command-ref/conf-file.md $(d)/src/expressions/builtins.md $(call rwildcard, $(d)/src, *.md)
$(trace-gen) RUST_LOG=warn mdbook build doc/manual -d $(DESTDIR)$(docdir)/manual $(trace-gen) RUST_LOG=warn mdbook build doc/manual -d $(DESTDIR)$(docdir)/manual
endif endif