From: Martin Quinson Date: Tue, 11 Sep 2018 23:16:33 +0000 (+0200) Subject: allow to have hidden/shown code blocks in the doc X-Git-Tag: v3_21~101 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/b2fde3bcf906ffcead5e2ce051d0458e0bfc14c1 allow to have hidden/shown code blocks in the doc --- diff --git a/docs/source/_ext/hidden_code_block.py b/docs/source/_ext/hidden_code_block.py new file mode 100644 index 0000000000..a009d43226 --- /dev/null +++ b/docs/source/_ext/hidden_code_block.py @@ -0,0 +1,128 @@ +"""Simple, inelegant Sphinx extension which adds a directive for a +highlighted code-block that may be toggled hidden and shown in HTML. +This is possibly useful for teaching courses. + +The directive, like the standard code-block directive, takes +a language argument and an optional linenos parameter. The +hidden-code-block adds starthidden and label as optional +parameters. + +Examples: + +.. hidden-code-block:: python + :starthidden: False + + a = 10 + b = a + 5 + +.. hidden-code-block:: python + :label: --- SHOW/HIDE --- + + x = 10 + y = x + 5 + +Thanks to http://www.javascriptkit.com/javatutors/dom3.shtml for +inspiration on the javascript. + +Thanks to Milad 'animal' Fatenejad for suggesting this extension +in the first place. + +Written by Anthony 'el Scopz' Scopatz, January 2012. +https://github.com/scopatz/hiddencode + +Released under the WTFPL (http://sam.zoy.org/wtfpl/). +""" + +from docutils import nodes +from docutils.parsers.rst import directives +from sphinx.directives.code import CodeBlock + +HCB_COUNTER = 0 + +js_showhide = """\ + +""" + +def nice_bool(arg): + tvalues = ('true', 't', 'yes', 'y') + fvalues = ('false', 'f', 'no', 'n') + arg = directives.choice(arg, tvalues + fvalues) + return arg in tvalues + + +class hidden_code_block(nodes.General, nodes.FixedTextElement): + pass + + +class HiddenCodeBlock(CodeBlock): + """Hidden code block is Hidden""" + + option_spec = dict(starthidden=nice_bool, + label=str, + **CodeBlock.option_spec) + + def run(self): + # Body of the method is more or less copied from CodeBlock + code = u'\n'.join(self.content) + hcb = hidden_code_block(code, code) + hcb['language'] = self.arguments[0] + hcb['linenos'] = 'linenos' in self.options + hcb['starthidden'] = self.options.get('starthidden', True) + hcb['label'] = self.options.get('label', '+ show/hide code') + hcb.line = self.lineno + return [hcb] + + +def visit_hcb_html(self, node): + """Visit hidden code block""" + global HCB_COUNTER + HCB_COUNTER += 1 + + # We want to use the original highlighter so that we don't + # have to reimplement it. However it raises a SkipNode + # error at the end of the function call. Thus we intercept + # it and raise it again later. + try: + self.visit_literal_block(node) + except nodes.SkipNode: + pass + + # The last element of the body should be the literal code + # block that was just made. + code_block = self.body[-1] + + fill_header = {'divname': 'hiddencodeblock{0}'.format(HCB_COUNTER), + 'startdisplay': 'none' if node['starthidden'] else 'block', + 'label': node.get('label'), + } + + divheader = ("""""" + """{label}
""" + '''
''' + ).format(**fill_header) + + code_block = js_showhide + divheader + code_block + "
" + + # reassign and exit + self.body[-1] = code_block + raise nodes.SkipNode + + +def depart_hcb_html(self, node): + """Depart hidden code block""" + # Stub because of SkipNode in visit + + +def setup(app): + app.add_directive('hidden-code-block', HiddenCodeBlock) + app.add_node(hidden_code_block, html=(visit_hcb_html, depart_hcb_html)) diff --git a/docs/source/conf.py b/docs/source/conf.py index d335a48c0e..9f3d260b78 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -13,8 +13,10 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # import os, subprocess -# import sys -# sys.path.insert(0, os.path.abspath('.')) + +# Search for our extensions too +import sys +sys.path.append(os.path.abspath('_ext')) # -- Project information ----------------------------------------------------- @@ -44,6 +46,7 @@ extensions = [ # 'sphinx.ext.ifconfig', 'breathe', 'exhale', + 'hidden_code_block', ] todo_include_todos = True