]> granicus.if.org Git - esp-idf/commitdiff
doc: Use confgen.py to build docs from same code path as config generation
authorAngus Gratton <angus@espressif.com>
Tue, 20 Mar 2018 05:31:53 +0000 (16:31 +1100)
committerAngus Gratton <gus@projectgus.com>
Sun, 29 Apr 2018 23:59:20 +0000 (09:59 +1000)
docs/conf_common.py
docs/gen-kconfig-doc.py [deleted file]
tools/kconfig_new/gen_kconfig_doc.py

index e5dd9df6e060ae240e08d0ce88075383f82474e8..16efc9d3c41306a16a878d832069cc678ff59a5f 100644 (file)
@@ -16,7 +16,7 @@
 
 import sys, os
 import re
-from subprocess import Popen, PIPE
+import subprocess
 import shlex
 
 # Note: If extensions (or modules to document with autodoc) are in another directory,
@@ -41,9 +41,21 @@ copy_if_modified('xml/', 'xml_in/')
 os.system('python ../gen-dxd.py')
 
 # Generate 'kconfig.inc' file from components' Kconfig files
+print "Generating kconfig.inc from kconfig contents"
 kconfig_inc_path = '{}/inc/kconfig.inc'.format(builddir)
-os.system('python ../gen-kconfig-doc.py > ' + kconfig_inc_path + '.in')
-copy_if_modified(kconfig_inc_path + '.in', kconfig_inc_path)
+temp_sdkconfig_path = '{}/sdkconfig.tmp'.format(builddir)
+kconfigs = subprocess.check_output(["find", "../../components", "-name", "Kconfig"])
+kconfig_projbuilds = subprocess.check_output(["find", "../../components", "-name", "Kconfig.projbuild"])
+confgen_args = ["python",
+                "../../tools/kconfig_new/confgen.py",
+                "--kconfig", "../../Kconfig",
+                "--config", temp_sdkconfig_path,
+                "--create-config-if-missing",
+                "--env", "COMPONENT_KCONFIGS={}".format(kconfigs),
+                "--env", "COMPONENT_KCONFIGS_PROJBUILD={}".format(kconfig_projbuilds),
+                "--output", "docs", kconfig_inc_path
+]
+subprocess.check_call(confgen_args)
 
 # http://stackoverflow.com/questions/12772927/specifying-an-online-image-in-sphinx-restructuredtext-format
 # 
diff --git a/docs/gen-kconfig-doc.py b/docs/gen-kconfig-doc.py
deleted file mode 100755 (executable)
index a141641..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# gen-kconfig-doc.py — generate Sphinx .rst file from Kconfig files
-#
-# This script iterates over Kconfig and Kconfig.projbuild files in
-# ESP-IDF component directories, and outputs documentation for these options
-# as ReST markup.
-# For each option in Kconfig file (e.g. 'FOO'), CONFIG_FOO link target is
-# generated, allowing options to be referenced in other documents 
-# (using :ref:`CONFIG_FOO`)
-#
-# This script uses kconfiglib library to do all the work of parsing Kconfig
-# files: https://github.com/ulfalizer/Kconfiglib
-#
-# Copyright 2017 Espressif Systems (Shanghai) PTE LTD
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http:#www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import os
-import kconfiglib
-
-# Indentation to be used in the generated file
-INDENT = '    '
-
-# Characters used when underlining section heading
-HEADING_SYMBOLS = '#*=-^"+'
-
-# Keep the heading level in sync with api-reference/kconfig.rst
-INITIAL_HEADING_LEVEL = 2
-MAX_HEADING_LEVEL = 5
-OPTION_HEADING_LEVEL = 6
-
-
-def print_menu_contents(title, items, heading_level, breadcrumbs):
-    if title:
-        print_section_heading(title, heading_level)
-    for entry in items:
-        if entry.is_menu():
-            if len(breadcrumbs) > 0:
-                new_breadcrumbs = breadcrumbs + ' > ' + entry.get_title()
-            else:
-                new_breadcrumbs = entry.get_title()
-
-            print_menu_contents(entry.get_title(), entry.get_items(),
-                                min(heading_level + 1, MAX_HEADING_LEVEL),
-                                new_breadcrumbs)
-        elif entry.is_choice():
-            print_choice(entry, breadcrumbs)
-        else:
-            if len(entry.get_prompts()) == 0:
-                # Skip entries which can never be visible
-                continue
-            # Currently this does not handle 'menuconfig' entires in any special way,
-            # as Kconfglib offers no way of recognizing them automatically.
-            print_option(entry, breadcrumbs)
-        # Trailing newline after every option
-        print
-
-def print_choice(choice, breadcrumbs):
-    print_option(choice, breadcrumbs)
-    print
-    print '%sAvailable options:' % INDENT
-    for opt in choice.get_symbols():
-        # Format available options as a list
-        print '%s- %s' % (INDENT * 2, opt.name)
-
-def print_section_heading(title, heading_level):
-    print title
-    print HEADING_SYMBOLS[heading_level] * len(title)
-    print
-
-def print_option(opt, breadcrumbs):
-    # add link target so we can use :ref:`CONFIG_FOO` 
-    print '.. _CONFIG_%s:' % opt.name
-    print
-    print_section_heading(opt.name, OPTION_HEADING_LEVEL)
-    if len(opt.prompts) > 0:
-        print '%s%s' % (INDENT, opt.prompts[0][0])
-        print
-    print '%s:emphasis:`Found in: %s`' % (INDENT, breadcrumbs)
-    print
-    if opt.get_help() is not None:
-        # Help text normally contains newlines, but spaces at the beginning of
-        # each line are stripped by kconfiglib. We need to re-indent the text
-        # to produce valid ReST.
-        print '%s%s' % (INDENT, opt.get_help().replace('\n', '\n%s' % INDENT))
-
-def process_kconfig_file(kconfig_file, heading_level, breadcrumbs):
-    if os.path.exists(kconfig_file):
-        cfg = kconfiglib.Config(kconfig_file, print_warnings=True)
-        print_menu_contents(None, cfg.get_top_level_items(), heading_level, breadcrumbs)
-
-def print_all_components():
-    heading_level = INITIAL_HEADING_LEVEL
-    # Currently this works only for IDF components.
-    # TODO: figure out if this can be re-used for documenting applications?
-    components_path = os.path.join(os.path.curdir, '../..', 'components')
-    for component_name in os.listdir(components_path):
-        if component_name.startswith('.'):
-            continue    # skip system thumbnail folders
-
-        kconfig_file_path = os.path.join(components_path, component_name, 'Kconfig')
-
-        process_kconfig_file(kconfig_file_path, heading_level, 'Component config')
-        process_kconfig_file(kconfig_file_path + '.projbuild', heading_level, '')
-
-if __name__ == '__main__':
-    print_all_components()
index 6614c54c331bc182335ee296a3d774668adeb09c..e5e6968f18799bc5d46f045281e975a75b4d4bdf 100644 (file)
@@ -7,7 +7,7 @@
 # generated, allowing options to be referenced in other documents
 # (using :ref:`CONFIG_FOO`)
 #
