11# Translates Vim documentation to HTML
22
3- import flask
43import functools
54import html
65import re
76import urllib .parse
87
8+ import flask
9+ import markupsafe
10+
911
1012class VimProject :
1113 name = "Vim"
@@ -86,7 +88,10 @@ class NeovimProject:
8688)
8789RE_EG_START = re .compile (r"(.* )?>(?:vim|lua)?$" )
8890RE_EG_END = re .compile (r"[^ \t]" )
89- RE_SECTION = re .compile (r"(?!NOTE$|CTRL-|\.\.\.$)([A-Z.][-A-Z0-9 .,()_?]*)(?:\s+\*|$)" )
91+ RE_SECTION = re .compile (
92+ r"(?!NOTE$|UTF-8.$|VALID.$|OLE.$|CTRL-|\.\.\.$)"
93+ r"([A-Z.][-A-Z0-9 .,()_?]*?)\s*(?:\s\*|$)"
94+ )
9095RE_STARTAG = re .compile (r'\*([^ \t"*]+)\*(?:\s|$)' )
9196RE_LOCAL_ADD = re .compile (r"LOCAL ADDITIONS:\s+\*local-additions\*$" )
9297
@@ -226,11 +231,13 @@ def to_html(self, filename, contents):
226231
227232 out = []
228233 sidebar_headings = []
234+ sidebar_lvl = 2
229235 in_example = False
230236 for idx , line in enumerate (lines ):
231237 prev_line = "" if idx == 0 else lines [idx - 1 ]
232238 if prev_line == "" and idx > 1 :
233239 prev_line = lines [idx - 2 ]
240+
234241 if in_example :
235242 if RE_EG_END .match (line ):
236243 in_example = False
@@ -239,18 +246,31 @@ def to_html(self, filename, contents):
239246 else :
240247 out .extend (('<span class="e">' , html_escape (line ), "</span>\n " ))
241248 continue
249+
242250 if RE_HRULE .match (line ):
243251 out .extend (('<span class="h">' , html_escape (line ), "</span>\n " ))
244252 continue
253+
245254 if m := RE_EG_START .match (line ):
246255 in_example = True
247256 line = m .group (1 ) or ""
248- span_opened = False
257+
258+ heading = None
259+ skip_to_col = None
249260 if m := RE_SECTION .match (line ):
250- out .extend (('<span class="c">' , m .group (1 ), "</span>" ))
251- line = line [m .end (1 ) :]
261+ heading = m .group (1 )
262+ heading_lvl = 2
263+ out .extend (('<span class="c">' , heading , "</span>" ))
264+ skip_to_col = m .end (1 )
252265 elif RE_HRULE1 .match (prev_line ) and (m := RE_HEADING .match (line )):
253266 heading = m .group (1 )
267+ heading_lvl = 1
268+
269+ span_opened = False
270+ if heading is not None and sidebar_lvl >= heading_lvl :
271+ if sidebar_lvl > heading_lvl :
272+ sidebar_lvl = heading_lvl
273+ sidebar_headings = []
254274 if m := RE_STARTAG .search (line ):
255275 tag = m .group (1 )
256276 else :
@@ -259,8 +279,14 @@ def to_html(self, filename, contents):
259279 span_opened = True
260280 tag_escaped = urllib .parse .quote_plus (tag )
261281 sidebar_headings .append (
262- flask .Markup (f'<a href="#{ tag_escaped } ">{ html_escape (heading )} </a>' )
282+ markupsafe .Markup (
283+ f'<a href="#{ tag_escaped } ">{ html_escape (heading )} </a>'
284+ )
263285 )
286+
287+ if skip_to_col is not None :
288+ line = line [skip_to_col :]
289+
264290 is_faq_line = (
265291 self ._project is VimProject and is_help_txt and RE_LOCAL_ADD .match (line )
266292 )
@@ -335,7 +361,7 @@ def to_html(self, filename, contents):
335361 filename = filename ,
336362 static_dir = static_dir ,
337363 helptxt = helptxt ,
338- content = flask .Markup ("" .join (out )),
364+ content = markupsafe .Markup ("" .join (out )),
339365 sidebar_headings = sidebar_headings ,
340366 )
341367
0 commit comments