docs build: switch to esp-docs framework from raw doxygen build

This commit is contained in:
Vikram Dattu
2024-02-06 18:41:07 +05:30
parent 5772ee461f
commit fb88feca05
29 changed files with 255 additions and 616 deletions

View File

@@ -7,6 +7,8 @@ variables:
MAKEFLAGS: "-j8 --no-keep-going"
APP_BUILD: "all"
GIT_SUBMODULE_STRATEGY: recursive
ESP_DOCS_ENV_IMAGE: "$CI_DOCKER_REGISTRY/esp-idf-doc-env-v5.0:2-2"
ESP_DOCS_PATH: "$CI_PROJECT_DIR"
before_script:
# add gitlab ssh key
@@ -170,31 +172,68 @@ build_matter:
- *build_matter_controller_example
build_docs:
stage: build
image: $CI_DOCKER_REGISTRY/esp32-ci-env
tags:
- build
artifacts:
paths:
- $CI_PROJECT_DIR/esp-rainmaker-docs-${CI_JOB_ID}.zip
script:
# Building sphinx docs
- echo Building sphinx docs
- cd docs
# unset IDF_PATH
- echo Unset IDF_PATH
- unset IDF_PATH
# Run requirements.txt
- echo Run requirements.txt
- python3 -m pip install -r requirements.txt
# Run make html
- echo Run make html
- make html
- cd $CI_PROJECT_DIR
- echo Generating tar files
- mkdir -p esp-rainmaker-docs-${CI_JOB_ID}/html
- cp -rf $CI_PROJECT_DIR/docs/_build/html/ esp-rainmaker-docs-${CI_JOB_ID}/html/
- tar -zcvf esp-rainmaker-docs-${CI_JOB_ID}.zip esp-rainmaker-docs-${CI_JOB_ID}
stage: build
image: $ESP_DOCS_ENV_IMAGE
tags:
- build_docs
artifacts:
paths:
- docs/_build/*/*/*.txt
- docs/_build/*/*/html/*
expire_in: 4 days
# No cleaning when the artifacts
after_script: []
script:
- cd docs
- pip install -r requirements.txt
- build-docs -l en -t esp32
.deploy_docs_template:
stage: deploy
image: $ESP_DOCS_ENV_IMAGE
tags:
- deploy_docs
needs:
- build_docs
only:
changes:
- "docs/**/*"
script:
- source ${CI_PROJECT_DIR}/docs/utils.sh
- add_doc_server_ssh_keys $DOCS_DEPLOY_PRIVATEKEY $DOCS_DEPLOY_SERVER $DOCS_DEPLOY_SERVER_USER
- export GIT_VER=$(git describe --always)
- pip install -r ${CI_PROJECT_DIR}/docs/requirements.txt
- deploy-docs
deploy_docs_preview:
extends:
- .deploy_docs_template
except:
refs:
- master
variables:
TYPE: "preview"
DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/"
DOCS_DEPLOY_PRIVATEKEY: "$DOCS_PREVIEW_PRIVATEKEY"
DOCS_DEPLOY_SERVER: "$DOCS_PREVIEW_SERVER"
DOCS_DEPLOY_SERVER_USER: "$DOCS_PREVIEW_USER"
DOCS_DEPLOY_PATH: "$DOCS_PREVIEW_PATH"
DOCS_DEPLOY_URL_BASE: "$DOCS_PREVIEW_URL_BASE"
deploy_docs_production:
extends:
- .deploy_docs_template
only:
refs:
- master
variables:
TYPE: "production"
DOCS_BUILD_DIR: "${CI_PROJECT_DIR}/docs/_build/"
DOCS_DEPLOY_PRIVATEKEY: "$DOCS_PROD_PRIVATEKEY"
DOCS_DEPLOY_SERVER: "$DOCS_PROD_SERVER"
DOCS_DEPLOY_SERVER_USER: "$DOCS_PROD_USER"
DOCS_DEPLOY_PATH: "$DOCS_PROD_PATH"
DOCS_DEPLOY_URL_BASE: "$DOCS_PROD_URL_BASE"
push_master_to_github:
stage: deploy

View File

