From 8b4f1ac2fe129a19373aec2597fd66deb89898c1 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 23 Jul 2019 07:16:14 +0100 Subject: [PATCH] Remove restriction on Sphinx<2.0 (#92) Changes include: - implement `HTML2JSONParser` and `pytest-regressions` for testing HTML documents Rather then searching for specific bits of text, we convert the document to a json object, stripping out sections irrelevant for testing (like the header, footer and scripts that can change between versions). and test with the `data_regression` fixture - Add pre_commit configuration - Update .travis.yml to test python 3.7 rather than 3.4 (which is deprecated) - Update RTD configuration - version bump fixes #76 --- .flake8 | 1 + .pre-commit-config.yaml | 39 +++ .style.yapf | 3 + .travis.yml | 98 +++--- .vscode/settings.json | 8 +- clean.sh | 5 + conda_dev_env.yaml | 50 +++ docs/environment.yaml | 7 +- docs/source/releases.rst | 43 ++- ipypublish/__init__.py | 2 +- ipypublish/convert/main.py | 2 +- .../tests/test_prepare_cites.py | 177 +++++------ .../test_prepare_cites/test_image_html.yml | 34 +++ .../test_prepare_cites/test_para_html.yml | 43 +++ .../test_prepare_cites/test_table_html.yml | 47 +++ ipypublish/sphinx/gls/processing.py | 27 +- ipypublish/sphinx/tests/test_bibgloss.py | 148 +++------ .../tests/test_bibgloss/test_basic_v1.yml | 278 +++++++++++++++++ .../tests/test_bibgloss/test_basic_v2.yml | 252 +++++++++++++++ .../tests/test_bibgloss/test_sortkeys_v1.yml | 227 ++++++++++++++ .../tests/test_bibgloss/test_sortkeys_v2.yml | 205 +++++++++++++ .../tests/test_bibgloss/test_unsorted_v1.yml | 226 ++++++++++++++ .../tests/test_bibgloss/test_unsorted_v2.yml | 199 ++++++++++++ ipypublish/sphinx/tests/test_notebook.py | 29 +- .../tests/test_notebook/test_basic_v1.yml | 262 ++++++++++++++++ .../tests/test_notebook/test_basic_v2.yml | 288 ++++++++++++++++++ ipypublish/tests/utils.py | 136 +++++++++ requirements-lock.txt | 41 --- requirements.txt | 3 +- setup.py | 62 ++-- 30 files changed, 2576 insertions(+), 366 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100644 .style.yapf create mode 100755 clean.sh create mode 100644 conda_dev_env.yaml create mode 100644 ipypublish/filters_pandoc/tests/test_prepare_cites/test_image_html.yml create mode 100644 ipypublish/filters_pandoc/tests/test_prepare_cites/test_para_html.yml create mode 100644 ipypublish/filters_pandoc/tests/test_prepare_cites/test_table_html.yml create mode 100644 ipypublish/sphinx/tests/test_bibgloss/test_basic_v1.yml create mode 100644 ipypublish/sphinx/tests/test_bibgloss/test_basic_v2.yml create mode 100644 ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v1.yml create mode 100644 ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v2.yml create mode 100644 ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v1.yml create mode 100644 ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v2.yml create mode 100644 ipypublish/sphinx/tests/test_notebook/test_basic_v1.yml create mode 100644 ipypublish/sphinx/tests/test_notebook/test_basic_v2.yml create mode 100644 ipypublish/tests/utils.py delete mode 100644 requirements-lock.txt diff --git a/.flake8 b/.flake8 index e9008a6..884318a 100644 --- a/.flake8 +++ b/.flake8 @@ -1,4 +1,5 @@ [flake8] +max-line-length = 120 exclude = setup.py, ipypublish/scripts/ipynb_latex_setup.py, diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9491db8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,39 @@ +# Install pre-commit hooks via +# pre-commit install + +- repo: git://github.com/pre-commit/pre-commit-hooks + sha: v2.2.3 + hooks: + - id: check-json + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - id: double-quote-string-fixer + - id: flake8 + +- repo: local + hooks: + + - id: yapf + name: Yet Another Python Formatter + entry: yapf + language: system + types: [python] + args: ["-i", "-vv"] + exclude: > + (?x)^( + setup.py + )$ + + - id: doc8 + name: RST Linting + entry: doc8 + language: system + types: [rst] + + # - id: travis-linter + # name: Travis Lint + # entry: travis lint + # files: .travis.yml + # language: ruby + # additional_dependencies: ['travis'] diff --git a/.style.yapf b/.style.yapf new file mode 100644 index 0000000..b3d849f --- /dev/null +++ b/.style.yapf @@ -0,0 +1,3 @@ +[style] +based_on_style = google +column_limit = 120 diff --git a/.travis.yml b/.travis.yml index 8ee3454..69ae187 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,65 +23,66 @@ matrix: env: TEST_TYPE="pytest" - os: linux sudo: required - python: 3.4 + python: 3.5 dist: trusty env: TEST_TYPE="pytest" - os: linux sudo: required - python: 3.5 - dist: trusty - env: TEST_TYPE="pytest" - - os: osx - language: generic + python: 3.7 + dist: xenial env: TEST_TYPE="pytest" - before_install: - - travis_wait brew update - # TODO currently by default python 2.7 is already installed (see https://github.com/travis-ci/travis-ci/issues/9929) - # - brew install python3 - # - brew upgrade python - # - pip install virtualenv - # - virtualenv env -p python3 - # - source env/bin/activate - # - alias pip="pip3" - - brew install pandoc - - brew upgrade wget - - travis_retry sudo wget http://mirror.ctan.org/systems/mac/mactex/BasicTeX.pkg - -O BasicTeX.pkg - - sudo installer -pkg BasicTeX.pkg -target / - - export PATH=$PATH:/usr/texbin:/Library/TeX/texbin - - travis_retry sudo tlmgr update --self - - travis_retry sudo tlmgr install babel - - travis_retry sudo tlmgr install translations - - travis_retry sudo tlmgr install latexmk - - travis_retry sudo tlmgr install adjustbox - - travis_retry sudo tlmgr install collectbox - - travis_retry sudo tlmgr install ucs - - travis_retry sudo tlmgr install enumitem - - travis_retry sudo tlmgr install placeins - - travis_retry sudo tlmgr install todonotes - - travis_retry sudo tlmgr install chngcntr - - travis_retry sudo tlmgr install doi - - travis_retry sudo tlmgr install mdframed - - travis_retry sudo tlmgr install cleveref - - travis_retry sudo tlmgr install biblatex - - travis_retry sudo tlmgr install needspace - - travis_retry sudo tlmgr install collection-fontsrecommended - # glossaries dependencies - - travis_retry sudo tlmgr install glossaries # NB: for different languages glossaries- - - travis_retry sudo tlmgr install mfirstuc # see https://tex.stackexchange.com/questions/268216/usepackageglossaries-wont-work-after-miktex-update-reinstallation - - travis_retry sudo tlmgr install xfor - - travis_retry sudo tlmgr install datatool - - travis_retry sudo tlmgr install substr + # TODO this takes too long to install + # - os: osx + # language: generic + # env: TEST_TYPE="pytest" + # before_install: + # - travis_wait brew update + # # TODO currently by default python 2.7 is already installed (see https://github.com/travis-ci/travis-ci/issues/9929) + # # - brew install python3 + # # - brew upgrade python + # # - pip install virtualenv + # # - virtualenv env -p python3 + # # - source env/bin/activate + # # - alias pip="pip3" + # - brew install pandoc + # - brew upgrade wget + # - travis_retry sudo wget http://mirror.ctan.org/systems/mac/mactex/BasicTeX.pkg + # -O BasicTeX.pkg + # - sudo installer -pkg BasicTeX.pkg -target / + # - export PATH=$PATH:/usr/texbin:/Library/TeX/texbin + # - travis_retry sudo tlmgr update --self + # - travis_retry sudo tlmgr install babel + # - travis_retry sudo tlmgr install translations + # - travis_retry sudo tlmgr install latexmk + # - travis_retry sudo tlmgr install adjustbox + # - travis_retry sudo tlmgr install collectbox + # - travis_retry sudo tlmgr install ucs + # - travis_retry sudo tlmgr install enumitem + # - travis_retry sudo tlmgr install placeins + # - travis_retry sudo tlmgr install todonotes + # - travis_retry sudo tlmgr install chngcntr + # - travis_retry sudo tlmgr install doi + # - travis_retry sudo tlmgr install mdframed + # - travis_retry sudo tlmgr install cleveref + # - travis_retry sudo tlmgr install biblatex + # - travis_retry sudo tlmgr install needspace + # - travis_retry sudo tlmgr install collection-fontsrecommended + # # glossaries dependencies + # - travis_retry sudo tlmgr install glossaries # NB: for different languages glossaries- + # - travis_retry sudo tlmgr install mfirstuc # see https://tex.stackexchange.com/questions/268216/usepackageglossaries-wont-work-after-miktex-update-reinstallation + # - travis_retry sudo tlmgr install xfor + # - travis_retry sudo tlmgr install datatool + # - travis_retry sudo tlmgr install substr allow_failures: - os: linux sudo: required - python: 3.4 + python: 3.5 dist: trusty env: TEST_TYPE="pytest" - os: linux sudo: required - python: 3.5 - dist: trusty + python: 3.7 + dist: xenial env: TEST_TYPE="pytest" - os: osx language: generic @@ -113,6 +114,9 @@ before_install: sudo wget http://mirrors.ctan.org/install/macros/latex/contrib/koma-script.tds.zip sudo unzip koma-script.tds.zip -d ~/texmf/ sudo apt-get install -y latexmk + if [[ "$TRAVIS_DIST" == "xenial" ]]; then + sudo apt-get install -y texlive-generic-recommended + fi fi install: diff --git a/.vscode/settings.json b/.vscode/settings.json index acdfab6..010f705 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,7 +12,7 @@ "**/*.pyc": true, "**/__pycache__": true }, - "python.pythonPath": "/anaconda/envs/lsr/bin/python", + "python.pythonPath": "/anaconda/envs/ipypublish_dev/bin/python", "restructuredtext.confPath": "${workspaceFolder}/docs/source", "restructuredtext.builtDocumentationPath": "${workspaceFolder}/docs/build/html", "restructuredtext.preview.scrollEditorWithPreview": false, @@ -26,7 +26,7 @@ "python.linting.pylamaEnabled": false, "python.linting.enabled": true, "python.linting.flake8Enabled": true, - "latex-workshop.latex.autoBuild.onSave.enabled": false, + "python.formatting.provider": "yapf", "cSpell.words": [ "Jupyter", "docutils", @@ -65,7 +65,7 @@ "yaml.format.enable": true, "markdown-preview-enhanced.usePandocParser": true, - "markdown-preview-enhanced.pandocPath": "/anaconda/envs/lsr/bin/pandoc", - "markdown-preview-enhanced.pandocArguments": "--filter=/anaconda/envs/lsr/bin/ipubpandoc", + "markdown-preview-enhanced.pandocPath": "/anaconda/envs/ipypublish_dev/bin/pandoc", + "markdown-preview-enhanced.pandocArguments": "--filter=/anaconda/envs/ipypublish_dev/bin/ipubpandoc", "markdown-preview-enhanced.enableScriptExecution": true } \ No newline at end of file diff --git a/clean.sh b/clean.sh new file mode 100755 index 0000000..1e6f507 --- /dev/null +++ b/clean.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +find . -name "*.pyc" -delete; +find . -name "*.pyo" -delete; +find . -name "__pycache__" -delete; +find . -name ".pytest_cache" -delete; diff --git a/conda_dev_env.yaml b/conda_dev_env.yaml new file mode 100644 index 0000000..5176c78 --- /dev/null +++ b/conda_dev_env.yaml @@ -0,0 +1,50 @@ +# Usage: +# $ conda env create -n ipypublish_dev -f conda_dev_env.yaml +# $ conda activate ipypublish_dev +# $ pip install --no-deps -e . +--- +name: ipypublish_dev +channels: +- conda-forge +dependencies: +- pip +- python =3.6 + +- bibtexparser +- docutils +- jinja2 +- jsonextended >=0.7 +- jsonschema +- jupytext +- nbconvert +- nbformat +- ordered-set +- pandoc =2.6 +- panflute +- ruamel.yaml +- setuptools +- six +- sphinx >=1.6 +- sphinxcontrib-bibtex +- texsoup <0.2 +- tornado +- traitlets +# testing +- pytest >=3.6 +- pytest-regressions +- nbsphinx +- pillow +- ipykernel +# style +- autopep8 +- doc8 +- flake8 <3.8.0,>=3.7.0 +- rope +- pre_commit =1.14.4 +- yapf =0.26.0 +# docs +- sphinx_rtd_theme +- jupyter +- matplotlib +- pandas +- sympy <1.3 diff --git a/docs/environment.yaml b/docs/environment.yaml index 66a7291..b131b99 100644 --- a/docs/environment.yaml +++ b/docs/environment.yaml @@ -2,8 +2,5 @@ channels: - conda-forge dependencies: - python =3.6 - # TODO pip>=10 fails du to this issue https://github.com/pypa/pip/issues/5247 - # raises error `Cannot uninstall 'docutils'. It is a distutils installed project` - # even though docutils appear to already be at the correct version (0.14)!? - - pip <10.0 - - pandoc + - pandoc =2.6 + - docutils =0.15 diff --git a/docs/source/releases.rst b/docs/source/releases.rst index b92bfbb..7e6e805 100644 --- a/docs/source/releases.rst +++ b/docs/source/releases.rst @@ -13,6 +13,43 @@ Releases Version 0.10 ------------ +v0.10.5 +~~~~~~~ + +Remove requirement for sphinx < 2.0 + +v0.10.4 +~~~~~~~ + +Fix image reference clashes in rst files (see chrisjsewell/ipypublish#90) + +v0.10.3 +~~~~~~~ + +Minor Improvements to `ipypublish.sphinx.notebook`: + +- remove ``sphinx.ext.imgconverter`` from sphinx auto-builds +- add additional known sphinx roles + +v0.10.2 +~~~~~~~ + +Update dependency requirements: + +- Only require backport dependencies + for python version older than their implementation +- use ``ordered-set``, instead of ``oset`` dependency, + since it is better maintained + +v0.10.1 +~~~~~~~ + +Minor Improvements to `ipypublish.sphinx.notebook`: + +- Formatting of the execution_count is now inserted by: + ``ipysphinx_input_prompt.format(count=execution_count)`` +- Use "Code Cell Output" as placeholder for output image caption + v0.10.0 ~~~~~~~ @@ -29,7 +66,7 @@ v0.10.0 of Sphinx extensions (using the Sphinx pytest fixtures) and creation of the ``IpyTestApp`` fixture -- fixed `tornado version restriction `_ +- fixed `tornado version restriction `_ Back-compatibility breaking changes: @@ -38,7 +75,8 @@ Back-compatibility breaking changes: (see :ref:`sphinx_ext_notebook`) - :py:meth:`ipypublish.postprocessors.base.IPyPostProcessor.run_postprocess` - input signature changed (and consequently it has changes for all post-processors) + input signature changed + (and consequently it has changes for all post-processors) v0.9 @@ -302,4 +340,3 @@ Version 0.1 ----------- Initial release, before changing latex meta tag convention - diff --git a/ipypublish/__init__.py b/ipypublish/__init__.py index 8d1eab0..72281de 100644 --- a/ipypublish/__init__.py +++ b/ipypublish/__init__.py @@ -1,3 +1,3 @@ from ipypublish.scripts import nb_setup # noqa: F401 -__version__ = '0.10.4' +__version__ = '0.10.5' diff --git a/ipypublish/convert/main.py b/ipypublish/convert/main.py index 62f9358..9daeed6 100755 --- a/ipypublish/convert/main.py +++ b/ipypublish/convert/main.py @@ -43,7 +43,7 @@ class IpyPubMain(Configurable): ).tag(config=True) plugin_folder_paths = T.Set( - T.Unicode, + T.Unicode(), default_value=(), help="a list of folders containing conversion configurations" ).tag(config=True) diff --git a/ipypublish/filters_pandoc/tests/test_prepare_cites.py b/ipypublish/filters_pandoc/tests/test_prepare_cites.py index f9b6b49..9747f9c 100644 --- a/ipypublish/filters_pandoc/tests/test_prepare_cites.py +++ b/ipypublish/filters_pandoc/tests/test_prepare_cites.py @@ -1,108 +1,91 @@ -import sys -import pytest from ipypublish.filters_pandoc.utils import apply_filter from ipypublish.filters_pandoc.prepare_cites import main +from ipypublish.tests.utils import HTML2JSONParser def test_para_rst(): """ """ - in_string = [ - "+@label{.class a=1} xyz *@label2* @label3{.b}", - "", - "(@label4{})", - "", - "(@label5{.b} x)" - ] - out_string = apply_filter(in_string, main, "rst") - - assert out_string.strip() == "\n".join([ - "@label xyz *@label2* @label3", - "", - "(@label4)", - "", - "(@label5 x)" - ]) - - -@pytest.mark.skipif(sys.version_info < (3, 6), - reason="html attributes not in same order") -def test_para_html(): + in_string = ['+@label{.class a=1} xyz *@label2* @label3{.b}', '', '(@label4{})', '', '(@label5{.b} x)'] + out_string = apply_filter(in_string, main, 'rst') + + assert out_string.strip() == '\n'.join(['@label xyz *@label2* @label3', '', '(@label4)', '', '(@label5 x)']) + + +def test_para_html(data_regression): """ """ - in_string = [ - "+@label{ .class a=1} xyz *@label2* @label3{ .b}" - ] - out_string = apply_filter(in_string, main, "html") - - assert out_string.strip() == "\n".join([ - '

' - '' - '@label' - ' ' - 'xyz ' - '@label2 ' - '' - '@label3' - '' - '

', - ]) - - -@pytest.mark.skipif(sys.version_info < (3, 6), - reason="html attributes not in same order") -def test_table_html(): + in_string = ['+@label{ .class a=1} xyz *@label2* @label3{ .b}'] + out_string = apply_filter(in_string, main, 'html') + + parser = HTML2JSONParser() + parser.feed(out_string) + data_regression.check(parser.parsed) + + # assert out_string.strip() == "\n".join([ + # '

' + # '' + # '@label' + # ' ' + # 'xyz ' + # '@label2 ' + # '' + # '@label3' + # '' + # '

', + # ]) + + +def test_table_html(data_regression): """ """ - in_string = [ - "a b", - "- -", - "x y", - "", - "Table: Caption +@label" - ] - out_string = apply_filter(in_string, main, "html") - - assert out_string.strip() == "\n".join([ - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '
Caption ' - '' - '@label' - '
ab
xy
' - ]) - - -@pytest.mark.skipif(sys.version_info < (3, 6), - reason="html attributes not in same order") -def test_image_html(): - - in_string = [ - "![a title with a @label1 +@label2 {.nclass x=3}](path/to/image.png)" - ] - out_string = apply_filter(in_string, main, "html") - - assert out_string.strip() == "\n".join([ - '
', - 'a title with a @label1 @label2' - '
a title with a ' - '@label1 ' - '' - '@label2' - '
', - '
' - ]) + in_string = ['a b', '- -', 'x y', '', 'Table: Caption +@label'] + out_string = apply_filter(in_string, main, 'html') + + parser = HTML2JSONParser() + parser.feed(out_string) + data_regression.check(parser.parsed) + + # assert out_string.strip() == "\n".join([ + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '', + # '
Caption ' + # '' + # '@label' + # '
ab
xy
' + # ]) + + +def test_image_html(data_regression): + + in_string = ['![a title with a @label1 +@label2 {.nclass x=3}](path/to/image.png)'] + out_string = apply_filter(in_string, main, 'html') + + parser = HTML2JSONParser() + parser.feed(out_string) + data_regression.check(parser.parsed) + + # assert out_string.strip() == "\n".join([ + # '
', + # 'a title with a @label1 @label2' + # '
a title with a ' + # '@label1 ' + # '' + # '@label2' + # '
', + # '
' + # ]) diff --git a/ipypublish/filters_pandoc/tests/test_prepare_cites/test_image_html.yml b/ipypublish/filters_pandoc/tests/test_prepare_cites/test_image_html.yml new file mode 100644 index 0000000..84ad63c --- /dev/null +++ b/ipypublish/filters_pandoc/tests/test_prepare_cites/test_image_html.yml @@ -0,0 +1,34 @@ +4_children: +- 1_tag: figure + 4_children: + - 1_tag: img + 3_attributes: + alt: a title with a @label1 @label2 + src: path/to/image.png + - 1_tag: figcaption + 2_data: + - a title with a + 4_children: + - 1_tag: span + 2_data: + - '@label1' + 3_attributes: + class: + - citation + data-cites: label1 + - 1_tag: span + 3_attributes: + class: + - attribute-Cite + - nclass + data-latex: cref + data-rst: numref + data-x: '3' + 4_children: + - 1_tag: span + 2_data: + - '@label2' + 3_attributes: + class: + - citation + data-cites: label2 diff --git a/ipypublish/filters_pandoc/tests/test_prepare_cites/test_para_html.yml b/ipypublish/filters_pandoc/tests/test_prepare_cites/test_para_html.yml new file mode 100644 index 0000000..65c872e --- /dev/null +++ b/ipypublish/filters_pandoc/tests/test_prepare_cites/test_para_html.yml @@ -0,0 +1,43 @@ +4_children: +- 1_tag: p + 2_data: + - ' xyz' + 4_children: + - 1_tag: span + 3_attributes: + class: + - attribute-Cite + - class + data-a: '1' + data-latex: cref + data-rst: numref + 4_children: + - 1_tag: span + 2_data: + - '@label' + 3_attributes: + class: + - citation + data-cites: label + - 1_tag: em + 4_children: + - 1_tag: span + 2_data: + - '@label2' + 3_attributes: + class: + - citation + data-cites: label2 + - 1_tag: span + 3_attributes: + class: + - attribute-Cite + - b + 4_children: + - 1_tag: span + 2_data: + - '@label3' + 3_attributes: + class: + - citation + data-cites: label3 diff --git a/ipypublish/filters_pandoc/tests/test_prepare_cites/test_table_html.yml b/ipypublish/filters_pandoc/tests/test_prepare_cites/test_table_html.yml new file mode 100644 index 0000000..916dec2 --- /dev/null +++ b/ipypublish/filters_pandoc/tests/test_prepare_cites/test_table_html.yml @@ -0,0 +1,47 @@ +4_children: +- 1_tag: table + 4_children: + - 1_tag: caption + 2_data: + - Caption + 4_children: + - 1_tag: span + 3_attributes: + class: + - attribute-Cite + data-latex: cref + data-rst: numref + 4_children: + - 1_tag: span + 2_data: + - '@label' + 3_attributes: + class: + - citation + data-cites: label + - 1_tag: thead + 4_children: + - 1_tag: tr + 3_attributes: + class: + - header + 4_children: + - 1_tag: th + 2_data: + - a + - 1_tag: th + 2_data: + - b + - 1_tag: tbody + 4_children: + - 1_tag: tr + 3_attributes: + class: + - odd + 4_children: + - 1_tag: td + 2_data: + - x + - 1_tag: td + 2_data: + - y diff --git a/ipypublish/sphinx/gls/processing.py b/ipypublish/sphinx/gls/processing.py index 0e948d4..46d4611 100644 --- a/ipypublish/sphinx/gls/processing.py +++ b/ipypublish/sphinx/gls/processing.py @@ -15,7 +15,7 @@ def init_bibgloss_cache(app): :param app: The sphinx application. :type app: :class:`sphinx.application.Sphinx` """ - if not hasattr(app.env, "bibgloss_cache"): + if not hasattr(app.env, 'bibgloss_cache'): app.env.bibgloss_cache = Cache() @@ -40,14 +40,13 @@ def process_citations(app, doctree, docname): """ # citation(rawsource='', *children, **attributes) for node in doctree.traverse(docutils.nodes.citation): - if "bibglossary" not in node.attributes.get('classes', []): + if 'bibglossary' not in node.attributes.get('classes', []): continue key = node[0].astext() try: label_str = app.env.bibgloss_cache.get_label_from_key(key) except KeyError: - logger.warning("could not relabel glossary item [%s]" % key, - type="bibgloss", subtype="relabel") + logger.warning('could not relabel glossary item [%s]' % key, type='bibgloss', subtype='relabel') else: if app.config.bibgloss_convert_latex: label = latex_to_docutils(label_str) @@ -56,6 +55,10 @@ def process_citations(app, doctree, docname): else: node[0] = docutils.nodes.label('', label_str) + if sphinx.version_info >= (2,): + # this creates a line break between the label and the definition + node.insert(1, docutils.nodes.line()) + def process_citation_references(app, doctree, docname): """Replace text of citation reference nodes by actual labels. @@ -70,28 +73,30 @@ def process_citation_references(app, doctree, docname): # into reference nodes, so iterate over reference nodes # reference(rawsource='', text='', *children, **attributes) for node in doctree.traverse(docutils.nodes.reference): - if "bibglossary" not in node.attributes.get('classes', []): + if 'bibglossary' not in node.attributes.get('classes', []): continue text = node[0].astext() key = text[1:-1] try: - if "bibgplural" in node.attributes.get('classes', []): + if 'bibgplural' in node.attributes.get('classes', []): label = app.env.bibgloss_cache.get_plural_from_key(key) else: label = app.env.bibgloss_cache.get_label_from_key(key) except KeyError: pass - logger.warning( - "could not relabel glossary reference [%s]" % key, - type="bibgloss", subtype="relabel") + logger.warning('could not relabel glossary reference [%s]' % key, type='bibgloss', subtype='relabel') else: - if "bibgcapital" in node.attributes.get('classes', []): + if 'bibgcapital' in node.attributes.get('classes', []): label = label.capitalize() if app.config.bibgloss_convert_latex: # note we use only the first child of the document # TODO is this the best way to do this label = latex_to_docutils(label) - node[0] = label.children[0] + if sphinx.version_info < (2,): + node[0] = label.children[0] + else: + # in sphinx v2 the child is a paragraph + node[0] = label.children[0].children[0] else: node[0] = docutils.nodes.Text(label) diff --git a/ipypublish/sphinx/tests/test_bibgloss.py b/ipypublish/sphinx/tests/test_bibgloss.py index ca9c7ad..e423cb4 100644 --- a/ipypublish/sphinx/tests/test_bibgloss.py +++ b/ipypublish/sphinx/tests/test_bibgloss.py @@ -5,165 +5,97 @@ General Sphinx test and check output. """ -import re import sys import pytest +import sphinx from ipypublish.sphinx.tests import get_test_source_dir +from ipypublish.tests.utils import HTML2JSONParser -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('bibgloss_basic')) -def test_basic(app, status, warning, get_sphinx_app_output): + +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('bibgloss_basic')) +def test_basic(app, status, warning, get_sphinx_app_output, data_regression): app.build() assert 'build succeeded' in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() - assert warnings == "" + assert warnings == '' output = get_sphinx_app_output(app, buildername='html') - assert re.search( - ('Name'), - output - ) - assert re.search( - ('name2'), - output - ) - assert re.search( - ('OTHER'), - output) - - assert re.search( - ('Names'), - output - ) - assert re.search( - ('name2 plural'), - output - ) - - assert re.search( - ('\\[name\\].*' - 'href="\\#id1".*' - 'href="\\#id4".*' - 'the description which ' - 'contains latex ' - '\\\\\\(\\\\frac\\{-23\\}\\{129\\}\\\\\\)' - ''), - output - ) - assert re.search( - ('\\[name2\\].*' - 'href="\\#id2".*' - 'href="\\#id5".*' - 'the description which contains

'), - output - ) - assert re.search( - ('\\[OTHER\\]Abbrev of other'), - output - ) - - assert re.search( - ( - '.*\\[name\\].*' - '.*\\[name2\\].*' - '.*\\[OTHER\\].*' - ), - output, - re.DOTALL - ) - - -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('bibgloss_sortkeys')) -def test_sortkeys(app, status, warning, get_sphinx_app_output): + parser = HTML2JSONParser() + parser.feed(output) + if sphinx.version_info >= (2,): + 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('bibgloss_sortkeys')) +def test_sortkeys(app, status, warning, get_sphinx_app_output, data_regression): app.build() assert 'build succeeded' in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() - assert warnings == "" + assert warnings == '' output = get_sphinx_app_output(app, buildername='html') - assert re.search( - ( - '.*href="\\#id1">\\[name\\].*' - '.*href="\\#id3">.*pi.*' - '.*href="\\#id2">\\[MA\\].*' - ), - output, - re.DOTALL - ) + parser = HTML2JSONParser() + parser.feed(output) + if sphinx.version_info >= (2,): + data_regression.check(parser.parsed, basename='test_sortkeys_v2') + else: + data_regression.check(parser.parsed, basename='test_sortkeys_v1') -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('bibgloss_unsorted')) -def test_unsorted(app, status, warning, get_sphinx_app_output): +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('bibgloss_unsorted')) +def test_unsorted(app, status, warning, get_sphinx_app_output, data_regression): app.build() assert 'build succeeded' in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() - assert warnings == "" + assert warnings == '' output = get_sphinx_app_output(app, buildername='html') - assert re.search( - ( - '.*href="\\#id1">\\[name\\].*' - '.*href="\\#id2">\\[OTHER\\].*' - '.*href="\\#id3">\\[name2\\].*' - ), - output, - re.DOTALL - ) + parser = HTML2JSONParser() + parser.feed(output) + if sphinx.version_info >= (2,): + data_regression.check(parser.parsed, basename='test_unsorted_v2') + else: + data_regression.check(parser.parsed, basename='test_unsorted_v1') -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('bibgloss_missingref')) +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('bibgloss_missingref')) def test_missingref(app, status, warning, get_sphinx_app_output): app.build() assert 'build succeeded' in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() - assert "could not relabel bibglossary reference [missingkey]" in warnings + if ('could not relabel bibglossary reference [missingkey]' not in warnings and # sphinx < 2 + 'WARNING: citation not found: missingkey' not in warnings): # sphinx >= 2 + raise AssertionError('should raise warning for missing citation `missingkey`: {}'.format(warnings)) -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('bibgloss_duplicatekey')) +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('bibgloss_duplicatekey')) def test_duplicatekey(app, status, warning, get_sphinx_app_output): with pytest.raises(KeyError): app.build() -@pytest.mark.skipif( - sys.version_info < (3, 0), - reason="SyntaxError on import of texsoup/data.py line 135") -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('bibgloss_tex')) +@pytest.mark.skipif(sys.version_info < (3, 0), reason='SyntaxError on import of texsoup/data.py line 135') +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('bibgloss_tex')) def test_load_tex(app, status, warning, get_sphinx_app_output): app.build() assert 'build succeeded' in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() - assert warnings == "" + assert warnings == '' diff --git a/ipypublish/sphinx/tests/test_bibgloss/test_basic_v1.yml b/ipypublish/sphinx/tests/test_bibgloss/test_basic_v1.yml new file mode 100644 index 0000000..09795e2 --- /dev/null +++ b/ipypublish/sphinx/tests/test_bibgloss/test_basic_v1.yml @@ -0,0 +1,278 @@ +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: + - section + id: welcome-to-ipysphinx-extension-tests-documentation + 4_children: + - 1_tag: h1 + 2_data: + - Welcome to IpySphinx extension tests documentation! + 4_children: + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#welcome-to-ipysphinx-extension-tests-documentation' + title: Permalink to this headline + - 1_tag: p + 2_data: + - ',' + - ',' + 4_children: + - 1_tag: a + 2_data: + - Name + 3_attributes: + class: + - bibgcapital + - bibglossary + - internal + - reference + href: '#term1' + id: id1 + - 1_tag: a + 2_data: + - name2 + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#term2' + id: id2 + - 1_tag: a + 2_data: + - OTHER + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#acro1' + id: id3 + - 1_tag: p + 2_data: + - ',' + 4_children: + - 1_tag: a + 2_data: + - Names + 3_attributes: + class: + - bibgcapital + - bibglossary + - bibgplural + - internal + - reference + href: '#term1' + id: id4 + - 1_tag: a + 2_data: + - name2 plural + 3_attributes: + class: + - bibglossary + - bibgplural + - internal + - reference + href: '#term2' + id: id5 + - 1_tag: p + 2_data: + - Glossary + 3_attributes: + class: + - rubric + - 1_tag: p + 3_attributes: + id: bibtex-bibglossary-contents-0 + 4_children: + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: term1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 2_data: + - '[name]' + 3_attributes: + class: + - label + - 1_tag: td + 2_data: + - ' the description which contains latex' + 4_children: + - 1_tag: em + 2_data: + - ( + - ',' + - ) + 4_children: + - 1_tag: a + 2_data: + - '1' + 3_attributes: + class: + - fn-backref + href: '#id1' + - 1_tag: a + 2_data: + - '2' + 3_attributes: + class: + - fn-backref + href: '#id4' + - 1_tag: span + 2_data: + - \(\frac{-23}{129}\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: term2 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 2_data: + - '[name2]' + 3_attributes: + class: + - label + - 1_tag: td + 4_children: + - 1_tag: em + 2_data: + - ( + - ',' + - ) + 4_children: + - 1_tag: a + 2_data: + - '1' + 3_attributes: + class: + - fn-backref + href: '#id2' + - 1_tag: a + 2_data: + - '2' + 3_attributes: + class: + - fn-backref + href: '#id5' + - 1_tag: p + 2_data: + - the description which contains + - 1_tag: p + 2_data: + - a second paragraph + 3_attributes: + class: + - last + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: acro1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[OTHER]' + 3_attributes: + class: + - fn-backref + href: '#id3' + - 1_tag: td + 2_data: + - Abbrev of other diff --git a/ipypublish/sphinx/tests/test_bibgloss/test_basic_v2.yml b/ipypublish/sphinx/tests/test_bibgloss/test_basic_v2.yml new file mode 100644 index 0000000..9ae16ea --- /dev/null +++ b/ipypublish/sphinx/tests/test_bibgloss/test_basic_v2.yml @@ -0,0 +1,252 @@ +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: + - section + id: welcome-to-ipysphinx-extension-tests-documentation + 4_children: + - 1_tag: h1 + 2_data: + - Welcome to IpySphinx extension tests documentation! + 4_children: + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#welcome-to-ipysphinx-extension-tests-documentation' + title: Permalink to this headline + - 1_tag: p + 2_data: + - ',' + - ',' + 4_children: + - 1_tag: a + 2_data: + - Name + 3_attributes: + class: + - bibgcapital + - bibglossary + - internal + - reference + href: '#term1' + id: id1 + - 1_tag: a + 2_data: + - name2 + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#term2' + id: id2 + - 1_tag: a + 2_data: + - OTHER + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#acro1' + id: id3 + - 1_tag: p + 2_data: + - ',' + 4_children: + - 1_tag: a + 2_data: + - Names + 3_attributes: + class: + - bibgcapital + - bibglossary + - bibgplural + - internal + - reference + href: '#term1' + id: id4 + - 1_tag: a + 2_data: + - name2 plural + 3_attributes: + class: + - bibglossary + - bibgplural + - internal + - reference + href: '#term2' + id: id5 + - 1_tag: p + 2_data: + - Glossary + 3_attributes: + class: + - rubric + - 1_tag: p + 3_attributes: + id: bibtex-bibglossary-contents-0 + 4_children: + - 1_tag: dl + 3_attributes: + class: + - citation + 4_children: + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: term1 + 4_children: + - 1_tag: span + 2_data: + - name + 3_attributes: + class: + - brackets + - 1_tag: span + 2_data: + - ( + - ',' + - ) + 3_attributes: + class: + - fn-backref + 4_children: + - 1_tag: a + 2_data: + - '1' + 3_attributes: + href: '#id1' + - 1_tag: a + 2_data: + - '2' + 3_attributes: + href: '#id4' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - the description which contains latex + 4_children: + - 1_tag: span + 2_data: + - \(\frac{-23}{129}\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: term2 + 4_children: + - 1_tag: span + 2_data: + - name2 + 3_attributes: + class: + - brackets + - 1_tag: span + 2_data: + - ( + - ',' + - ) + 3_attributes: + class: + - fn-backref + 4_children: + - 1_tag: a + 2_data: + - '1' + 3_attributes: + href: '#id2' + - 1_tag: a + 2_data: + - '2' + 3_attributes: + href: '#id5' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - the description which contains + - 1_tag: p + 2_data: + - a second paragraph + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: acro1 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 2_data: + - OTHER + 3_attributes: + class: + - fn-backref + href: '#id3' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - Abbrev of other diff --git a/ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v1.yml b/ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v1.yml new file mode 100644 index 0000000..2c59816 --- /dev/null +++ b/ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v1.yml @@ -0,0 +1,227 @@ +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: + - section + id: welcome-to-ipysphinx-extension-tests-documentation + 4_children: + - 1_tag: h1 + 2_data: + - Welcome to IpySphinx extension tests documentation! + 4_children: + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#welcome-to-ipysphinx-extension-tests-documentation' + title: Permalink to this headline + - 1_tag: p + 2_data: + - ',' + - ',' + 4_children: + - 1_tag: a + 2_data: + - Name + 3_attributes: + class: + - bibgcapital + - bibglossary + - internal + - reference + href: '#gtkey1' + id: id1 + - 1_tag: a + 2_data: + - MA + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#akey1' + id: id2 + - 1_tag: a + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#symbol1' + id: id3 + 4_children: + - 1_tag: span + 2_data: + - \(\pi\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: p + 2_data: + - Glossary + 3_attributes: + class: + - rubric + - 1_tag: p + 3_attributes: + id: bibtex-bibglossary-contents-0 + 4_children: + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: gtkey1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[name]' + 3_attributes: + class: + - fn-backref + href: '#id1' + - 1_tag: td + 2_data: + - full description + 4_children: + - 1_tag: strong + 2_data: + - with latex + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: symbol1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[' + - ']' + 3_attributes: + class: + - fn-backref + href: '#id3' + 4_children: + - 1_tag: span + 2_data: + - \(\pi\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: td + 2_data: + - full description + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: akey1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[MA]' + 3_attributes: + class: + - fn-backref + href: '#id2' + - 1_tag: td + 2_data: + - My Abbreviation diff --git a/ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v2.yml b/ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v2.yml new file mode 100644 index 0000000..5ccb098 --- /dev/null +++ b/ipypublish/sphinx/tests/test_bibgloss/test_sortkeys_v2.yml @@ -0,0 +1,205 @@ +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: + - section + id: welcome-to-ipysphinx-extension-tests-documentation + 4_children: + - 1_tag: h1 + 2_data: + - Welcome to IpySphinx extension tests documentation! + 4_children: + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#welcome-to-ipysphinx-extension-tests-documentation' + title: Permalink to this headline + - 1_tag: p + 2_data: + - ',' + - ',' + 4_children: + - 1_tag: a + 2_data: + - Name + 3_attributes: + class: + - bibgcapital + - bibglossary + - internal + - reference + href: '#gtkey1' + id: id1 + - 1_tag: a + 2_data: + - MA + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#akey1' + id: id2 + - 1_tag: a + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#symbol1' + id: id3 + 4_children: + - 1_tag: span + 2_data: + - \(\pi\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: p + 2_data: + - Glossary + 3_attributes: + class: + - rubric + - 1_tag: p + 3_attributes: + id: bibtex-bibglossary-contents-0 + 4_children: + - 1_tag: dl + 3_attributes: + class: + - citation + 4_children: + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: gtkey1 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 2_data: + - name + 3_attributes: + class: + - fn-backref + href: '#id1' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - full description + 4_children: + - 1_tag: strong + 2_data: + - with latex + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: symbol1 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 3_attributes: + class: + - fn-backref + href: '#id3' + 4_children: + - 1_tag: span + 2_data: + - \(\pi\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - full description + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: akey1 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 2_data: + - MA + 3_attributes: + class: + - fn-backref + href: '#id2' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - My Abbreviation diff --git a/ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v1.yml b/ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v1.yml new file mode 100644 index 0000000..f29600e --- /dev/null +++ b/ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v1.yml @@ -0,0 +1,226 @@ +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: + - section + id: welcome-to-ipysphinx-extension-tests-documentation + 4_children: + - 1_tag: h1 + 2_data: + - Welcome to IpySphinx extension tests documentation! + 4_children: + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#welcome-to-ipysphinx-extension-tests-documentation' + title: Permalink to this headline + - 1_tag: p + 2_data: + - ',' + - ',' + 4_children: + - 1_tag: a + 2_data: + - Name + 3_attributes: + class: + - bibgcapital + - bibglossary + - internal + - reference + href: '#term1' + id: id1 + - 1_tag: a + 2_data: + - OTHER + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#acro1' + id: id2 + - 1_tag: a + 2_data: + - name2 + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#term2' + id: id3 + - 1_tag: p + 2_data: + - Glossary + 3_attributes: + class: + - rubric + - 1_tag: p + 3_attributes: + id: bibtex-bibglossary-contents-0 + 4_children: + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: term1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[name]' + 3_attributes: + class: + - fn-backref + href: '#id1' + - 1_tag: td + 2_data: + - the description which contains latex + 4_children: + - 1_tag: span + 2_data: + - \(\frac{-23}{129}\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: acro1 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[OTHER]' + 3_attributes: + class: + - fn-backref + href: '#id2' + - 1_tag: td + 2_data: + - Abbrev of other + - 1_tag: table + 3_attributes: + class: + - bibglossary + - citation + - docutils + frame: void + id: term2 + rules: none + 4_children: + - 1_tag: colgroup + 4_children: + - 1_tag: col + 3_attributes: + class: + - label + - 1_tag: col + - 1_tag: tbody + 3_attributes: + valign: top + 4_children: + - 1_tag: tr + 4_children: + - 1_tag: td + 3_attributes: + class: + - label + 4_children: + - 1_tag: a + 2_data: + - '[name2]' + 3_attributes: + class: + - fn-backref + href: '#id3' + - 1_tag: td + 4_children: + - 1_tag: p + 2_data: + - the description which contains + 3_attributes: + class: + - first + - 1_tag: p + 2_data: + - a second paragraph + 3_attributes: + class: + - last diff --git a/ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v2.yml b/ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v2.yml new file mode 100644 index 0000000..176d07c --- /dev/null +++ b/ipypublish/sphinx/tests/test_bibgloss/test_unsorted_v2.yml @@ -0,0 +1,199 @@ +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: + - section + id: welcome-to-ipysphinx-extension-tests-documentation + 4_children: + - 1_tag: h1 + 2_data: + - Welcome to IpySphinx extension tests documentation! + 4_children: + - 1_tag: a + 2_data: + - ¶ + 3_attributes: + class: + - headerlink + href: '#welcome-to-ipysphinx-extension-tests-documentation' + title: Permalink to this headline + - 1_tag: p + 2_data: + - ',' + - ',' + 4_children: + - 1_tag: a + 2_data: + - Name + 3_attributes: + class: + - bibgcapital + - bibglossary + - internal + - reference + href: '#term1' + id: id1 + - 1_tag: a + 2_data: + - OTHER + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#acro1' + id: id2 + - 1_tag: a + 2_data: + - name2 + 3_attributes: + class: + - bibglossary + - internal + - reference + href: '#term2' + id: id3 + - 1_tag: p + 2_data: + - Glossary + 3_attributes: + class: + - rubric + - 1_tag: p + 3_attributes: + id: bibtex-bibglossary-contents-0 + 4_children: + - 1_tag: dl + 3_attributes: + class: + - citation + 4_children: + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: term1 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 2_data: + - name + 3_attributes: + class: + - fn-backref + href: '#id1' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - the description which contains latex + 4_children: + - 1_tag: span + 2_data: + - \(\frac{-23}{129}\) + 3_attributes: + class: + - math + - nohighlight + - notranslate + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: acro1 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 2_data: + - OTHER + 3_attributes: + class: + - fn-backref + href: '#id2' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - Abbrev of other + - 1_tag: dt + 3_attributes: + class: + - bibglossary + - label + id: term2 + 4_children: + - 1_tag: span + 3_attributes: + class: + - brackets + 4_children: + - 1_tag: a + 2_data: + - name2 + 3_attributes: + class: + - fn-backref + href: '#id3' + - 1_tag: dd + 4_children: + - 1_tag: div + 3_attributes: + class: + - line + 4_children: + - 1_tag: br + - 1_tag: p + 2_data: + - the description which contains + - 1_tag: p + 2_data: + - a second paragraph diff --git a/ipypublish/sphinx/tests/test_notebook.py b/ipypublish/sphinx/tests/test_notebook.py index 46f5d46..f4a5558 100644 --- a/ipypublish/sphinx/tests/test_notebook.py +++ b/ipypublish/sphinx/tests/test_notebook.py @@ -5,33 +5,28 @@ General Sphinx test and check output. """ -import re -from textwrap import dedent import pytest +import sphinx from ipypublish.sphinx.tests import get_test_source_dir +from ipypublish.tests.utils import HTML2JSONParser -@pytest.mark.sphinx( - buildername='html', - srcdir=get_test_source_dir('notebook')) -def test_basic(app, status, warning, get_sphinx_app_output): + +@pytest.mark.sphinx(buildername='html', srcdir=get_test_source_dir('notebook')) +def test_basic(app, status, warning, get_sphinx_app_output, data_regression): app.build() assert 'build succeeded' in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() - assert warnings == "" + assert warnings == '' output = get_sphinx_app_output(app, buildername='html') - assert re.search( - dedent("""\ -
-
-        This is some printed text,
-        with a nicely formatted output\\.
-
-        
"""), - output - ) + parser = HTML2JSONParser() + parser.feed(output) + if sphinx.version_info >= (2,): + data_regression.check(parser.parsed, basename='test_basic_v2') + else: + data_regression.check(parser.parsed, basename='test_basic_v1') diff --git a/ipypublish/sphinx/tests/test_notebook/test_basic_v1.yml b/ipypublish/sphinx/tests/test_notebook/test_basic_v1.yml new file mode 100644 index 0000000..1e9edf7 --- /dev/null +++ b/ipypublish/sphinx/tests/test_notebook/test_basic_v1.yml @@ -0,0 +1,262 @@ +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-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 + - nblast + - nboutput + 4_children: + - 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 + - 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_basic_v2.yml b/ipypublish/sphinx/tests/test_notebook/test_basic_v2.yml new file mode 100644 index 0000000..3112754 --- /dev/null +++ b/ipypublish/sphinx/tests/test_notebook/test_basic_v2.yml @@ -0,0 +1,288 @@ +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-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 + - nblast + - nboutput + 4_children: + - 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 + - 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/tests/utils.py b/ipypublish/tests/utils.py new file mode 100644 index 0000000..e5b16da --- /dev/null +++ b/ipypublish/tests/utils.py @@ -0,0 +1,136 @@ +from copy import deepcopy +import six +try: + from html.parser import HTMLParser +except ImportError: + from HTMLParser import HTMLParser + + +class HTML2JSONParser(HTMLParser, object): + """parses html content to a JSON object, + of the form:: + + {"attrs": {}, "data": [], "children": []} + + """ + + _tag_key = '1_tag' + _data_key = '2_data' + _tag_attrs_key = '3_attributes' + _children_key = '4_children' + + def __init__(self, + ignore_tags=('head', 'script', 'style'), + ignore_classes=('footer', 'sphinxsidebar', 'clearer'), + rstrip_data=True, + sort_class_attr=True, + replace_data_lines=None, + convert_charrefs=False): + """parses html content to a JSON object, + of the form:: + + {"tag": "tag_name", "attrs": {}, "data": [], "children": []} + + Parameters + ---------- + ignore_tags : list[str] + HTML tags that will be ignored (and all their children) + ignore_classes : list[str] + HTML tags with one or more of these classes will be ignored (and all their children) + rstrip_data : bool + apply `rstrip()` to data text, and don't add if data == '' + sort_class_attr : bool + if an attribute is named 'class', its contents will be split and sorted + replace_data_lines: None or dict + mapping of data lines to replace (useful for mapping across different environment versions) + convert_charrefs: bool + If True, all character references (except the ones in script/style elements) + are automatically converted to the corresponding Unicode characters. + + """ + if six.PY2: + super(HTML2JSONParser, self).__init__() + else: + super(HTML2JSONParser, self).__init__(convert_charrefs=convert_charrefs) + self._content = {} + self._curr_tags = [] + self._curr_depth = 0 + self._ignore_depth = None + self._rstrip_data = rstrip_data + self._sort_class_attr = sort_class_attr + self._ignore_tags = ignore_tags + self._ignore_classes = set(ignore_classes) + self._replace_data_lines = replace_data_lines or {} + + @property + def parsed(self): + return deepcopy(self._content) + + def reset(self): + self._content = {} + self._curr_tags = [] + self._curr_depth = 0 + self._ignore_depth = None + super(HTML2JSONParser, self).reset() + + def _get_subcontent(self): + sub_content = self._content + for ptag in self._curr_tags: + sub_content = sub_content[self._children_key][ptag] + return sub_content + + def handle_starttag(self, tag, attrs): + self._curr_depth += 1 + attr_dict = dict(attrs) + classes = attr_dict.get('class', '').split() + if self._ignore_depth is not None: + return + elif tag in self._ignore_tags or self._ignore_classes.intersection(classes): + # we ignore any tags and data, until the current depth is less than the ignore depth + self._ignore_depth = self._curr_depth + return + sub_content = self._get_subcontent() + if self._sort_class_attr and 'class' in attr_dict: + attr_dict['class'] = sorted(classes) + tag_dict = {self._tag_key: tag} + if attr_dict: + tag_dict[self._tag_attrs_key] = attr_dict + sub_content.setdefault(self._children_key, []).append(tag_dict) + self._curr_tags.append(len(sub_content[self._children_key]) - 1) + + def handle_endtag(self, tag): + self._curr_depth -= 1 + + if self._ignore_depth is not None: + if self._ignore_depth > self._curr_depth: + # print("exited ignore: {}".format(tag)) + self._ignore_depth = None + return + + if tag != self._get_subcontent()[self._tag_key]: + raise AssertionError('{} != {} (current path: {})'.format(tag, + self._get_subcontent()[self._tag_key], + self._curr_tags)) + self._curr_tags = self._curr_tags[:-1] + + def handle_data(self, data): + if self._ignore_depth is not None: + return + if not data.strip(): + return + data = data.splitlines() + if self._rstrip_data: + data = [d.rstrip() for d in data] + if self._replace_data_lines: + data = [self._replace_data_lines.get(d, d) for d in data] + sub_content = self._get_subcontent() + sub_content.setdefault(self._data_key, []).extend(data) + + def handle_entityref(self, name): + pass + + def handle_charref(self, name): + pass + + def handle_comment(self, data): + pass diff --git a/requirements-lock.txt b/requirements-lock.txt deleted file mode 100644 index 01ef5fd..0000000 --- a/requirements-lock.txt +++ /dev/null @@ -1,41 +0,0 @@ -# -# This file is autogenerated by pip-compile -# To update, run: -# -# pip-compile --output-file requirements-lock.txt setup.py -# -bibtexparser==1.1.0 -bleach==3.1.0 # via nbconvert -click==7.0 # via panflute -decorator==4.3.2 # via traitlets -defusedxml==0.5.0 # via nbconvert -docutils==0.14 -entrypoints==0.3 # via nbconvert -future==0.17.1 # via bibtexparser, panflute -ipython-genutils==0.2.0 # via nbformat, traitlets -jinja2==2.10 -jsonextended==0.7.7 -jsonschema==2.6.0 -jupyter-core==4.4.0 # via nbconvert, nbformat -jupytext==0.8.6 -markupsafe==1.1.0 # via jinja2 -mistune==0.8.4 # via nbconvert -mock==2.0.0 # via jupytext -nbconvert==5.4.0 -nbformat==4.4.0 -ordered-set==3.1.1 -pandocfilters==1.4.2 # via nbconvert -panflute==1.11.2 -pathlib2==2.3.3 # via jsonextended -pbr==5.1.2 # via mock -pygments==2.3.1 # via nbconvert -pyparsing==2.3.1 # via bibtexparser -pyyaml==3.13 # via jupytext, panflute -ruamel.yaml==0.15.87 -shutilwhich==1.1.0 # via panflute -six==1.12.0 -testfixtures==6.5.0 # via jupytext -testpath==0.4.2 # via nbconvert -tornado==5.1.1 -traitlets==4.3.2 -webencodings==0.5.1 # via bleach diff --git a/requirements.txt b/requirements.txt index 08b2909..a87b374 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,6 @@ bibtexparser -docutils +docutils; python_version >= '3' +docutils <0.15; python_version < '3' jinja2 jsonextended>=0.7 jsonschema diff --git a/setup.py b/setup.py index d66627f..a301ed7 100755 --- a/setup.py +++ b/setup.py @@ -24,39 +24,41 @@ long_description_content_type='text/markdown', install_requires=requirements, extras_require={ - "sphinx": { - "sphinx(>=1.6,<2)", - "sphinxcontrib-bibtex", + 'sphinx': { + 'sphinx>=1.6', + 'sphinxcontrib-bibtex', }, - "tests": { - "pytest>=3.6", - "pytest-cov", - "flake8(>=3.7,<3.8)", - "coverage", - "pillow", - "nbsphinx", - "ipykernel", - "sphinx(>=1.6,<2)", - "sphinxcontrib-bibtex", - "texsoup<=0.1.4" + 'tests': { + 'pytest>=3.6', + 'pytest-regressions', + 'pytest-cov', + 'flake8(>=3.7,<3.8)', + 'coverage', + 'pillow', + 'nbsphinx', + 'ipykernel', + 'sphinx>=1.6', + 'sphinxcontrib-bibtex', + 'texsoup<=0.1.4', + 'doc8' }, - "science": { - "matplotlib", - "numpy", - "pandas", - "sympy" + 'science': { + 'matplotlib', + 'numpy', + 'pandas', + 'sympy' }, - "rtd": { - "recommonmark>=0.5", - "pytest>=3.6", - "pillow", - "numpy", - "matplotlib", - "pandas", - "sympy<1.3", - "sphinx(>=1.6,<2)", - "sphinxcontrib-bibtex", - "ipykernel" + 'rtd': { + 'recommonmark>=0.5', + 'pytest>=3.6', + 'pillow', + 'numpy', + 'matplotlib', + 'pandas', + 'sympy<1.3', + 'sphinx>=1.6', + 'sphinxcontrib-bibtex', + 'ipykernel' } }, license='MIT',