1
1
import shutil
2
+ from pathlib import Path
2
3
3
4
import marko
5
+ import minify_html
4
6
from marko .block import Heading
7
+ from marko .block import Paragraph
8
+ from marko .inline import Link as MarkdownLink
5
9
from marko .md_renderer import MarkdownRenderer
6
10
from mkdocs import plugins
7
11
from mkdocs .config .defaults import MkDocsConfig
12
16
13
17
MAN_INDEXES = ["man1/index.md" , "man3/index.md" , "man5/index.md" , "man7/index.md" ]
14
18
SKIP_FILES = ["index.md" , "fips.md" ]
19
+ LINKS_MAP = {}
15
20
16
21
17
22
def get_names_paragraph (content : str ) -> str :
@@ -43,6 +48,19 @@ def on_pre_build(config: MkDocsConfig) -> None:
43
48
shutil .copytree ("scaffold" , "docs" , dirs_exist_ok = True )
44
49
45
50
51
+ def on_files (files : Files , config : MkDocsConfig ) -> Files | None :
52
+ for man_file in files .documentation_pages ():
53
+ if man_file .src_uri in SKIP_FILES + MAN_INDEXES :
54
+ continue
55
+ man_dir = Path (man_file .src_uri ).parent
56
+ names = get_names (man_file .content_string )
57
+ for name in names :
58
+ # e.g. "openssl/core_dispatch.h" to "openssl-core_dispatch.h"
59
+ name = name .strip ().replace ("/" , "-" )
60
+ LINKS_MAP [f"../../{ man_dir } /{ name } " ] = f"../{ man_dir } /{ man_file .name } .md"
61
+ return files
62
+
63
+
46
64
def populate_index_content (source_md : str , page : Page , config : MkDocsConfig , files : Files ) -> str :
47
65
if page .file .src_uri not in MAN_INDEXES :
48
66
return source_md
@@ -64,7 +82,24 @@ def populate_index_content(source_md: str, page: Page, config: MkDocsConfig, fil
64
82
return source_md + "\n " .join (sorted (rows ))
65
83
66
84
67
- def fix_headings (source_md : str , page : Page , config : MkDocsConfig , files : Files ) -> str :
85
+ def fix_links (paragraph : Paragraph ) -> Paragraph :
86
+ stack = [paragraph ]
87
+ while stack :
88
+ current_child = stack .pop ()
89
+ for child in current_child .children :
90
+ if isinstance (child , Paragraph ):
91
+ stack .append (child )
92
+ if isinstance (child , MarkdownLink ):
93
+ child .dest = LINKS_MAP .get (child .dest ) or child .dest
94
+ return paragraph
95
+
96
+
97
+ def fix_heading (heading : Heading , parser : marko .Markdown ) -> Heading :
98
+ heading_text = f"#{ parser .render (heading )} "
99
+ return parser .parse (heading_text )
100
+
101
+
102
+ def fix_markdown (source_md : str , page : Page , config : MkDocsConfig , files : Files ) -> str :
68
103
if page .file .src_uri in SKIP_FILES + MAN_INDEXES :
69
104
return source_md
70
105
parser = marko .Markdown (renderer = MarkdownRenderer )
@@ -74,12 +109,11 @@ def fix_headings(source_md: str, page: Page, config: MkDocsConfig, files: Files)
74
109
new_children .append (h1 )
75
110
parsed = parser .parse (source_md )
76
111
for child in parsed .children :
77
- if not isinstance (child , Heading ):
78
- new_children .append (child )
79
- continue
80
- heading_text = f"#{ parser .render (child )} "
81
- heading = parser .parse (heading_text )
82
- new_children .append (heading )
112
+ if isinstance (child , Paragraph ):
113
+ child = fix_links (child )
114
+ if isinstance (child , Heading ):
115
+ child = fix_heading (child , parser )
116
+ new_children .append (child )
83
117
parsed .children = new_children
84
118
return parser .render (parsed )
85
119
@@ -90,7 +124,7 @@ def fix_img_links(source_md: str, page: Page, config: MkDocsConfig, files: Files
90
124
return source_md .replace ('<img src="' , '<img src="../' )
91
125
92
126
93
- on_page_markdown = plugins .CombinedEvent (fix_headings , fix_img_links , populate_index_content )
127
+ on_page_markdown = plugins .CombinedEvent (fix_markdown , fix_img_links , populate_index_content )
94
128
95
129
96
130
def populate_nav (files : Files ) -> dict [str , list [Link ]]:
@@ -135,3 +169,15 @@ def on_nav(nav: Navigation, config: MkDocsConfig, files: Files) -> Navigation:
135
169
if item .is_page :
136
170
item .title = nav_map [item .file .name ]
137
171
return nav
172
+
173
+
174
+ def on_post_page (output : str , page : Page , config : MkDocsConfig ):
175
+ return minify_html .minify (
176
+ output ,
177
+ do_not_minify_doctype = True ,
178
+ ensure_spec_compliant_unquoted_attribute_values = True ,
179
+ keep_spaces_between_attributes = True ,
180
+ minify_css = True ,
181
+ minify_js = True ,
182
+ remove_processing_instructions = True ,
183
+ )
0 commit comments