@@ -4,7 +4,7 @@
## Introduction
ESP RainMaker is an end-to-end solution offered by Espressif to enable remote control and monitoring for ESP32 series of SoCs (e.g., ESP32, ESP32-S2, ESP32-C3, ESP32-C6, ESP32-C2, etc.) based products without any configuration required in the Cloud. <br>
ESP RainMaker is an end-to-end solution offered by Espressif to enable remote control and monitoring for products based on ESP32 series of SoCs (e.g., ESP32, ESP32-S2, ESP32-C3, ESP32-C6, ESP32-C2, etc.) without any configuration required in the Cloud. <br>
The primary components of this solution are:

View File

@@ -21,29 +21,23 @@ PROJECT_NAME = "ESP RainMaker Programming Guide"
## and used to include in API reference documentation
INPUT = \
## RainMaker Core
../components/esp_rainmaker/include/esp_rmaker_core.h \
../components/esp_rainmaker/include/esp_rmaker_user_mapping.h \
../components/esp_rainmaker/include/esp_rmaker_schedule.h \
../components/esp_rainmaker/include/esp_rmaker_scenes.h \
## RainMaker Standard Types
../components/esp_rainmaker/include/esp_rmaker_standard_types.h \
../components/esp_rainmaker/include/esp_rmaker_standard_params.h \
../components/esp_rainmaker/include/esp_rmaker_standard_devices.h \
../components/esp_rainmaker/include/esp_rmaker_standard_services.h \
## RainMaker OTA
../components/esp_rainmaker/include/esp_rmaker_ota.h \
## RainMaker MQTT
../components/esp_rainmaker/include/esp_rmaker_mqtt.h \
## RainMaker Console
../components/esp_rainmaker/include/esp_rmaker_console.h \
## RainMaker Common
../components/rmaker_common/include/esp_rmaker_common_events.h \
../components/rmaker_common/include/esp_rmaker_factory.h \
../components/rmaker_common/include/esp_rmaker_work_queue.h \
../components/rmaker_common/include/esp_rmaker_utils.h \
../components/rmaker_common/include/esp_rmaker_cmd_resp.h \
../components/rmaker_common/include/esp_rmaker_mqtt_glue.h
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_core.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_user_mapping.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_schedule.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_scenes.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_standard_types.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_standard_params.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_standard_devices.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_standard_services.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_ota.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_mqtt.h \
$(PROJECT_PATH)/components/esp_rainmaker/include/esp_rmaker_console.h \
$(PROJECT_PATH)/components/rmaker_common/include/esp_rmaker_common_events.h \
$(PROJECT_PATH)/components/rmaker_common/include/esp_rmaker_factory.h \
$(PROJECT_PATH)/components/rmaker_common/include/esp_rmaker_work_queue.h \
$(PROJECT_PATH)/components/rmaker_common/include/esp_rmaker_utils.h \
$(PROJECT_PATH)/components/rmaker_common/include/esp_rmaker_cmd_resp.h \
$(PROJECT_PATH)/components/rmaker_common/include/esp_rmaker_mqtt_glue.h
## Get warnings for functions that have no documentation for their parameters or return value
##
@@ -54,7 +48,11 @@ WARN_NO_PARAMDOC = YES
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED =
PREDEFINED = \
$(ENV_DOXYGEN_DEFINES)
## Extract all
EXTRACT_ALL = YES
## Do not complain about not having dot
##
@@ -77,4 +75,3 @@ QUIET = YES
## Log warnings in a file for further review
##
WARN_LOGFILE = "doxygen-warning-log.txt"

View File

