Source code for sphinx_runpython.collapse.sphinx_collapse_extension

import logging
from docutils import nodes
from docutils.parsers.rst import directives
import sphinx
from docutils.parsers.rst import Directive
from sphinx.util.nodes import nested_parse_with_titles
from ..language import TITLES, sphinx_lang


class collapse_node(nodes.admonition):
    """
    Defines ``collapse`` node.
    """

    pass


[docs]class CollapseDirective(Directive): """ A ``collapse`` adds hide/unhide button for a part of HTML page. It has no effect in other formats. * *legend*: legend for the button, if not precise, it will be hide / unhide. Example: ``:legend: hide/unhide``. * *hide*: the text is shown by default unless this option is set up. Example:: .. collapse:: :legend: hide/unhide some text to hide or unhide Which gives: .. collapse:: some text to hide or unhide """ node_class = collapse_node has_content = True required_arguments = 0 optional_arguments = 0 final_argument_whitespace = False option_spec = { "class": directives.class_option, "legend": directives.unchanged, "hide": directives.unchanged, } def run(self): """ Builds the collapse text. """ env = getattr(self.state.document.settings, "env", None) lang = sphinx_lang(env) titles = TITLES.get(lang, TITLES["en"]) if "legend" in self.options: legend = self.options["legend"] if "/" not in legend: logger = logging.getLogger("sphinx") logger.warning( "[CollapseDirective] unable to interpret parameter legend %r.", legend, ) legend = None spl = legend.split("/") hide = spl[0].strip() unhide = spl[1].strip() else: legend = None if legend is None: hide = titles["hide"] unhide = titles["unhide"] if "hide" in self.options and self.options["hide"] not in ( False, "False", "false", 0, "0", ): show = False else: show = True node = collapse_node(hide=hide, unhide=unhide, show=show) nested_parse_with_titles(self.state, self.content, node) return [node]
def visit_collapse_node(self, node): pass def depart_collapse_node(self, node): pass def visit_collapse_node_rst(self, node): self.new_state(0) legend = "/".join([node["hide"], node["unhide"]]) self.add_text(".. collapse::" + self.nl) self.add_text(" :legend: " + legend + self.nl) if not node["show"]: self.add_text(" :hide:" + self.nl) self.new_state(self.indent) def depart_collapse_node_rst(self, node): self.end_state() self.end_state(wrap=False) def visit_collapse_node_html(self, node): nid = str(id(node)) hide, unhide = node["hide"], node["unhide"] script = """function myFunction__ID__() { var x = document.getElementById("collapse__ID__"); var b = document.getElementById("colidb__ID__"); if (x.style.display === "none") { x.style.display = "block"; b.innerText = '__HIDE__'; } else { x.style.display = "none"; b.innerText = '__UNHIDE__'; } }""".replace( " ", "" ) script = script.replace("__ID__", nid) script = script.replace("__HIDE__", hide) script = script.replace("__UNHIDE__", unhide) self.body.append("<script>{0}{1}{0}</script>{0}".format("\n", script)) if node["show"]: content = f'<div id="collapse{nid}"">' label = hide else: content = f'<div id="collapse{nid}" style="display:none;">' label = unhide self.body.append( f'<p style="margin-bottom:10px;"><button id="colidb{nid}" ' f'onclick="myFunction{nid}()">{label}</button></p>\n' ) self.body.append(content) def depart_collapse_node_html(self, node): self.body.append("</div>") def setup(app): app.add_node( collapse_node, html=(visit_collapse_node_html, depart_collapse_node_html), epub=(visit_collapse_node_html, depart_collapse_node_html), elatex=(visit_collapse_node, depart_collapse_node), latex=(visit_collapse_node, depart_collapse_node), text=(visit_collapse_node, depart_collapse_node), md=(visit_collapse_node, depart_collapse_node), rst=(visit_collapse_node_rst, depart_collapse_node_rst), ) app.add_directive("collapse", CollapseDirective) return {"version": sphinx.__display_version__, "parallel_read_safe": True}