diff --git a/MANIFEST.in b/MANIFEST.in index 00b80a8..9bbfe95 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,4 +5,5 @@ recursive-include ipypublish *.json recursive-include ipypublish *.j2 recursive-include ipypublish *.yaml recursive-include ipypublish/sphinx/notebook/css *.css +recursive-include ipypublish/sphinx/notebook/js *.js include ipypublish/tests/test_files/example.jpg diff --git a/docs/source/releases.rst b/docs/source/releases.rst index 7e6e805..6236c44 100644 --- a/docs/source/releases.rst +++ b/docs/source/releases.rst @@ -13,6 +13,12 @@ Releases Version 0.10 ------------ +v0.10.6 +~~~~~~~ + +Added sphinx option for toggling code cells; +see :ref:`sphinx_ext_notebook_toggle_in` example. + v0.10.5 ~~~~~~~ diff --git a/docs/source/sphinx_ext_notebook.rst b/docs/source/sphinx_ext_notebook.rst index 791bd28..d36ed4b 100644 --- a/docs/source/sphinx_ext_notebook.rst +++ b/docs/source/sphinx_ext_notebook.rst @@ -110,22 +110,27 @@ setup by adding to the conf.py: .. table:: Configuration values to use in conf.py :name: tbl:sphinx_config - ============================= =========================== ================================================================== + ============================= =========================== =================================================================== Name Default Description - ============================= =========================== ================================================================== + ============================= =========================== =================================================================== ipysphinx_export_config "sphinx_ipypublish_all.ext" ipypublish configuration file to use for conversion to .rst ipysphinx_folder_suffix "_nbfiles" for dumping internal images, etc ipysphinx_overwrite_existing False raise error if nb_name.rst already exists ipysphinx_config_folders () additional folders containing ipypublish configuration files ipysphinx_show_prompts False show cell prompts - ipysphinx_input_prompt "[{count}]:" format of input prompts - ipysphinx_output_prompt "[{count}]:" format of output prompts + ipysphinx_input_prompt "[{count}]:" format of input prompts + ipysphinx_output_prompt "[{count}]:" format of output prompts + ipysphinx_code_toggle False add a button at the right side of input cells, to toggle show/hide + ipysphinx_code_hide False for input cells with a toggle, whether to initialise them as hidden ipysphinx_preconverters {} a mapping of additional file extensions to preconversion functions - ============================= =========================== ================================================================== + ============================= =========================== =================================================================== Examples -------- +Basic input +~~~~~~~~~~~ + .. code-block:: rst .. nbinput:: python @@ -142,6 +147,10 @@ Examples print("hallo") + +Basic output +~~~~~~~~~~~~ + .. code-block:: rst .. nboutput:: @@ -154,6 +163,36 @@ Examples hallo +.. _sphinx_ext_notebook_toggle_in: + +Toggle input +~~~~~~~~~~~~ + +.. code-block:: rst + + .. nbinput:: python + :add-toggle: + :execution-count: 3 + + j = 0 + for i in range(3): + print(i) + j += i + print(j) + +.. nbinput:: python + :add-toggle: + :execution-count: 3 + + j = 0 + for i in range(3): + print(i) + j += i + print(j) + +Information and Warnings +~~~~~~~~~~~~~~~~~~~~~~~~ + .. code-block:: rst .. nbinfo:: Some information @@ -165,4 +204,3 @@ Examples .. nbwarning:: This is a warning .. nbwarning:: This is a warning - diff --git a/ipypublish/__init__.py b/ipypublish/__init__.py index 72281de..b8dd118 100644 --- a/ipypublish/__init__.py +++ b/ipypublish/__init__.py @@ -1,3 +1,3 @@ from ipypublish.scripts import nb_setup # noqa: F401 -__version__ = '0.10.5' +__version__ = '0.10.6' diff --git a/ipypublish/sphinx/notebook/css/nb_cells.css b/ipypublish/sphinx/notebook/css/nb_cells.css index 29dc42b..e78dd5e 100644 --- a/ipypublish/sphinx/notebook/css/nb_cells.css +++ b/ipypublish/sphinx/notebook/css/nb_cells.css @@ -202,4 +202,21 @@ div.rendered_html tbody tr:hover { background: rgba(66, 165, 245, 0.2); } - +.toggle-nbinput { + min-width: 2ex; + padding-top: 0.4em; + padding-left: 0.1em; + text-align: right; + flex: 0; + margin-left:auto; + margin-right:0; +} +.toggle-nbinput p { + overflow: hidden; +} +.toggle-nbinput:after { + content: " ▼"; +} +.toggle-nbinput.open:after { + content: " ▲"; +} diff --git a/ipypublish/sphinx/notebook/directives.py b/ipypublish/sphinx/notebook/directives.py index b736326..85e10d8 100644 --- a/ipypublish/sphinx/notebook/directives.py +++ b/ipypublish/sphinx/notebook/directives.py @@ -7,9 +7,7 @@ from docutils.statemachine import StringList from ipypublish.sphinx.utils import import_sphinx -from ipypublish.sphinx.notebook.nodes import ( - AdmonitionNode, CodeAreaNode, FancyOutputNode -) +from ipypublish.sphinx.notebook.nodes import (AdmonitionNode, CodeAreaNode, FancyOutputNode) class NbAdmonition(rst.Directive): @@ -51,13 +49,14 @@ class NbInput(rst.Directive): 'empty-lines-after': rst.directives.nonnegative_int, 'no-output': rst.directives.flag, 'caption': rst.directives.unchanged, - 'name': rst.directives.unchanged + 'name': rst.directives.unchanged, + 'add-toggle': rst.directives.flag } has_content = True def run(self): """This is called by the reST parser.""" - self.state.document['nbsphinx_include_css'] = True + self.state.document['ipysphinx_include_css'] = True return _create_nbcell_nodes(self) @@ -78,7 +77,7 @@ class NbOutput(rst.Directive): def run(self): """This is called by the reST parser.""" - self.state.document['nbsphinx_include_css'] = True + self.state.document['ipysphinx_include_css'] = True return _create_nbcell_nodes(self) @@ -114,15 +113,14 @@ def _create_nbcell_nodes(directive): if directive.arguments and directive.arguments[0] in ['rst', 'ansi']: fancy_output = True else: - raise AssertionError("directive should be NbInput or NbOutput") + raise AssertionError('directive should be NbInput or NbOutput') outer_node = docutils.nodes.container(classes=outer_classes) # add prompts if config.ipysphinx_show_prompts and execution_count: prompt = prompt_template.format(count=execution_count) - prompt_node = docutils.nodes.literal_block( - prompt, prompt, language='none', classes=['prompt']) + prompt_node = docutils.nodes.literal_block(prompt, prompt, language='none', classes=['prompt']) elif config.ipysphinx_show_prompts: prompt = '' prompt_node = docutils.nodes.container(classes=['prompt', 'empty']) @@ -132,21 +130,17 @@ def _create_nbcell_nodes(directive): if fancy_output: inner_node = docutils.nodes.container(classes=inner_classes) - sphinx.util.nodes.nested_parse_with_titles( - directive.state, directive.content, inner_node) + sphinx.util.nodes.nested_parse_with_titles(directive.state, directive.content, inner_node) outtype = directive.arguments[0] if outtype == 'rst': outer_node += FancyOutputNode('', inner_node, prompt=prompt) elif outtype == 'ansi': outer_node += inner_node else: - raise AssertionError( - "`.. nboutput:: type` should be 'rst' or 'ansi', " - "not: {}".format(outtype)) + raise AssertionError("`.. nboutput:: type` should be 'rst' or 'ansi', " 'not: {}'.format(outtype)) else: text = '\n'.join(directive.content.data) - inner_node = docutils.nodes.literal_block( - text, text, language=language, classes=inner_classes) + inner_node = docutils.nodes.literal_block(text, text, language=language, classes=inner_classes) codearea_node = CodeAreaNode('', inner_node, prompt=prompt) # create a literal text block (e.g. with the code-block directive), # that starts or ends with a blank line @@ -157,16 +151,19 @@ def _create_nbcell_nodes(directive): codearea_node[attr] = value # add caption and label, see: - if directive.options.get("caption", False): - caption = directive.options.get("caption") - wrapper = container_wrapper( - directive, inner_node, caption, inner_classes) + if directive.options.get('caption', False): + caption = directive.options.get('caption') + wrapper = container_wrapper(directive, inner_node, caption, inner_classes) # add label directive.add_name(wrapper) outer_node += wrapper else: outer_node += codearea_node + if isinstance(directive, NbInput) and (config.ipysphinx_code_toggle or 'add-toggle' in directive.options): + outer_node += sphinx.addnodes.only( + '', docutils.nodes.container(classes=['toggle-nbinput', 'empty']), expr='html') + return [outer_node] @@ -174,17 +171,14 @@ def container_wrapper(directive, literal_node, caption, classes): """adapted from https://github.com/sphinx-doc/sphinx/blob/master/sphinx/directives/code.py """ - container_node = docutils.nodes.container( - '', literal_block=True, classes=classes) # ['literal-block-wrapper'] + container_node = docutils.nodes.container('', literal_block=True, classes=classes) # ['literal-block-wrapper'] parsed = docutils.nodes.Element() - directive.state.nested_parse(StringList([caption], source=''), - directive.content_offset, parsed) + directive.state.nested_parse(StringList([caption], source=''), directive.content_offset, parsed) if isinstance(parsed[0], docutils.nodes.system_message): msg = 'Invalid caption: %s' % parsed[0].astext() raise ValueError(msg) elif isinstance(parsed[0], docutils.nodes.Element): - caption_node = docutils.nodes.caption(parsed[0].rawsource, '', - *parsed[0].children) + caption_node = docutils.nodes.caption(parsed[0].rawsource, '', *parsed[0].children) caption_node.source = literal_node.source caption_node.line = literal_node.line container_node += caption_node diff --git a/ipypublish/sphinx/notebook/extension.py b/ipypublish/sphinx/notebook/extension.py index 6ea9c2a..40a3389 100644 --- a/ipypublish/sphinx/notebook/extension.py +++ b/ipypublish/sphinx/notebook/extension.py @@ -1,16 +1,14 @@ +import io import os from docutils.parsers import rst -from six import string_types +import six from ipypublish import __version__ from ipypublish.sphinx.utils import import_sphinx -from ipypublish.sphinx.notebook.directives import ( - NbInfo, NbInput, NbOutput, NbWarning, - AdmonitionNode, CodeAreaNode, FancyOutputNode) -from ipypublish.sphinx.notebook.transforms import ( - CreateDomainObjectLabels, CreateSectionLabels, RewriteLocalLinks -) +from ipypublish.sphinx.notebook.directives import (NbInfo, NbInput, NbOutput, NbWarning, AdmonitionNode, CodeAreaNode, + FancyOutputNode) +from ipypublish.sphinx.notebook.transforms import (CreateDomainObjectLabels, CreateSectionLabels, RewriteLocalLinks) from ipypublish.sphinx.notebook.parser import NBParser try: @@ -63,13 +61,11 @@ def add_transform(transform, post=False): associate_single_extension(app, '.ipynb', called_from_setup=True) # config for export config - app.add_config_value( - 'ipysphinx_export_config', 'sphinx_ipypublish_all.ext', rebuild='env') + app.add_config_value('ipysphinx_export_config', 'sphinx_ipypublish_all.ext', rebuild='env') # config for contolling conversion process # where to dump internal images, etc of the notebook - app.add_config_value( - 'ipysphinx_folder_suffix', "_nbfiles", rebuild='env') + app.add_config_value('ipysphinx_folder_suffix', '_nbfiles', rebuild='env') # whether to raise error if nb_name.rst already exists app.add_config_value('ipysphinx_overwrite_existing', False, rebuild='env') # additional folders containing conversion files @@ -77,10 +73,12 @@ def add_transform(transform, post=False): # config for cell prompts app.add_config_value('ipysphinx_show_prompts', False, rebuild='env') - app.add_config_value( - 'ipysphinx_input_prompt', '[{count}]:', rebuild='env') - app.add_config_value( - 'ipysphinx_output_prompt', '[{count}]:', rebuild='env') + app.add_config_value('ipysphinx_input_prompt', '[{count}]:', rebuild='env') + app.add_config_value('ipysphinx_output_prompt', '[{count}]:', rebuild='env') + + # config for input cell toggling + app.add_config_value('ipysphinx_code_toggle', False, rebuild='env') + app.add_config_value('ipysphinx_code_hide', False, rebuild='env') # config for html css app.add_config_value('ipysphinx_responsive_width', '540px', rebuild='html') @@ -88,6 +86,8 @@ def add_transform(transform, post=False): # setup html style app.connect('builder-inited', set_css_prompts) app.connect('html-page-context', html_add_css) + # add javascript + app.connect('html-page-context', html_add_javascript) # config for additions to the output rst (per file) # these strings are processed by the exporters jinja template @@ -106,41 +106,37 @@ def add_transform(transform, post=False): app.add_directive('nbwarning', NbWarning) # add docutils nodes and visit/depart wraps - app.add_node(CodeAreaNode, - html=( - lambda self, node: None, - depart_codearea_html - ), - # latex=( - # lambda self, node: self.pushbody([]), # used in depart - # lambda self, node: None, - # ) - ) - app.add_node(FancyOutputNode, - html=( - lambda self, node: None, - lambda self, node: None, - ), - # latex=( - # lambda self, node: None, - # lambda self, node: None, - # ) - ) - app.add_node(AdmonitionNode, - html=( - visit_admonition_html, - lambda self, node: - self.body.append('\n') - ), - # latex=( - # lambda self, node: - # self.body.append( - # '\n\\begin{{sphinxadmonition}}{{{class}}}' - # '{{}}\\unskip'.format(node['classes'][1])), - # lambda self, node: - # self.body.append('\\end{sphinxadmonition}\n') - # ) - ) + app.add_node( + CodeAreaNode, + html=(lambda self, node: None, depart_codearea_html), + # latex=( + # lambda self, node: self.pushbody([]), # used in depart + # lambda self, node: None, + # ) + ) + app.add_node( + FancyOutputNode, + html=( + lambda self, node: None, + lambda self, node: None, + ), + # latex=( + # lambda self, node: None, + # lambda self, node: None, + # ) + ) + app.add_node( + AdmonitionNode, + html=(visit_admonition_html, lambda self, node: self.body.append('\n')), + # latex=( + # lambda self, node: + # self.body.append( + # '\n\\begin{{sphinxadmonition}}{{{class}}}' + # '{{}}\\unskip'.format(node['classes'][1])), + # lambda self, node: + # self.body.append('\\end{sphinxadmonition}\n') + # ) + ) # add transformations add_transform(CreateSectionLabels) @@ -150,14 +146,12 @@ def add_transform(transform, post=False): # Work-around until https://github.com/sphinx-doc/sphinx/pull/5504 is done: mathjax_config = app.config._raw_config.setdefault('mathjax_config', {}) mathjax_config.setdefault( - 'tex2jax', - { + 'tex2jax', { 'inlineMath': [['$', '$'], ['\\(', '\\)']], 'processEscapes': True, 'ignoreClass': 'document', 'processClass': 'math|output_area', - } - ) + }) # Make docutils' "code" directive (generated by markdown2rst/pandoc) # behave like Sphinx's "code-block", @@ -174,13 +168,10 @@ def add_transform(transform, post=False): def associate_extensions(app): for suffix in app.config.ipysphinx_preconverters: - associate_single_extension(app, suffix, - config_value="ipysphinx_preconverters") + associate_single_extension(app, suffix, config_value='ipysphinx_preconverters') -def associate_single_extension(app, extension, suffix='jupyter_notebook', - called_from_setup=False, - config_value=None): +def associate_single_extension(app, extension, suffix='jupyter_notebook', called_from_setup=False, config_value=None): # type: (Sphinx, str) -> None """ associate a file extension with the NBParser @@ -192,11 +183,10 @@ def associate_single_extension(app, extension, suffix='jupyter_notebook', See also https://github.com/sphinx-doc/sphinx/issues/2162. """ - if not isinstance(extension, string_types): - raise AssertionError("extension is not a string: {}".format(extension)) - if not extension.startswith("."): - raise AssertionError( - "extension should start with a '.': {}".format(extension)) + if not isinstance(extension, six.string_types): + raise AssertionError('extension is not a string: {}'.format(extension)) + if not extension.startswith('.'): + raise AssertionError("extension should start with a '.': {}".format(extension)) sphinx = import_sphinx() @@ -208,11 +198,10 @@ def associate_single_extension(app, extension, suffix='jupyter_notebook', if not called_from_setup: # too late to set up, see # https://github.com/sphinx-doc/sphinx/issues/2162#issuecomment-169193107 - raise sphinx.errors.ExtensionError( - "Using sphinx<1.8, {0} cannot be used.\n" - "Instead use: source_parsers = " - "{{'{1}': 'ipypublish.ipysphinx.parser.NBParser'}} " - "in conf.py".format(config_value, extension)) + raise sphinx.errors.ExtensionError('Using sphinx<1.8, {0} cannot be used.\n' + 'Instead use: source_parsers = ' + "{{'{1}': 'ipypublish.ipysphinx.parser.NBParser'}} " + 'in conf.py'.format(config_value, extension)) source_suffix = app.config._raw_config.get('source_suffix', ['.rst']) @@ -223,13 +212,11 @@ def associate_single_extension(app, extension, suffix='jupyter_notebook', app.config._raw_config['source_suffix'] = source_suffix source_parsers = app.config._raw_config.get('source_parsers', {}) - if (extension not in source_parsers - and extension[1:] not in source_parsers): + if (extension not in source_parsers and extension[1:] not in source_parsers): source_parsers[extension] = NBParser app.config._raw_config['source_parsers'] = source_parsers - sphinx.util.logging.getLogger('nbparser').info( - "ipypublish: associated {} with NBParser".format(extension)) + sphinx.util.logging.getLogger('nbparser').info('ipypublish: associated {} with NBParser'.format(extension)) def visit_admonition_html(self, node): @@ -245,17 +232,14 @@ def visit_admonition_html(self, node): def depart_codearea_html(self, node): """Add empty lines before and after the code.""" text = self.body[-1] - text = text.replace('
',
-                        '
\n' + '\n' * node.get('empty-lines-before', 0))
-    text = text.replace('
', - '\n' * node.get('empty-lines-after', 0) + '
') + text = text.replace('
', '
\n' + '\n' * node.get('empty-lines-before', 0))
+    text = text.replace('
', '\n' * node.get('empty-lines-after', 0) + '
') self.body[-1] = text def read_css(name): - folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), - "css") - with open(os.path.join(folder, name + ".css")) as fobj: + folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'css') + with io.open(os.path.join(folder, name + '.css')) as fobj: content = fobj.read() return content @@ -285,7 +269,7 @@ def set_css_prompts(app): def html_add_css(app, pagename, templatename, context, doctree): """Add CSS string to HTML pages that contain code cells.""" style = '' - if doctree and doctree.get('nbsphinx_include_css'): + if doctree and doctree.get('ipysphinx_include_css'): style += read_css('nb_cells') % app.config if doctree and app.config.html_theme in ('sphinx_rtd_theme', 'julia'): style += read_css('sphinx_rtd_theme') @@ -293,3 +277,21 @@ def html_add_css(app, pagename, templatename, context, doctree): style += read_css('cloud_theme') if style: context['body'] = '\n\n' + context['body'] + + +def copy_javascript(name): + folder = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'js') + with open(os.path.join(folder, name + '.js')) as fobj: + content = fobj.read() + + return content + + +def html_add_javascript(app, pagename, templatename, context, doctree): + """Add JavaScript string to HTML pages that contain code cells.""" + if doctree and doctree.get('ipysphinx_include_css'): + if app.config.ipysphinx_code_hide: + code = copy_javascript('toggle_code_hide') + else: + code = copy_javascript('toggle_code_show') + context['body'] = '\n\n' + context['body'] diff --git a/ipypublish/sphinx/notebook/js/toggle_code_hide.js b/ipypublish/sphinx/notebook/js/toggle_code_hide.js new file mode 100644 index 0000000..cb8812f --- /dev/null +++ b/ipypublish/sphinx/notebook/js/toggle_code_hide.js @@ -0,0 +1,9 @@ +$(function() { + + $(".input_area").hide(); + $(".toggle-nbinput").click(function () { + $(this).toggleClass("open"); + $(this).prev(".input_area").toggle("400"); + }); + +}); diff --git a/ipypublish/sphinx/notebook/js/toggle_code_show.js b/ipypublish/sphinx/notebook/js/toggle_code_show.js new file mode 100644 index 0000000..aa8da32 --- /dev/null +++ b/ipypublish/sphinx/notebook/js/toggle_code_show.js @@ -0,0 +1,10 @@ + +$(function () { + + $(".input_area").show(); + $(".toggle-nbinput").click(function () { + $(this).toggleClass("open"); + $(this).prev(".input_area").toggle("400"); + }); + +}); diff --git a/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py new file mode 100644 index 0000000..5bfe1a0 --- /dev/null +++ b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/conf.py @@ -0,0 +1,8 @@ +extensions = [ + 'ipypublish.sphinx.notebook', +] +exclude_patterns = ['_build'] +master_doc = 'contents' +ipysphinx_show_prompts = True +ipysphinx_code_toggle = True +ipysphinx_code_hide = True diff --git a/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst new file mode 100644 index 0000000..462942d --- /dev/null +++ b/ipypublish/sphinx/tests/sourcedirs/notebook_cell_decor/contents.rst @@ -0,0 +1,37 @@ +.. nbinput:: ipython3 + :execution-count: 3 + :no-output: + + Image('example.jpg',height=400) + + +.. nboutput:: rst + + .. table:: An example of a table created with pandas dataframe. + :name: tbl:example + + == ============== = ===== ===== + \ a b c d + == ============== = ===== ===== + 1 x m 0.914 0.021 + 2 y n 0.333 0.116 + == ============== = ===== ===== + + +.. nboutput:: ansi + + .. rst-class:: highlight + + .. raw:: html + +
+
+        This is some printed text,
+        with a nicely formatted output.
+
+        
+ + .. raw:: latex + + This is some printed text, + with a nicely formatted output. diff --git a/ipypublish/sphinx/tests/test_notebook.py b/ipypublish/sphinx/tests/test_notebook.py index f4a5558..3d0b740 100644 --- a/ipypublish/sphinx/tests/test_notebook.py +++ b/ipypublish/sphinx/tests/test_notebook.py @@ -30,3 +30,22 @@ def test_basic(app, status, warning, get_sphinx_app_output, data_regression): data_regression.check(parser.parsed, basename='test_basic_v2') else: data_regression.check(parser.parsed, basename='test_basic_v1') + + +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('notebook_cell_decor')) +def test_cell_decoration(app, status, warning, get_sphinx_app_output, data_regression): + """ test a notebook with prompts and toggle buttons""" + app.build() + + assert 'build succeeded' in status.getvalue() # Build succeeded + warnings = warning.getvalue().strip() + assert warnings == '' + + output = get_sphinx_app_output(app, buildername='html') + + parser = HTML2JSONParser() + parser.feed(output) + if sphinx.version_info >= (2,): + data_regression.check(parser.parsed, basename='test_cell_decoration_v2') + else: + data_regression.check(parser.parsed, basename='test_cell_decoration_v1') diff --git a/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml new file mode 100644 index 0000000..e4e915c --- /dev/null +++ b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v1.yml @@ -0,0 +1,300 @@ +4_children: +- 1_tag: html + 3_attributes: + xmlns: http://www.w3.org/1999/xhtml + 4_children: + - 1_tag: body + 4_children: + - 1_tag: div + 3_attributes: + class: + - document + 4_children: + - 1_tag: div + 3_attributes: + class: + - documentwrapper + 4_children: + - 1_tag: div + 3_attributes: + class: + - bodywrapper + 4_children: + - 1_tag: div + 3_attributes: + class: + - body + role: main + 4_children: + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - nbinput + - nblast + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight-none + - notranslate + - prompt + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight + 4_children: + - 1_tag: pre + 2_data: + - '[3]:' + 4_children: + - 1_tag: span + - 1_tag: div + 3_attributes: + class: + - highlight-ipython3 + - input_area + - notranslate + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight + 4_children: + - 1_tag: pre + 4_children: + - 1_tag: span + - 1_tag: span + 2_data: + - Image + 3_attributes: + class: + - n + - 1_tag: span + 2_data: + - ( + 3_attributes: + class: + - p + - 1_tag: span + 2_data: + - example.jpg + 3_attributes: + class: + - s1 + - 1_tag: span + 2_data: + - ',' + 3_attributes: + class: + - p + - 1_tag: span + 2_data: + - height + 3_attributes: + class: + - n + - 1_tag: span + 2_data: + - '=' + 3_attributes: + class: + - o + - 1_tag: span + 2_data: + - '400' + 3_attributes: + class: + - mi + - 1_tag: span + 2_data: + - ) + 3_attributes: + class: + - p + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - empty + - toggle-nbinput + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - nblast + - nboutput + 4_children: + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - empty + - prompt + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - output_area + 4_children: + - 1_tag: table + 3_attributes: + border: '1' + class: + - docutils + id: tbl-example + 4_children: + - 1_tag: caption + 4_children: + - 1_tag: span + 2_data: + - An example of a table created with pandas dataframe. + 3_attributes: + class: + - caption-text + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#tbl-example' + title: Permalink to this table + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + width: 7% + - 1_tag: col + 3_attributes: + width: 52% + - 1_tag: col + 3_attributes: + width: 4% + - 1_tag: col + 3_attributes: + width: 19% + - 1_tag: col + 3_attributes: + width: 19% + - 1_tag: thead + 3_attributes: + valign: bottom + 4_children: + - 1_tag: tr + 3_attributes: + class: + - row-odd + 4_children: + - 1_tag: th + 3_attributes: + class: + - head + - 1_tag: th + 2_data: + - a + 3_attributes: + class: + - head + - 1_tag: th + 2_data: + - b + 3_attributes: + class: + - head + - 1_tag: th + 2_data: + - c + 3_attributes: + class: + - head + - 1_tag: th + 2_data: + - d + 3_attributes: + class: + - head + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 3_attributes: + class: + - row-even + 4_children: + - 1_tag: td + 2_data: + - '1' + - 1_tag: td + 2_data: + - x + - 1_tag: td + 2_data: + - m + - 1_tag: td + 2_data: + - '0.914' + - 1_tag: td + 2_data: + - '0.021' + - 1_tag: tr + 3_attributes: + class: + - row-odd + 4_children: + - 1_tag: td + 2_data: + - '2' + - 1_tag: td + 2_data: + - y + - 1_tag: td + 2_data: + - n + - 1_tag: td + 2_data: + - '0.333' + - 1_tag: td + 2_data: + - '0.116' + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - nblast + - nboutput + 4_children: + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - empty + - prompt + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - output_area + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight + 4_children: + - 1_tag: pre + 2_data: + - '' + - '' + - This is some printed text, + - with a nicely formatted output. + - '' diff --git a/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml new file mode 100644 index 0000000..58ec628 --- /dev/null +++ b/ipypublish/sphinx/tests/test_notebook/test_cell_decoration_v2.yml @@ -0,0 +1,326 @@ +4_children: +- 1_tag: html + 3_attributes: + xmlns: http://www.w3.org/1999/xhtml + 4_children: + - 1_tag: body + 4_children: + - 1_tag: div + 3_attributes: + class: + - document + 4_children: + - 1_tag: div + 3_attributes: + class: + - documentwrapper + 4_children: + - 1_tag: div + 3_attributes: + class: + - bodywrapper + 4_children: + - 1_tag: div + 3_attributes: + class: + - body + role: main + 4_children: + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - nbinput + - nblast + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight-none + - notranslate + - prompt + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight + 4_children: + - 1_tag: pre + 2_data: + - '[3]:' + 4_children: + - 1_tag: span + - 1_tag: div + 3_attributes: + class: + - highlight-ipython3 + - input_area + - notranslate + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight + 4_children: + - 1_tag: pre + 4_children: + - 1_tag: span + - 1_tag: span + 2_data: + - Image + 3_attributes: + class: + - n + - 1_tag: span + 2_data: + - ( + 3_attributes: + class: + - p + - 1_tag: span + 2_data: + - example.jpg + 3_attributes: + class: + - s1 + - 1_tag: span + 2_data: + - ',' + 3_attributes: + class: + - p + - 1_tag: span + 2_data: + - height + 3_attributes: + class: + - n + - 1_tag: span + 2_data: + - '=' + 3_attributes: + class: + - o + - 1_tag: span + 2_data: + - '400' + 3_attributes: + class: + - mi + - 1_tag: span + 2_data: + - ) + 3_attributes: + class: + - p + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - empty + - toggle-nbinput + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - nblast + - nboutput + 4_children: + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - empty + - prompt + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - output_area + 4_children: + - 1_tag: table + 3_attributes: + class: + - align-default + - docutils + id: tbl-example + 4_children: + - 1_tag: caption + 4_children: + - 1_tag: span + 2_data: + - An example of a table created with pandas dataframe. + 3_attributes: + class: + - caption-text + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#tbl-example' + title: Permalink to this table + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + style: 'width: 7%' + - 1_tag: col + 3_attributes: + style: 'width: 52%' + - 1_tag: col + 3_attributes: + style: 'width: 4%' + - 1_tag: col + 3_attributes: + style: 'width: 19%' + - 1_tag: col + 3_attributes: + style: 'width: 19%' + - 1_tag: thead + 4_children: + - 1_tag: tr + 3_attributes: + class: + - row-odd + 4_children: + - 1_tag: th + 3_attributes: + class: + - head + 4_children: + - 1_tag: p + - 1_tag: th + 3_attributes: + class: + - head + 4_children: + - 1_tag: p + 2_data: + - a + - 1_tag: th + 3_attributes: + class: + - head + 4_children: + - 1_tag: p + 2_data: + - b + - 1_tag: th + 3_attributes: + class: + - head + 4_children: + - 1_tag: p + 2_data: + - c + - 1_tag: th + 3_attributes: + class: + - head + 4_children: + - 1_tag: p + 2_data: + - d + - 1_tag: tbody + 4_children: + - 1_tag: tr + 3_attributes: + class: + - row-even + 4_children: + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - '1' + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - x + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - m + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - '0.914' + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - '0.021' + - 1_tag: tr + 3_attributes: + class: + - row-odd + 4_children: + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - '2' + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - y + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - n + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - '0.333' + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - '0.116' + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - nblast + - nboutput + 4_children: + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - empty + - prompt + - 1_tag: div + 3_attributes: + class: + - container + - docutils + - output_area + 4_children: + - 1_tag: div + 3_attributes: + class: + - highlight + 4_children: + - 1_tag: pre + 2_data: + - '' + - '' + - This is some printed text, + - with a nicely formatted output. + - ''