@@ -2,28 +2,14 @@
This folder contains source files of **ESP RainMaker API documentation**.
The sources do not render well in GitHub and some information is not visible at all.
Use actual documentation generated within about 20 minutes on each commit:
# Hosted Documentation
* Check here: https://docs.espressif.com/projects/esp-rainmaker/en/latest/
* Check the following link for the documentation: https://docs.espressif.com/projects/esp-rainmaker/en/latest/
The above URL is for the master branch latest version.
# Building Documentation
* Install `make` and `doxygen` for your platform (`make` may already be installed as an ESP-IDF prerequisite).
* Change to the docs directory and run `make html`
* `make` will probably prompt you to run a python pip install step to get some other Python-related prerequisites. Run the command as shown, then re-run `make html` to build the docs.
## For MSYS2 MINGW32 on Windows
If using Windows and the MSYS2 MINGW32 terminal, run this command before running "make html" the first time:
```
pacman -S doxygen mingw-w64-i686-python2-pillow
```
Note: Currently it is not possible to build docs on Windows without using a Unix-on-Windows layer such as MSYS2 MINGW32.
* ESP RainMaker uses esp-docs for building the docs.
* Change to the docs directory and run `build-docs -l en -t esp32`
* To understand more about ESP-Docs, please follow https://docs.espressif.com/projects/esp-docs.

View File

@@ -1,18 +0,0 @@
RainMaker Common
################
Utilities
---------
.. include:: /_build/inc/esp_rmaker_utils.inc
Factory Storage
---------------
.. include:: /_build/inc/esp_rmaker_factory.inc
Work Queue
----------
.. include:: /_build/inc/esp_rmaker_work_queue.inc
Common Events
-------------
.. include:: /_build/inc/esp_rmaker_common_events.inc

View File

@@ -1,3 +0,0 @@
RainMaker Console
#################
.. include:: /_build/inc/esp_rmaker_console.inc

View File

@@ -1,18 +0,0 @@
RainMaker Core
##############
Core
----
.. include:: /_build/inc/esp_rmaker_core.inc
User Mapping
------------
.. include:: /_build/inc/esp_rmaker_user_mapping.inc
Scheduling
----------
.. include:: /_build/inc/esp_rmaker_schedule.inc
Scenes
------
.. include:: /_build/inc/esp_rmaker_scenes.inc

View File

@@ -1,3 +0,0 @@
RainMaker MQTT
##############
.. include:: /_build/inc/esp_rmaker_mqtt.inc

View File

@@ -1,3 +0,0 @@
RainMaker OTA
#############
.. include:: /_build/inc/esp_rmaker_ota.inc

View File

@@ -1,18 +0,0 @@
RainMaker Standard Types
########################
Standard Types
--------------
.. include:: /_build/inc/esp_rmaker_standard_types.inc
Standard Parameters
-------------------
.. include:: /_build/inc/esp_rmaker_standard_params.inc
Standard Devices
----------------
.. include:: /_build/inc/esp_rmaker_standard_devices.inc
Standard Services
-----------------
.. include:: /_build/inc/esp_rmaker_standard_services.inc

View File

@@ -1,86 +0,0 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
sys.path.append(os.path.abspath('../cli/'))
autodoc_mock_imports = ["pathlib", "cryptography", "nvs_partition_gen", "oauth2client", "serial", "user_mapping", "rmaker_tools.rmaker_prov.esp_rainmaker_prov", "rmaker_tools.rmaker_prov.security", "rmaker_tools.rmaker_prov.prov", "rmaker_tools.rmaker_prov.prov_util", "rmaker_tools.rmaker_claim.claim"]
# -- Project information -----------------------------------------------------
project = u'ESP RainMaker Programming Guide'
copyright = u'2020, Espressif Systems (Shanghai) CO., LTD'
author = 'Espressif'
try:
builddir = os.environ['BUILDDIR']
except KeyError:
builddir = '_build'
def call_with_python(cmd):
# using sys.executable ensures that the scripts are called with the same Python interpreter
if os.system('{} {}'.format(sys.executable, cmd)) != 0:
raise RuntimeError('{} failed'.format(cmd))
# Call Doxygen to get XML files from the header files
print("Calling Doxygen to generate latest XML files")
if os.system("doxygen Doxyfile") != 0:
raise RuntimeError('Doxygen call failed')
# Generate 'api_name.inc' files using the XML files by Doxygen
call_with_python('./gen-dxd.py')
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'breathe',
'sphinx.ext.autodoc',
'link-roles'
]
# Setup the breathe extension
breathe_projects = {
"ESP RainMaker": "./xml"
}
breathe_default_project = "ESP RainMaker"
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_logo = "_static/esp-rainmaker-logo.png"
def setup(app):
app.add_stylesheet('theme_overrides.css')

