doc: scripts: gen_kconfig_rest: fix rendering issues

As of today we assume that the help text contained in the Kconfig help
field will be properly formatted RST. However, there is no guarantee
that this will happen. This patch tries to address this problem by:

- Escaping inline RST characters for text that needs to be rendered as
  "normal text" (i.e. prompt)
- Use code-blocks to render help content. This way help is rendered as
  literal text and so it does not get processed by the RST parser.

A secondary change: the index table now contains the prompt information
only. The page was taking a long time to render because of the large
amount of content. Using a table doesn't help either. Note that adding
code-block to include help as a literal increases build time even more,
so it is not an option.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2021-05-20 12:32:51 +02:00 committed by Kumar Gala
commit 381180c46f

View file

@ -16,6 +16,7 @@ import collections
from operator import attrgetter from operator import attrgetter
import os import os
import pathlib import pathlib
import re
import sys import sys
import textwrap import textwrap
@ -35,6 +36,10 @@ NO_MAX_WIDTH = """
""" """
def escape_inline_rst(text):
# Escape reStructuredText inline markup characters
return re.sub(r"(\*|_|`)", r"\\\1", text)
def rst_link(sc): def rst_link(sc):
# Returns an RST link (string) for the symbol/choice 'sc', or the normal # Returns an RST link (string) for the symbol/choice 'sc', or the normal
# Kconfig expression format (e.g. just the name) for 'sc' if it can't be # Kconfig expression format (e.g. just the name) for 'sc' if it can't be
@ -394,7 +399,7 @@ def sym_table_rst(title, syms):
:widths: auto :widths: auto
* - Symbol name * - Symbol name
- Help/prompt - Prompt
""" """
for sym in sorted(syms, key=attrgetter("name")): for sym in sorted(syms, key=attrgetter("name")):
@ -409,15 +414,9 @@ def sym_table_rst(title, syms):
def sym_index_desc(sym): def sym_index_desc(sym):
# Returns the description used for 'sym' on the index page # Returns the description used for 'sym' on the index page
# Use the first help text, if available
for node in sym.nodes:
if node.help is not None:
return node.help.replace("\n", "\n ")
# If there's no help, use the first prompt string
for node in sym.nodes: for node in sym.nodes:
if node.prompt: if node.prompt:
return node.prompt[0] return escape_inline_rst(node.prompt[0])
# No help text or prompt # No help text or prompt
return "" return ""
@ -547,7 +546,7 @@ def choice_header_rst(choice):
def prompt_rst(sc): def prompt_rst(sc):
# Returns RST that lists the prompts of 'sc' (symbol or choice) # Returns RST that lists the prompts of 'sc' (symbol or choice)
return "\n\n".join(f"*{node.prompt[0]}*" return "\n\n".join(f"*{escape_inline_rst(node.prompt[0])}*"
for node in sc.nodes if node.prompt) \ for node in sc.nodes if node.prompt) \
or "*(No prompt -- not directly user assignable.)*" or "*(No prompt -- not directly user assignable.)*"
@ -563,7 +562,8 @@ def help_rst(sc):
if node.help is not None: if node.help is not None:
rst += "Help\n" \ rst += "Help\n" \
"====\n\n" \ "====\n\n" \
f"{node.help}\n\n" ".. code-block:: none\n\n" \
f"{textwrap.indent(node.help, 4 * ' ')}\n\n"
return rst return rst
@ -736,15 +736,13 @@ def kconfig_definition_rst(sc):
if len(sc.nodes) > 1: heading += "s" if len(sc.nodes) > 1: heading += "s"
rst = f"{heading}\n{len(heading)*'='}\n\n" rst = f"{heading}\n{len(heading)*'='}\n\n"
rst += ".. highlight:: kconfig"
for node in sc.nodes: for node in sc.nodes:
rst += "\n\n" \ rst += "\n\n" \
f"At ``{strip_module_path(node.filename)}:{node.linenr}``\n\n" \ f"At ``{strip_module_path(node.filename)}:{node.linenr}``\n\n" \
f"{include_path(node)}" \ f"{include_path(node)}" \
f"Menu path: {menu_path(node)}\n\n" \ f"Menu path: {menu_path(node)}\n\n" \
".. parsed-literal::\n\n" \ ".. code-block:: kconfig\n\n" \
f"{textwrap.indent(node.custom_str(rst_link), 4*' ')}" f"{textwrap.indent(str(node), 4*' ')}"
# Not the last node? # Not the last node?
if node is not sc.nodes[-1]: if node is not sc.nodes[-1]: