Feature/ntyukaev/add doxygen snippet sphinx (#10277)
* add doxygensnippet directive * update MANIFEST.in
This commit is contained in:
@@ -85,7 +85,9 @@ html_theme_options = {
|
||||
|
||||
html_context = {
|
||||
'current_language': 'English',
|
||||
'languages': (('English', '/latest'), ('Chinese', '/cn/latest'))
|
||||
'languages': (('English', '/latest'), ('Chinese', '/cn/latest')),
|
||||
'doxygen_mapping_file': '@DOXYGEN_MAPPING_FILE@',
|
||||
'doxygen_snippet_root': '@OpenVINO_SOURCE_DIR@'
|
||||
}
|
||||
|
||||
repositories = {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
include openvino_sphinx_theme/theme.conf
|
||||
recursive-include openvino_sphinx_theme *.html *.rst
|
||||
recursive-include openvino_sphinx_theme/templates *.html *.rst
|
||||
recursive-include openvino_sphinx_theme/static *.js *.png *.css *.svg
|
||||
recursive-include openvino_sphinx_theme/directives *.py
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from json import JSONDecodeError
|
||||
from sphinx.errors import ExtensionError
|
||||
import jinja2
|
||||
from docutils.parsers import rst
|
||||
from pathlib import Path
|
||||
from bs4 import BeautifulSoup as bs
|
||||
from sphinx.util import logging
|
||||
from pydata_sphinx_theme import index_toctree
|
||||
|
||||
from .directives.code import DoxygenSnippet
|
||||
|
||||
SPHINX_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@@ -15,7 +18,7 @@ def setup_edit_url(app, pagename, templatename, context, doctree):
|
||||
"""Add a function that jinja can access for returning the edit URL of a page."""
|
||||
|
||||
def has_github_page():
|
||||
doxygen_mapping_file = app.config['doxygen_mapping_file']
|
||||
doxygen_mapping_file = app.config.html_context.get('doxygen_mapping_file')
|
||||
name = pagename.rsplit('-')[0]
|
||||
if name in doxygen_mapping_file:
|
||||
return True
|
||||
@@ -46,7 +49,7 @@ def setup_edit_url(app, pagename, templatename, context, doctree):
|
||||
url_template = '{{ github_url }}/{{ github_user }}/{{ github_repo }}' \
|
||||
'/edit/{{ github_version }}/{{ doc_path }}{{ file_name }}'
|
||||
|
||||
doxygen_mapping_file = app.config['doxygen_mapping_file']
|
||||
doxygen_mapping_file = app.config.html_context.get('doxygen_mapping_file')
|
||||
rst_name = pagename.rsplit('-')[0]
|
||||
file_name = doxygen_mapping_file[rst_name]
|
||||
parent_folder = Path(os.path.dirname(file_name)).parts[0]
|
||||
@@ -126,10 +129,9 @@ def _add_collapse_checkboxes(soup, open_first=False):
|
||||
# (by checking the checkbox)
|
||||
if "current" in classes or (open_first and toctree_checkbox_count == 1):
|
||||
checkbox.attrs["checked"] = ""
|
||||
|
||||
|
||||
element.insert(1, checkbox)
|
||||
|
||||
|
||||
def add_toctree_functions(app, pagename, templatename, context, doctree):
|
||||
|
||||
# override pydata_sphinx_theme
|
||||
@@ -208,10 +210,18 @@ def add_toctree_functions(app, pagename, templatename, context, doctree):
|
||||
|
||||
return out
|
||||
|
||||
|
||||
context["generate_sidebar_nav"] = generate_sidebar_nav
|
||||
|
||||
|
||||
def read_doxygen_configs(app, env, docnames):
|
||||
if app.config.html_context.get('doxygen_mapping_file'):
|
||||
try:
|
||||
with open(app.config.html_context.get('doxygen_mapping_file'), 'r', encoding='utf-8') as f:
|
||||
app.config.html_context['doxygen_mapping_file'] = json.load(f)
|
||||
except (JSONDecodeError, FileNotFoundError):
|
||||
app.config.html_context['doxygen_mapping_file'] = dict()
|
||||
|
||||
|
||||
def setup(app):
|
||||
theme_path = get_theme_path()
|
||||
templates_path = os.path.join(theme_path, 'templates')
|
||||
@@ -220,5 +230,7 @@ def setup(app):
|
||||
app.config.html_static_path.append(static_path)
|
||||
app.connect("html-page-context", setup_edit_url, priority=sys.maxsize)
|
||||
app.connect("html-page-context", add_toctree_functions)
|
||||
app.connect('env-before-read-docs', read_doxygen_configs)
|
||||
app.add_html_theme('openvino_sphinx_theme', theme_path)
|
||||
rst.directives.register_directive('doxygensnippet', DoxygenSnippet)
|
||||
return {'parallel_read_safe': True, 'parallel_write_safe': True}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import os.path
|
||||
|
||||
from sphinx.directives.code import LiteralInclude, LiteralIncludeReader, container_wrapper
|
||||
from sphinx.util import logging
|
||||
from docutils.parsers.rst import directives
|
||||
from typing import List, Tuple
|
||||
from docutils.nodes import Node
|
||||
from docutils import nodes
|
||||
from sphinx.util import parselinenos
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DoxygenSnippet(LiteralInclude):
|
||||
|
||||
option_spec = dict({'fragment': directives.unchanged_required}, **LiteralInclude.option_spec)
|
||||
|
||||
def run(self) -> List[Node]:
|
||||
if 'fragment' in self.options:
|
||||
self.options['start-after'] = self.options['fragment']
|
||||
self.options['end-before'] = self.options['fragment']
|
||||
document = self.state.document
|
||||
if not document.settings.file_insertion_enabled:
|
||||
return [document.reporter.warning('File insertion disabled',
|
||||
line=self.lineno)]
|
||||
# convert options['diff'] to absolute path
|
||||
if 'diff' in self.options:
|
||||
_, path = self.env.relfn2path(self.options['diff'])
|
||||
self.options['diff'] = path
|
||||
|
||||
try:
|
||||
location = self.state_machine.get_source_and_line(self.lineno)
|
||||
doxygen_snippet_root = self.config.html_context.get('doxygen_snippet_root')
|
||||
|
||||
if doxygen_snippet_root and os.path.exists(doxygen_snippet_root):
|
||||
rel_filename = self.arguments[0]
|
||||
filename = os.path.join(doxygen_snippet_root, rel_filename)
|
||||
else:
|
||||
rel_filename, filename = self.env.relfn2path(self.arguments[0])
|
||||
self.env.note_dependency(rel_filename)
|
||||
|
||||
reader = LiteralIncludeReader(filename, self.options, self.config)
|
||||
text, lines = reader.read(location=location)
|
||||
|
||||
retnode = nodes.literal_block(text, text, source=filename) # type: Element
|
||||
retnode['force'] = 'force' in self.options
|
||||
self.set_source_info(retnode)
|
||||
if self.options.get('diff'): # if diff is set, set udiff
|
||||
retnode['language'] = 'udiff'
|
||||
elif 'language' in self.options:
|
||||
retnode['language'] = self.options['language']
|
||||
if ('linenos' in self.options or 'lineno-start' in self.options or
|
||||
'lineno-match' in self.options):
|
||||
retnode['linenos'] = True
|
||||
retnode['classes'] += self.options.get('class', [])
|
||||
extra_args = retnode['highlight_args'] = {}
|
||||
if 'emphasize-lines' in self.options:
|
||||
hl_lines = parselinenos(self.options['emphasize-lines'], lines)
|
||||
if any(i >= lines for i in hl_lines):
|
||||
logger.warning(__('line number spec is out of range(1-%d): %r') %
|
||||
(lines, self.options['emphasize-lines']),
|
||||
location=location)
|
||||
extra_args['hl_lines'] = [x + 1 for x in hl_lines if x < lines]
|
||||
extra_args['linenostart'] = reader.lineno_start
|
||||
|
||||
if 'caption' in self.options:
|
||||
caption = self.options['caption'] or self.arguments[0]
|
||||
retnode = container_wrapper(self, retnode, caption)
|
||||
|
||||
# retnode will be note_implicit_target that is linked from caption and numref.
|
||||
# when options['name'] is provided, it should be primary ID.
|
||||
self.add_name(retnode)
|
||||
|
||||
return [retnode]
|
||||
except Exception as exc:
|
||||
return [document.reporter.warning(exc, line=self.lineno)]
|
||||
Reference in New Issue
Block a user