37
docs/conf_common.py Normal file
View File

@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
#
# Common (non-language-specific) configuration for Sphinx
#
# type: ignore
# pylint: disable=wildcard-import
# pylint: disable=undefined-variable
from __future__ import print_function, unicode_literals
from esp_docs.conf_docs import * # noqa: F403,F401
import os
import sys
sys.path.insert(0, os.path.abspath('.'))
extensions += ['sphinx_copybutton',
# Needed as a trigger for running doxygen
'esp_docs.esp_extensions.dummy_build_system',
'esp_docs.esp_extensions.run_doxygen',
'sphinx.ext.autodoc'
]
# link roles config
github_repo = 'espressif/esp-rainmaker'
# context used by sphinx_idf_theme
html_context['github_user'] = 'espressif'
html_context['github_repo'] = 'esp-rainmaker'
html_static_path = ['../_static']
# Extra options required by sphinx_idf_theme
project_slug = 'esp-rainmaker'
idf_targets = ['esp32', 'esp32s3', 'esp32c2', 'esp32c3']
languages = ['en']

View File

@@ -0,0 +1,18 @@
RainMaker Common
################
Utilities
---------
.. include-build-file:: inc/esp_rmaker_utils.inc
Factory Storage
---------------
.. include-build-file:: inc/esp_rmaker_factory.inc
Work Queue
----------
.. include-build-file:: inc/esp_rmaker_work_queue.inc
Common Events
-------------
.. include-build-file:: inc/esp_rmaker_common_events.inc

View File

@@ -0,0 +1,3 @@
RainMaker Console
#################
.. include-build-file:: inc/esp_rmaker_console.inc

View File

@@ -0,0 +1,18 @@
RainMaker Core
##############
Core
----
.. include-build-file:: inc/esp_rmaker_core.inc
User Mapping
------------
.. include-build-file:: inc/esp_rmaker_user_mapping.inc
Scheduling
----------
.. include-build-file:: inc/esp_rmaker_schedule.inc
Scenes
------
.. include-build-file:: inc/esp_rmaker_scenes.inc

View File

@@ -0,0 +1,3 @@
RainMaker MQTT
##############
.. include-build-file:: inc/esp_rmaker_mqtt.inc

View File

@@ -0,0 +1,3 @@
RainMaker OTA
#############
.. include-build-file:: inc/esp_rmaker_ota.inc

View File

@@ -0,0 +1,18 @@
RainMaker Standard Types
########################
Standard Types
--------------
.. include-build-file:: inc/esp_rmaker_standard_types.inc
Standard Parameters
-------------------
.. include-build-file:: inc/esp_rmaker_standard_params.inc
Standard Devices
----------------
.. include-build-file:: inc/esp_rmaker_standard_devices.inc
Standard Services
-----------------
.. include-build-file:: inc/esp_rmaker_standard_services.inc

31
docs/en/conf.py Normal file
View File

@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
#
# English Language RTD & Sphinx config file
#
# Uses ../conf_common.py for most non-language-specific settings.
# Importing conf_common adds all the non-language-specific
# parts to this conf module
try:
from conf_common import * # noqa: F403,F401
except ImportError:
import os
import sys
sys.path.insert(0, os.path.abspath('../'))
from conf_common import * # noqa: F403,F401
import datetime
sys.path.append(os.path.abspath('../../cli/'))
autodoc_mock_imports = ["pathlib", "cryptography", "nvs_partition_gen", "oauth2client", "serial", "user_mapping", "rmaker_tools.rmaker_prov.esp_rainmaker_prov", "rmaker_tools.rmaker_prov.security", "rmaker_tools.rmaker_prov.prov", "rmaker_tools.rmaker_prov.prov_util", "rmaker_tools.rmaker_claim.claim"]
current_year = datetime.datetime.now().year
# -- Project information -----------------------------------------------------
project = u'ESP RainMaker Programming Guide'
copyright = u'2020, Espressif Systems (Shanghai) CO., LTD'
author = 'Espressif'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
language = 'en'

14
docs/en/index.rst Normal file
View File

