Skip to content

Commit 3205b8a

Browse files
committed
kernel-doc: Don't mangle literal code blocks in comments
The origin patch comes from Jonathan Corbet [1] patching kernel-doc (perl) parser of the Linux tree. [1] https://www.mail-archive.com/linux-doc@vger.kernel.org/msg18046.html -- It can be useful to put code snippets into kerneldoc comments; that can be done with the "::" operator at the end of a line like this:: if (desperate) run_in_circles(); kernel-doc currently fails to understand these literal blocks and applies its normal markup to them, which is then treated as literal by sphinx. The result is unsightly markup instead of a useful code snippet. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
1 parent dd4cb89 commit 3205b8a

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

docs/linuxdoc-howto/all-in-a-tumble.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ typedef int my_typedef;
286286
* +-+----+ | | +----+-+
287287
* \| \| |/ |/
288288
* +------+ +------+
289-
*
289+
* foo() bar()
290+
*
290291
* Highlighted code blocks:
291292
* The next example shows a code block, with highlighting C syntax in the
292293
* output.
@@ -295,7 +296,7 @@ typedef int my_typedef;
295296
*
296297
* // Hello World program
297298
* #include<stdio.h>
298-
* int main\()
299+
* int main()
299300
* {
300301
* printf("Hello World");
301302
* }

linuxdoc/kernel_doc.py

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def __getitem__(self, group):
105105
if group < 0 or group > self.groups - 1:
106106
raise IndexError("group index out of range (max %s groups)" % self.groups )
107107
if self.last_match is None:
108-
raise IndexError("nothing hase matched / no groups")
108+
raise IndexError("nothing has matched / no groups")
109109
return self.last_match.group(group + 1)
110110

111111
# these regular expresions has been *stolen* from the kernel-doc perl script.
@@ -249,11 +249,67 @@ def normalize_id(ID):
249249
u"""substitude invalid chars of the ID with ``-`` and mak it lowercase"""
250250
return ID_CHARS.sub("-", ID).lower()
251251

252-
def map_text(text, map_table):
252+
253+
RST_DIRECTIVE_PATTERN = r"""
254+
\.\.[ ]+ # explicit markup start
255+
(%s) # directive name
256+
[ ]? # optional space
257+
:: # directive delimiter
258+
([ ]+|$) # whitespace or end of line
259+
"""
260+
261+
RST_CODE_BLOCK = RE(RST_DIRECTIVE_PATTERN % 'code-block', re.VERBOSE | re.UNICODE)
262+
RST_LITERAL_BLOCK = RE(r'(?<!\\)(\\\\)*::$')
263+
RST_INDENT = RE(r"^(\s*)[^\s]")
264+
265+
def map_row(row, map_table):
253266
for regexpr, substitute in map_table:
254267
if substitute is not None:
255-
text = regexpr.sub(substitute, text)
256-
return text
268+
row = regexpr.sub(substitute, row)
269+
return row
270+
271+
def highlight_parser(text, map_table):
272+
# FIXME: document this
273+
block_indent = 0
274+
row_indent = 0
275+
state = 'highlight' # [highlight|literal]
276+
out = []
277+
in_rows = text.splitlines()
278+
279+
while in_rows:
280+
row = in_rows.pop(0)
281+
282+
if not row.strip(): # pass-through empty lines & continue
283+
out.append(row)
284+
continue
285+
286+
RST_INDENT.search(row)
287+
indent = len(RST_INDENT[0].expandtabs())
288+
289+
if state == 'highlight':
290+
out.append(map_row(row, map_table))
291+
# prepare next state
292+
if (RST_LITERAL_BLOCK.search(row) or RST_CODE_BLOCK.search(row)):
293+
state = 'literal'
294+
block_indent = row_indent + 1
295+
continue
296+
297+
if state == 'literal':
298+
if indent < block_indent:
299+
# this is a new block, push row back onto the stack and repeat
300+
# the loop
301+
state = 'highlight'
302+
block_indent = indent
303+
in_rows.insert(0, row)
304+
continue
305+
else:
306+
out.append(row)
307+
308+
return "\n".join(out)
309+
310+
311+
312+
257313

258314
# ==============================================================================
259315
# helper
@@ -536,7 +592,7 @@ def setOptions(self, options):
536592
def highlight(self, cont):
537593
u"""returns *highlighted* text"""
538594
if self.options.highlight:
539-
return map_text(cont, self.HIGHLIGHT_MAP)
595+
return highlight_parser(cont, self.HIGHLIGHT_MAP)
540596
return cont
541597

542598
def get_preamble(self):
@@ -801,9 +857,9 @@ class ReSTTranslator(TranslatorAPI):
801857

802858
def highlight(self, text):
803859
if self.options.markup == "kernel-doc":
804-
text = map_text(text, self.MASK_REST_INLINES + self.HIGHLIGHT_MAP )
860+
text = highlight_parser(text, self.MASK_REST_INLINES + self.HIGHLIGHT_MAP )
805861
elif self.options.markup == "reST":
806-
text = map_text(text, self.HIGHLIGHT_MAP )
862+
text = highlight_parser(text, self.HIGHLIGHT_MAP )
807863
return text
808864

809865
def format_block(self, content):

0 commit comments

Comments
 (0)