11# Translates Vim documentation to HTML
22
33from datetime import datetime
4- import flask
54import functools
65import html
76import json
87import re
98import urllib .parse
109
10+ import flask
11+ import markupsafe
12+
1113
1214class MacVimProject :
1315 name = "MacVim"
@@ -98,7 +100,10 @@ class NeovimProject:
98100)
99101RE_EG_START = re .compile (r"(.* )?>(?:vim|lua)?$" )
100102RE_EG_END = re .compile (r"[^ \t]" )
101- RE_SECTION = re .compile (r"(?!NOTE$|CTRL-|\.\.\.$)([A-Z.][-A-Z0-9 .,()_?]*)(?:\s+\*|$)" )
103+ RE_SECTION = re .compile (
104+ r"(?!NOTE$|UTF-8.$|VALID.$|OLE.$|CTRL-|\.\.\.$)"
105+ r"([A-Z.][-A-Z0-9 .,()_?]*?)\s*(?:\s\*|$)"
106+ )
102107RE_STARTAG = re .compile (r'\*([^ \t"*]+)\*(?:\s|$)' )
103108RE_LOCAL_ADD = re .compile (r"LOCAL ADDITIONS:\s+\*local-additions\*$" )
104109
@@ -275,11 +280,13 @@ def to_html(self, filename, contents):
275280
276281 out = []
277282 sidebar_headings = []
283+ sidebar_lvl = 2
278284 in_example = False
279285 for idx , line in enumerate (lines ):
280286 prev_line = "" if idx == 0 else lines [idx - 1 ]
281287 if prev_line == "" and idx > 1 :
282288 prev_line = lines [idx - 2 ]
289+
283290 if in_example :
284291 if RE_EG_END .match (line ):
285292 in_example = False
@@ -288,18 +295,31 @@ def to_html(self, filename, contents):
288295 else :
289296 out .extend (('<span class="e">' , html_escape (line ), "</span>\n " ))
290297 continue
298+
291299 if RE_HRULE .match (line ):
292300 out .extend (('<span class="h">' , html_escape (line ), "</span>\n " ))
293301 continue
302+
294303 if m := RE_EG_START .match (line ):
295304 in_example = True
296305 line = m .group (1 ) or ""
297- span_opened = False
306+
307+ heading = None
308+ skip_to_col = None
298309 if m := RE_SECTION .match (line ):
299- out .extend (('<span class="c">' , m .group (1 ), "</span>" ))
300- line = line [m .end (1 ) :]
310+ heading = m .group (1 )
311+ heading_lvl = 2
312+ out .extend (('<span class="c">' , heading , "</span>" ))
313+ skip_to_col = m .end (1 )
301314 elif RE_HRULE1 .match (prev_line ) and (m := RE_HEADING .match (line )):
302315 heading = m .group (1 )
316+ heading_lvl = 1
317+
318+ span_opened = False
319+ if heading is not None and sidebar_lvl >= heading_lvl :
320+ if sidebar_lvl > heading_lvl :
321+ sidebar_lvl = heading_lvl
322+ sidebar_headings = []
303323 if m := RE_STARTAG .search (line ):
304324 tag = m .group (1 )
305325 else :
@@ -308,8 +328,14 @@ def to_html(self, filename, contents):
308328 span_opened = True
309329 tag_escaped = urllib .parse .quote_plus (tag )
310330 sidebar_headings .append (
311- flask .Markup (f'<a href="#{ tag_escaped } ">{ html_escape (heading )} </a>' )
331+ markupsafe .Markup (
332+ f'<a href="#{ tag_escaped } ">{ html_escape (heading )} </a>'
333+ )
312334 )
335+
336+ if skip_to_col is not None :
337+ line = line [skip_to_col :]
338+
313339 is_faq_line = (
314340 self ._project is VimProject and is_help_txt and RE_LOCAL_ADD .match (line )
315341 )
@@ -392,7 +418,7 @@ def to_html(self, filename, contents):
392418 filename = filename ,
393419 static_dir = static_dir ,
394420 helptxt = helptxt ,
395- content = flask .Markup ("" .join (out )),
421+ content = markupsafe .Markup ("" .join (out )),
396422 sidebar_headings = sidebar_headings ,
397423 current_time = current_time ,
398424 commit = self ._commit ,
0 commit comments