-# Copyright 2017 Espressif Systems (Shanghai) PTE LTD
+# Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -30,12 +30,13 @@ INDENT = '    '
 HEADING_SYMBOLS = '#*=-^"+'
 
 # Keep the heading level in sync with api-reference/kconfig.rst
-INITIAL_HEADING_LEVEL = 2
-MAX_HEADING_LEVEL = 5
+INITIAL_HEADING_LEVEL = 3
+MAX_HEADING_LEVEL = len(HEADING_SYMBOLS)-1
 
 def write_docs(config, filename):
     """ Note: writing .rst documentation ignores the current value
-    of any items. ie the --config option can be ignored. """
+    of any items. ie the --config option can be ignored.
+    (However at time of writing it still needs to be set to something...) """
     with open(filename, "w") as f:
         config.walk_menu(lambda node: write_menu_item(f, node))
 
@@ -61,6 +62,15 @@ def get_heading_level(node):
         node = node.parent
     return result
 
+def format_rest_text(text, indent):
+    # Format an indented text block for use with ReST
+    text = indent + text.replace('\n', '\n' + indent)
+    # Escape some characters which are inline formatting in ReST
+    text = text.replace("*", "\\*")
+    text = text.replace("_", "\\_")
+    text += '\n'
+    return text
+
 def write_menu_item(f, node):
     if not node.prompt:
         return  # Don't do anything for invisible menu items
@@ -87,12 +97,12 @@ def write_menu_item(f, node):
         title = node.prompt[0]
 
     # if no symbol name, use the prompt as the heading
-    if is_menu:
+    if True or is_menu:
         f.write('%s\n' % title)
         f.write(HEADING_SYMBOLS[get_heading_level(node)] * len(title))
         f.write('\n\n')
     else:
-        f.write('**%s**\n\n\n % title')
+        f.write('**%s**\n\n\n' % title)
 
     if name:
         f.write('%s%s\n\n' % (INDENT, node.prompt[0]))
@@ -103,7 +113,7 @@ def write_menu_item(f, node):
             # Help text normally contains newlines, but spaces at the beginning of
             # each line are stripped by kconfiglib. We need to re-indent the text
             # to produce valid ReST.
-            f.write('%s%s\n' % (INDENT, node.help.replace('\n', '\n%s' % INDENT)))
+            f.write(format_rest_text(node.help, INDENT))
     except AttributeError:
         pass  # No help
 
@@ -115,8 +125,8 @@ def write_menu_item(f, node):
             f.write('%s- %-20s (%s)\n' % (INDENT * 2, choice_node.prompt[0], choice_node.item.name))
             if choice_node.help:
                 HELP_INDENT = INDENT * 2
-                fmt_help = choice_node.help.replace('\n', '\n%s  ' % HELP_INDENT)
-                f.write('%s  \n%s  %s\n' % (HELP_INDENT, HELP_INDENT, fmt_help))
+                fmt_help = format_rest_text(choice_node.help, '  ' + HELP_INDENT)
+                f.write('%s  \n%s\n' % (HELP_INDENT, fmt_help))
             choice_node = choice_node.next
 
         f.write('\n\n')