docs: self host docs

Move doc hosting from readthedocs to espressif servers

Update CI, Sphinx configs and add IDF Sphinx theme
This commit is contained in:
Marius Vikhammer
2020-08-28 15:29:37 +08:00
parent a6bddd68d2
commit 8e7e0973db
20 changed files with 1494 additions and 118 deletions

View File

@@ -266,6 +266,7 @@ MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
PREDEFINED = \
__attribute__(x)= \
_Static_assert()= \
IDF_DEPRECATED(X)= \
IRAM_ATTR= \
configSUPPORT_DYNAMIC_ALLOCATION=1 \

785
docs/_static/espressif2.pdf vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -20,16 +20,21 @@ import sys
import os
import re
import subprocess
from sanitize_version import sanitize_version
from get_github_rev import get_github_rev
# Note: 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
from local_util import run_cmd_get_output, copy_if_modified
from local_util import copy_if_modified
# build_docs on the CI server sometimes fails under Python3. This is a workaround:
sys.setrecursionlimit(3500)
config_dir = os.path.abspath(os.path.dirname(__file__))
try:
builddir = os.environ['BUILDDIR']
except KeyError:
@@ -146,6 +151,7 @@ suppress_warnings = ['image.nonlocal_uri']
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['breathe',
'sphinx_idf_theme',
'link-roles',
'sphinxcontrib.blockdiag',
'sphinxcontrib.seqdiag',
@@ -154,6 +160,7 @@ extensions = ['breathe',
'sphinxcontrib.rackdiag',
'sphinxcontrib.packetdiag',
'html_redirects',
'latex_builder',
]
# Enabling this fixes cropping of blockdiag edge labels
@@ -188,16 +195,14 @@ master_doc = 'index'
# built documents.
#
# Readthedocs largely ignores 'version' and 'release', and displays one of
# 'latest', tag name, or branch name, depending on the build type.
# Still, this is useful for non-RTD builds.
# This is supposed to be "the short X.Y version", but it's the only version
# This is the full exact version, canonical git version description
# visible when you open index.html.
# Display full version to make things less confusing.
version = run_cmd_get_output('git describe')
# The full version, including alpha/beta/rc tags.
# If needed, nearest tag is returned by 'git describe --abbrev=0'.
release = version
version = subprocess.check_output(['git', 'describe']).strip().decode('utf-8')
# The 'release' version is the same as version for non-CI builds, but for CI
# builds on a branch then it's replaced with the branch name
release = sanitize_version(version)
print('Version: {0} Release: {1}'.format(version, release))
# There are two options for replacing |today|: either, you set today to some
@@ -228,6 +233,13 @@ exclude_patterns = ['_build','README.md']
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Extra options required by sphinx_idf_theme
project_slug = 'esp-idf'
versions_url = 'https://dl.espressif.com/dl/esp-idf/idf_versions.js'
languages = ['en', 'zh_CN']
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
@@ -250,7 +262,15 @@ html_redirect_pages = [tuple(line.split(' ')) for line in lines]
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
html_theme = 'sphinx_rtd_theme'
html_theme = 'sphinx_idf_theme'
# context used by sphinx_idf_theme
html_context = {
"display_github": True, # Add 'Edit on Github' link instead of 'View page source'
"github_user": "espressif",
"github_repo": "esp-idf",
"github_version": get_github_rev(),
}
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -333,28 +353,41 @@ htmlhelp_basename = 'ReadtheDocsTemplatedoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
# 'papersize': 'letterpaper',
#
# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',
#
# Additional stuff for the LaTeX preamble.
# 'preamble': '',
}
latex_template_dir = os.path.join(config_dir, 'latex_templates')
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
('index', 'ReadtheDocsTemplate.tex', u'Read the Docs Template Documentation',
u'Read the Docs', 'manual'),
]
preamble = ''
with open(os.path.join(latex_template_dir, 'preamble.tex')) as f:
preamble = f.read()
titlepage = ''
with open(os.path.join(latex_template_dir, 'titlepage.tex')) as f:
titlepage = f.read()
latex_elements = {
'papersize': 'a4paper',
# Latex figure (float) alignment
'figure_align':'htbp',
'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
'fncychap': '\\usepackage[Sonny]{fncychap}',
'preamble': preamble,
'maketitle': titlepage,
}
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
# The name of an image file (relative to this directory) to place at the bottom of
# the title page.
latex_logo = "../_static/espressif2.pdf"
latex_engine = 'xelatex'
latex_use_xindy = False
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
@@ -415,3 +448,24 @@ texinfo_documents = [
def setup(app):
app.add_stylesheet('theme_overrides.css')
generate_version_specific_includes(app)
# Not all config variables are set when setup is called
app.connect('config-inited', setup_config_values)
app.connect('config-inited', setup_html_context)
def setup_config_values(app, config):
# Sets up global config values needed by other extensions
idf_target_title_dict = {
'esp32': 'ESP32',
}
app.add_config_value('idf_target_title_dict', idf_target_title_dict, 'env')
pdf_name = "esp-idf-{}-{}-{}".format(app.config.language, app.config.version, "esp32")
app.add_config_value('pdf_file', pdf_name, 'env')
def setup_html_context(app, config):
# Setup path for 'edit on github'-link
app.config.html_context['conf_py_path'] = "/docs/{}/".format(app.config.language)

View File

@@ -17,7 +17,7 @@ except ImportError:
# General information about the project.
project = u'ESP-IDF Programming Guide'
copyright = u'2016 - 2020, Espressif Systems (Shanghai) CO., LTD'
copyright = u'2016 - 2021, Espressif Systems (Shanghai) CO., LTD'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -189,34 +189,29 @@ def write_version_note(template, out_dir, version, ver_type, is_stable):
def get_version():
"""
Returns a tuple of (name of branch/tag, type branch/tag, is_stable)
Returns a tuple of (name of branch/tag/commit-id, type branch/tag/commit, is_stable)
"""
# Trust what RTD says our version is, if it is set
version = os.environ.get("READTHEDOCS_VERSION", None)
if version == "latest":
return ("master", "branch", False)
# Otherwise, use git to look for a tag
# Use git to look for a tag
try:
tag = subprocess.check_output(["git", "describe", "--exact-match"]).strip()
tag = subprocess.check_output(["git", "describe", "--exact-match"]).strip().decode('utf-8')
is_stable = re.match(r"v[0-9\.]+$", tag) is not None
return (tag, "tag", is_stable)
except subprocess.CalledProcessError:
pass
# No tag, look for a branch
refs = subprocess.check_output(["git", "for-each-ref", "--points-at", "HEAD", "--format", "%(refname)"])
print("refs:\n%s" % refs)
refs = refs.split(b"\n")
# Note: this looks for branches in 'origin' because GitLab CI doesn't check out a local branch
branches = [r.replace(b"refs/remotes/origin/",b"").strip() for r in refs if r.startswith(b"refs/remotes/origin/")]
if len(branches) == 0:
# last resort, return the commit (may happen on Gitlab CI sometimes, unclear why)
return (subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).strip(), "commit", False)
if "master" in branches:
return ("master", "branch", False)
else:
return (branches[0], "branch", False) # take whatever the first branch is
# No tag, look at branch name from CI, this will give the correct branch name even if the ref for the branch we
# merge into has moved forward before the pipeline runs
branch = os.environ.get("CI_COMMIT_REF_NAME", None)
if branch is not None:
return (branch, "branch", False)
# Try to find the branch name even if docs are built locally
branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip().decode('utf-8')
if branch != "HEAD":
return (branch, "branch", False)
# As a last resort we return commit SHA-1, should never happen in CI/docs that should be published
return (subprocess.check_output(["git", "rev-parse", "--short", "HEAD"]).strip().decode('utf-8'), "commit", False)
if __name__ == "__main__":

