import os from docutils import nodes from docutils.parsers.rst import Directive, directives from docutils.parsers.rst.directives.images import Image from sphinx.directives.code import LiteralInclude def excluded_list(argument): return argument.split(',') class LvExample(Directive): required_arguments = 1 option_spec = { 'excluded_languages': excluded_list, 'language': directives.unchanged, 'description': directives.unchanged } def get_example_code_path(self, example_path, language): return os.path.abspath("../examples/" + example_path + "." + language) def human_language_name(self, language): if language == 'py': return 'MicroPython' elif language == 'c': return 'C' else: return language def github_path(self, example_path, language): env = self.state.document.settings.env return f"https://github.com/lvgl/lvgl/blob/{env.config.repo_commit_hash}/examples/{example_path}.{language}" def embed_code(self, example_file, example_path, language, buttons={}): toggle = nodes.container('', literal_block=False, classes=['toggle']) header = nodes.container('', literal_block=False, classes=['header']) toggle.append(header) try: with open(example_file) as f: contents = f.read() except FileNotFoundError: contents = 'Error encountered while trying to open ' + example_file literal_list = nodes.literal_block(contents, contents) literal_list['language'] = language toggle.append(literal_list) paragraph_node = nodes.raw(text=f"

{self.human_language_name(language)} code  

", format='html') for text, url in buttons.items(): paragraph_node.append(nodes.raw(text=f"{text}", format='html')) header.append(paragraph_node) return toggle def run(self): example_path = self.arguments[0] example_name = os.path.split(example_path)[1] excluded_languages = self.options.get('excluded_languages', []) node_list = [] env = self.state.document.settings.env iframe_html = "" c_path = self.get_example_code_path(example_path, 'c') py_path = self.get_example_code_path(example_path, 'py') c_code = self.embed_code(c_path, example_path, 'c', buttons={ ' GitHub': self.github_path(example_path, 'c') }) py_code = self.embed_code(py_path, example_path, 'py', buttons={ ' GitHub': self.github_path(example_path, 'py'), ' Simulator': f"https://sim.lvgl.io/v{env.config.version}/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/{example_path}.py" }) if not 'c' in excluded_languages: if env.app.tags.has('html'): iframe_html = f"
" description_html = f"
{self.options.get('description', '')}
" layout_node = nodes.raw(text=f"
{iframe_html}{description_html}
", format='html') node_list.append(layout_node) if not 'c' in excluded_languages: node_list.append(c_code) if not 'py' in excluded_languages: node_list.append(py_code) trailing_node = nodes.raw(text=f"
", format='html') node_list.append(trailing_node) return node_list def setup(app): app.add_directive("lv_example", LvExample) app.add_config_value("repo_commit_hash", "", "env") return { 'version': '0.1', 'parallel_read_safe': True, 'parallel_write_safe': True, }