@@ -0,0 +1,14 @@
ESP RainMaker Programming Guide
===============================
ESP RainMaker is an end-to-end solution offered by Espressif to enable remote control and monitoring for products based on ESP32 series of SoCs (e.g., ESP32, ESP32-S2, ESP32-C3, ESP32-C6, ESP32-C2, etc.) without any configuration required in the Cloud. It provides a device SDK, self-adapting phone apps, transparent cloud middleware and host utilities to reduce complexity in development of connected devices.
This is the C API (for firmware) and Python API (for host tools) documentation for ESP RainMaker. All other documentation can be found at `http://rainmaker.espressif.com <http://rainmaker.espressif.com>`_
.. _C API Reference: c-api-reference/index.html
.. _Python API Reference: python-api-reference/index.html
.. toctree::
:hidden:
c-api-reference/index
python-api-reference/index

View File

@@ -1,318 +0,0 @@
#!/usr/bin/env python
#
# gen-dxd.py - Generate Doxygen Directives
#
# This code is in the Public Domain (or CC0 licensed, at your option.)
# Unless required by applicable law or agreed to in writing, this
# software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied.
#
from __future__ import print_function
from __future__ import unicode_literals
from builtins import range
from io import open
import sys
import os
import re
# Determime build directory
builddir = '_build'
if 'BUILDDIR' in os.environ:
builddir = os.environ['BUILDDIR']
# Script configurationheader_file_path_prefix = "../../components/"
header_file_path_prefix = "components/"
"""string: path prefix for header files.
"""
doxyfile_path = "Doxyfile"
"""string: path to a file containing header files to processs.
"""
xml_directory_path = "xml"
"""string: path to directory with XML files by Doxygen.
"""
inc_directory_path = os.path.join(builddir, 'inc')
"""string: path prefix for header files.
"""
all_kinds = [
("function", "Functions"),
("union", "Unions"),
("struct", "Structures"),
("define", "Macros"),
("typedef", "Type Definitions"),
("enum", "Enumerations")
]
"""list of items that will be generated for a single API file
"""
def get_doxyfile_input():
"""Get contents of Doxyfile's INPUT statement.
Returns:
Contents of Doxyfile's INPUT.
"""
if not os.path.isfile(doxyfile_path):
print("Doxyfile '%s' does not exist!" % doxyfile_path)
sys.exit()
print("Getting Doxyfile's INPUT")
input_file = open(doxyfile_path, "r", encoding='utf-8')
line = input_file.readline()
# read contents of Doxyfile until 'INPUT' statement
while line:
if line.find("INPUT") == 0:
break
line = input_file.readline()
doxyfile_INPUT = ""
line = input_file.readline()
# skip input_file contents until end of 'INPUT' statement
while line:
if line.isspace():
# we have reached the end of 'INPUT' statement
break
# process only lines that are not comments
if line.find("#") == -1:
# extract header file path inside components folder
m = re.search(header_file_path_prefix + "(.*\.h)", line) # noqa: W605 - regular expression
header_file_path = m.group(1)
doxyfile_INPUT += header_file_path + "\n"
# proceed reading next line
line = input_file.readline()
input_file.close()
return doxyfile_INPUT
def get_api_name(header_file_path):
"""Get name of API from header file path.
Args:
header_file_path: path to the header file.
Returns:
The name of API.
"""
api_name = ""
regex = r".*/(.*)\.h"
m = re.search(regex, header_file_path)
if m:
api_name = m.group(1)
return api_name
def get_rst_header(header_name):
"""Get rst formatted code with a header.
Args:
header_name: name of header.
Returns:
Formatted rst code with the header.
"""
rst_output = ""
rst_output += header_name + "\n"
rst_output += "^" * len(header_name) + "\n"
rst_output += "\n"
return rst_output
def select_unions(innerclass_list):
"""Select unions from innerclass list.
Args:
innerclass_list: raw list with unions and structures
extracted from Dogygen's xml file.
Returns:
Doxygen directives with unions selected from the list.
"""
rst_output = ""
for line in innerclass_list.splitlines():
# union is denoted by "union" at the beginning of line
if line.find("union") == 0:
union_id, union_name = re.split(r"\t+", line)
rst_output += ".. doxygenunion:: "
rst_output += union_name
rst_output += "\n"
return rst_output
def select_structs(innerclass_list):
"""Select structures from innerclass list.
Args:
innerclass_list: raw list with unions and structures
extracted from Dogygen's xml file.
Returns:
Doxygen directives with structures selected from the list.
Note: some structures are excluded as described on code below.
"""
rst_output = ""
for line in innerclass_list.splitlines():
# structure is denoted by "struct" at the beginning of line
if line.find("struct") == 0:
# skip structures that are part of union
# they are documented by 'doxygenunion' directive
if line.find("::") > 0:
continue
struct_id, struct_name = re.split(r"\t+", line)
rst_output += ".. doxygenstruct:: "
rst_output += struct_name
rst_output += "\n"
rst_output += " :members:\n"
rst_output += "\n"
return rst_output
def get_directives(tree, kind):
"""Get directives for specific 'kind'.
Args:
tree: the ElementTree 'tree' of XML by Doxygen
kind: name of API "kind" to be generated
Returns:
Doxygen directives for selected 'kind'.
Note: the header with "kind" name is included.
"""
rst_output = ""
if kind in ["union", "struct"]:
innerclass_list = ""
for elem in tree.iterfind('compounddef/innerclass'):
innerclass_list += elem.attrib["refid"] + "\t" + elem.text + "\n"
if kind == "union":
rst_output += select_unions(innerclass_list)
else:
rst_output += select_structs(innerclass_list)
else:
for elem in tree.iterfind(
'compounddef/sectiondef/memberdef[@kind="%s"]' % kind):
name = elem.find('name')
rst_output += ".. doxygen%s:: " % kind
rst_output += name.text + "\n"
if rst_output:
all_kinds_dict = dict(all_kinds)
rst_output = get_rst_header(all_kinds_dict[kind]) + rst_output + "\n"
return rst_output
def generate_directives(header_file_path):
"""Generate API reference with Doxygen directives for a header file.
Args:
header_file_path: a path to the header file with API.
Returns:
Doxygen directives for the header file.
"""
api_name = get_api_name(header_file_path)
# in XLT file name each "_" in the api name is expanded by Doxygen to "__"
xlt_api_name = api_name.replace("_", "__")
xml_file_path = "%s/%s_8h.xml" % (xml_directory_path, xlt_api_name)
rst_output = ""
rst_output = ".. File automatically generated by 'gen-dxd.py'\n"
rst_output += "\n"
rst_output += get_rst_header("Header File")
rst_output += "* :component_file:`" + header_file_path + "`\n"
rst_output += "\n"
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
tree = ET.ElementTree(file=xml_file_path)
for i in range(len(all_kinds)):
kind = all_kinds[i][0]
rst_output += get_directives(tree, kind)
return rst_output
def generate_api_inc_files():
"""Generate header_file.inc files
with API reference made of doxygen directives
for each header file
specified in the 'INPUT' statement of Doxyfile.
"""
if not os.path.isdir(xml_directory_path):
print("Directory %s does not exist!" % xml_directory_path)
sys.exit()
if not os.path.exists(inc_directory_path):
os.makedirs(inc_directory_path)
list_to_generate = get_doxyfile_input()
print("Generating 'api_name.inc' files with Doxygen directives")
for header_file_path in list_to_generate.splitlines():
api_name = get_api_name(header_file_path)
inc_file_path = inc_directory_path + "/" + api_name + ".inc"
rst_output = generate_directives(header_file_path)
previous_rst_output = ''
if os.path.isfile(inc_file_path):
with open(inc_file_path, "r", encoding='utf-8') as inc_file_old:
previous_rst_output = inc_file_old.read()
if previous_rst_output != rst_output:
with open(inc_file_path, "w", encoding='utf-8') as inc_file:
inc_file.write(rst_output)
if __name__ == "__main__":
"""The main script that generates
Doxygen directives.
"""
# Process command line arguments, if any
if len(sys.argv) > 1:
if not os.path.isdir(xml_directory_path):
print("Directory %s does not exist!" % xml_directory_path)
sys.exit()
header_file_path = sys.argv[1]
api_name = get_api_name(header_file_path)
if api_name:
rst_output = generate_directives(header_file_path)
print("Doxygen directives for '%s'" % header_file_path)
print()
print(rst_output)
else:
print("Options to execute 'gen-dxd.py' application:")
print("1: $ python gen-dxd.py")
print(" Generate API 'header_file.inc' files for headers defined in '%s'" % doxyfile_path)
print("2: $ python gen-dxd.py header_file_path")
print(" Print out Doxygen directives for a single header file")
print(" example: $ python gen-dxd.py mdns/include/mdns.h")
print(" NOTE: Run Doxygen first to get XML files for the header file")
sys.exit()
# No command line arguments given
generate_api_inc_files()