15
docs/get_github_rev.py Normal file
View File

@@ -0,0 +1,15 @@
import subprocess
# Get revision used for constructing github URLs
def get_github_rev():
path = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).strip().decode('utf-8')
try:
tag = subprocess.check_output(['git', 'describe', '--exact-match']).strip().decode('utf-8')
except subprocess.CalledProcessError:
tag = None
print('Git commit ID: ', path)
if tag:
print('Git tag: ', tag)
return tag
return path

55
docs/latex_builder.py Normal file
View File

@@ -0,0 +1,55 @@
from sphinx.builders.latex import LaTeXBuilder
import os
# Overrides the default Sphinx latex build
class IdfLatexBuilder(LaTeXBuilder):
def __init__(self, app):
# Sets up the latex_documents config value, done here instead of conf.py since it depends on the runtime value 'idf_target'
self.init_latex_documents(app)
super().__init__(app)
def init_latex_documents(self, app):
file_name = app.config.pdf_file + '.tex'
if app.config.language == 'zh_CN':
latex_documents = [('index', file_name, u'ESP-IDF 编程指南', u'乐鑫信息科技', 'manual')]
else:
# Default to english naming
latex_documents = [('index', file_name, u'ESP-IDF Programming Guide', u'Espressif Systems', 'manual')]
app.config.latex_documents = latex_documents
def prepare_latex_macros(self, package_path, config):
PACKAGE_NAME = "espidf.sty"
latex_package = ''
with open(package_path, 'r') as template:
latex_package = template.read()
idf_target_title = "ESP32"
latex_package = latex_package.replace('<idf_target_title>', idf_target_title)
# Release name for the PDF front page, remove '_' as this is used for subscript in Latex
idf_release_name = "Release {}".format(config.version.replace('_', '-'))
latex_package = latex_package.replace('<idf_release_name>', idf_release_name)
with open(os.path.join(self.outdir, PACKAGE_NAME), 'w') as package_file:
package_file.write(latex_package)
def finish(self):
super().finish()
TEMPLATE_PATH = "../latex_templates/espidf.sty"
self.prepare_latex_macros(os.path.join(self.confdir,TEMPLATE_PATH), self.config)
def setup(app):
app.add_builder(IdfLatexBuilder, override=True)
return {'parallel_read_safe': True, 'parallel_write_safe': True, 'version': '0.1'}