View File

@@ -1,11 +0,0 @@
ESP RainMaker Programming Guide
===============================
ESP RainMaker is a platform that allows developers to build connected devices with Espressifs ESP32-S2 SoC without hassle of managing the infrastructure. It provides a device SDK, self-adapting phone apps, transparent cloud middleware and host utilities to reduce complexity in development of connected devices.
This is the C API (for firmware) and Python API (for host tools) documentation for ESP RainMaker. All other documentation can be found at `http://rainmaker.espressif.com <http://rainmaker.espressif.com>`_
.. toctree::
:maxdepth: 2
C API Reference <c-api-reference/index>
Python API Reference <python-api-reference/index>

View File

@@ -1,66 +0,0 @@
# based on http://protips.readthedocs.io/link-roles.html
from __future__ import print_function
from __future__ import unicode_literals
import re
import os
from docutils import nodes
from local_util import run_cmd_get_output
def get_github_rev():
path = run_cmd_get_output('git rev-parse --short HEAD')
tag = run_cmd_get_output('git describe --exact-match')
print('Git commit ID: ', path)
if len(tag):
print('Git tag: ', tag)
path = tag
return path
def setup(app):
rev = get_github_rev()
# links to files or folders on the GitHub
baseurl = 'https://github.com/espressif/esp-rainmaker'
app.add_role('component_file', autolink('{}/blob/{}/components/%s'.format(baseurl, rev)))
# link to the current documentation file in specific language version
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if on_rtd:
# provide RTD specific commit identification to be included in the link
tag_rev = 'latest'
if (run_cmd_get_output('git rev-parse --short HEAD') != rev):
tag_rev = rev
else:
# if not on the RTD then provide generic identification
tag_rev = run_cmd_get_output('git describe --always')
app.add_role('link_to_translation', crosslink('%s../../%s/{}/%s.html'.format(tag_rev)))
def autolink(pattern):
def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
m = re.search('(.*)\s*<(.*)>', text) # noqa: W605 - regular expression
if m:
link_text = m.group(1)
link = m.group(2)
else:
link_text = text
link = text
url = pattern % (link,)
node = nodes.reference(rawtext, link_text, refuri=url, **options)
return [node], []
return role
def crosslink(pattern):
def role(name, rawtext, text, lineno, inliner, options={}, content=[]):
(language, link_text) = text.split(':')
docname = inliner.document.settings.env.docname
doc_path = inliner.document.settings.env.doc2path(docname, None, None)
return_path = '../' * doc_path.count('/')
url = pattern % (return_path, language, docname)
node = nodes.reference(rawtext, link_text, refuri=url, **options)
return [node], []
return role

View File

@@ -1,6 +1,4 @@
# This is a list of python packages used to generate documentation. This file is used with pip:
# pip install --user -r requirements.txt
#
sphinx==2.3.1
breathe==4.14.1
sphinx_rtd_theme # This theme is no longer a hard dependency since version 1.4.0. Need to install it manually.
esp-docs==0.2.4

18
docs/utils.sh Normal file
View File

@@ -0,0 +1,18 @@
# Bash helper functions for adding SSH keys
function add_ssh_keys() {
local key_string="${1}"
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo -n "${key_string}" >~/.ssh/id_rsa_base64
base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 >~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
}
function add_doc_server_ssh_keys() {
local key_string="${1}"
local server_url="${2}"
local server_user="${3}"
add_ssh_keys "${key_string}"
echo -e "Host ${server_url}\n\tStrictHostKeyChecking no\n\tUser ${server_user}\n" >>~/.ssh/config
}