View File

@@ -0,0 +1,7 @@
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{espidf}[2020/03/25 v0.1.0 LaTeX package (ESP-IDF markup)]
\newcommand{\idfTarget}{<idf_target_title>}
\newcommand{\idfReleaseName}{<idf_release_name>}
\endinput

View File

@@ -0,0 +1,129 @@
% package with esp-idf specific macros
\usepackage{espidf}
\setcounter{secnumdepth}{2}
\setcounter{tocdepth}{2}
\usepackage{amsmath,amsfonts,amssymb,amsthm}
\usepackage{graphicx}
%%% reduce spaces for Table of contents, figures and tables
%%% it is used "\addtocontents{toc}{\vskip -1.2cm}" etc. in the document
\usepackage[notlot,nottoc,notlof]{}
\usepackage{color}
\usepackage{transparent}
\usepackage{eso-pic}
\usepackage{lipsum}
%%% Needed for displaying Chinese in English documentation
\usepackage{xeCJK}
\usepackage{footnotebackref} %%link at the footnote to go to the place of footnote in the text
%% spacing between line
\usepackage{setspace}
\singlespacing
\definecolor{myred}{RGB}{229, 32, 26}
\definecolor{mygrayy}{RGB}{127, 127, 127}
\definecolor{myblack}{RGB}{64, 64, 64}
%%%%%%%%%%% datetime
\usepackage{datetime}
\newdateformat{MonthYearFormat}{%
\monthname[\THEMONTH], \THEYEAR}
%% RO, LE will not work for 'oneside' layout.
%% Change oneside to twoside in document class
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhf{}
% Header and footer
\makeatletter
\fancypagestyle{normal}{
\fancyhf{}
\fancyhead[L]{\nouppercase{\leftmark}}
\fancyfoot[C]{\py@HeaderFamily\thepage \\ \href{https://www.espressif.com/en/company/documents/documentation_feedback?docId=4287&sections=&version=\idfReleaseName}{Submit Document Feedback}}
\fancyfoot[L]{Espressif Systems}
\fancyfoot[R]{\idfReleaseName}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
}
\makeatother
\renewcommand{\headrulewidth}{0.5pt}
\renewcommand{\footrulewidth}{0.5pt}
% Define a spacing for section, subsection and subsubsection
% http://tex.stackexchange.com/questions/108684/spacing-before-and-after-section-titles
\titlespacing*{\section}{0pt}{6pt plus 0pt minus 0pt}{6pt plus 0pt minus 0pt}
\titlespacing*{\subsection}{0pt}{18pt plus 64pt minus 0pt}{0pt}
\titlespacing*{\subsubsection}{0pt}{12pt plus 0pt minus 0pt}{0pt}
\titlespacing*{\paragraph} {0pt}{3.25ex plus 1ex minus .2ex}{1.5ex plus .2ex}
\titlespacing*{\subparagraph} {0pt}{3.25ex plus 1ex minus .2ex}{1.5ex plus .2ex}
% Define the colors of table of contents
% This is helpful to understand http://tex.stackexchange.com/questions/110253/what-the-first-argument-for-lsubsection-actually-is
\definecolor{LochmaraColor}{HTML}{1020A0}
% Hyperlinks
\hypersetup{
colorlinks = true,
allcolors = {LochmaraColor},
}
\RequirePackage{tocbibind} %%% comment this to remove page number for following
\addto\captionsenglish{\renewcommand{\contentsname}{Table of contents}}
\addto\captionsenglish{\renewcommand{\listfigurename}{List of figures}}
\addto\captionsenglish{\renewcommand{\listtablename}{List of tables}}
% \addto\captionsenglish{\renewcommand{\chaptername}{Chapter}}
%%reduce spacing for itemize
\usepackage{enumitem}
\setlist{nosep}
%%%%%%%%%%% Quote Styles at the top of chapter
\usepackage{epigraph}
\setlength{\epigraphwidth}{0.8\columnwidth}
\newcommand{\chapterquote}[2]{\epigraphhead[60]{\epigraph{\textit{#1}}{\textbf {\textit{--#2}}}}}
%%%%%%%%%%% Quote for all places except Chapter
\newcommand{\sectionquote}[2]{{\quote{\textit{``#1''}}{\textbf {\textit{--#2}}}}}
% Insert 22pt white space before roc title. \titlespacing at line 65 changes it by -22 later on.
\renewcommand*\contentsname{\hspace{0pt}Contents}
% Define section, subsection and subsubsection font size and color
\usepackage{sectsty}
\definecolor{AllportsColor}{HTML}{A02010}
\allsectionsfont{\color{AllportsColor}}
\usepackage{titlesec}
\titleformat{\section}
{\color{AllportsColor}\LARGE\bfseries}{\thesection.}{1em}{}
\titleformat{\subsection}
{\color{AllportsColor}\Large\bfseries}{\thesubsection.}{1em}{}
\titleformat{\subsubsection}
{\color{AllportsColor}\large\bfseries}{\thesubsubsection.}{1em}{}
\titleformat{\paragraph}
{\color{AllportsColor}\large\bfseries}{\theparagraph}{1em}{}
\titleformat{\subparagraph}
{\normalfont\normalsize\bfseries}{\thesubparagraph}{1em}{}
\titleformat{\subsubparagraph}
{\normalfont\normalsize\bfseries}{\thesubsubparagraph}{1em}{}

View File

@@ -0,0 +1,39 @@
\makeatletter
\newgeometry{left=0cm,right=0cm,bottom=2cm}
\cfoot{www.espressif.com}
\renewcommand{\headrulewidth}{0pt}
{\color{myred}\rule{30pt}{2.1cm}}
\hspace{0.2cm}
\begin{minipage}[b]{18cm}
{\fontsize{36pt}{48pt}\textbf{\idfTarget}}\\
{\fontsize{28pt}{18pt}\textbf{\color{mygrayy}\@title}}
\end{minipage}
\hspace{\stretch{1}}
\vspace{48em}
\begin{flushright}
\setlength\parindent{8em}
\begin{minipage}[b]{2cm}
\sphinxlogo
\end{minipage}
\hspace{0.2cm}
\rule{3pt}{1.9cm}
\hspace{0.2cm}
\begin{minipage}[b]{7cm}
{\large{\idfReleaseName}}\smallskip\newline
{\large{\@author}}\smallskip\newline
{\large{\@date}}\smallskip
\end{minipage}
{\color{myred}\rule{30pt}{1.9cm}}
\end{flushright}
\restoregeometry
\makeatother

View File

@@ -1,17 +1,15 @@
# This is a list of python packages used to generate documentation. This file is used with pip:
# pip install --user -r requirements.txt
#
sphinx>=1.8.4
breathe==4.11.1
sphinx-rtd-theme
sphinx==2.3.1
breathe==4.14.1
sphinx-notfound-page
sphinxcontrib-blockdiag>=1.5.5, <2.0.0
sphinxcontrib-seqdiag>=0.8.5, <2.0.0
sphinxcontrib-actdiag>=0.8.5, <2.0.0
sphinxcontrib-nwdiag>=0.9.5, <2.0.0
blockdiag>=1.5.4, <2.0.0
seqdiag>=0.9.6, <2.0.0
actdiag>=0.5.4, <2.0.0
nwdiag>=1.0.4, <2.0.0
sphinxcontrib-blockdiag==2.0.0
sphinxcontrib-seqdiag==2.0.0
sphinxcontrib-actdiag==2.0.0
sphinxcontrib-nwdiag==2.0.0
sphinxcontrib-wavedrom==2.0.0
nwdiag==2.0.0
recommonmark
future>=0.16.0 # for ../tools/gen_esp_err_to_name.py
sphinx_idf_theme==0.2

43
docs/sanitize_version.py Normal file
View File

@@ -0,0 +1,43 @@
# Tiny Python module to sanitize a Git version into something that can be used in a URL
#
# (this is used in multiple places: conf_common.py and in tools/ci/docs_deploy
#
# Copyright 2020 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
def sanitize_version(original_version):
""" Given a version (probably output from 'git describe --always' or similar), return
a URL-safe sanitized version. (this is used as 'release' config variable when building
the docs.)
Will override the original version with the Gitlab CI CI_COMMIT_REF_NAME environment variable if
this is present.
Also follows the RTD-ism that master branch is named 'latest'
"""
try:
version = os.environ['CI_COMMIT_REF_NAME']
except KeyError:
version = original_version
if version == "master":
return "latest"
version = version.replace('/', '-')
return version

View File

@@ -119,9 +119,9 @@ DUT1 终端::
Waiting for signal: [dut2 mac address]!
Please input parameter value from any board send this signal and press "Enter" key.
DUT2 终端::
DUT2 终端::
Send signal: [dut2 mac address][10:20:30:40:50:60]!
@@ -189,7 +189,7 @@ DUT2 终端::
当单元测试应用程序空闲时,输入回车键,它会打印出测试菜单,其中包含所有的测试项目。
.. code:: bash
.. code::
Here's the test menu, pick your combo:
(1) "esp_ota_begin() verifies arguments" [ota]
@@ -236,7 +236,7 @@ DUT2 终端::
一旦选择了多设备测试用例,它会打印一个子菜单:
.. code:: bash
.. code::
Running gpio master/slave test example...
gpio master/slave test example
@@ -247,7 +247,7 @@ DUT2 终端::
与多设备测试用例相似,多阶段测试用例也会打印子菜单:
.. code:: bash
.. code::
Running reset reason check for deepsleep...
reset reason check for deepsleep

View File

@@ -17,7 +17,7 @@ C 文件可以包含多个测试用例。测试文件的名字要以 “test”
测试用例需要通过 C 文件中特定的函数来添加,如下所示:
.. code:: c
.. code-block:: c
TEST_CASE("test name", "[module name]"
{
@@ -179,7 +179,7 @@ DUT2slave终端
当单元测试应用程序空闲时,输入回车键,它会打印出测试菜单,其中包含所有的测试项目。
.. code:: bash
.. code::
Here's the test menu, pick your combo:
(1) "esp_ota_begin() verifies arguments" [ota]
@@ -226,7 +226,7 @@ DUT2slave终端
一旦选择了多设备测试用例,它会打印一个子菜单:
.. code:: bash
.. code::
Running gpio master/slave test example...
gpio master/slave test example
@@ -237,7 +237,7 @@ DUT2slave终端
与多设备测试用例相似,多阶段测试用例也会打印子菜单:
.. code:: bash
.. code::
Running reset reason check for deepsleep...
reset reason check for deepsleep

View File

@@ -17,7 +17,7 @@ except ImportError:
# General information about the project.
project = u'ESP-IDF 编程指南'
copyright = u'2016 - 2020 乐鑫信息科技(上海)股份有限公司'
copyright = u'2016 - 2021 乐鑫信息科技(上海)股份有限公司'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.