├── .github
└── workflows
│ └── integration.yml
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── MANIFEST.in
├── README.md
├── doc
├── Makefile
├── conf.py
├── dokieli.md
├── hypothesis.md
├── index.md
├── requirements.txt
└── utterances.md
├── readthedocs.yml
├── setup.cfg
├── setup.py
├── sphinx_comments
└── __init__.py
└── tests
├── config
└── conf.py
├── test_comments.py
└── test_comments
├── dokieli.html
├── hypothesis.html
└── utterances.html
/.github/workflows/integration.yml:
--------------------------------------------------------------------------------
1 | name: continuous-integration
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 |
7 | tests:
8 |
9 | runs-on: ubuntu-latest
10 | strategy:
11 | matrix:
12 | python-version: [3.6, 3.7, 3.8]
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: Set up Python ${{ matrix.python-version }}
17 | uses: actions/setup-python@v1
18 | with:
19 | python-version: ${{ matrix.python-version }}
20 | - name: Install dependencies
21 | run: |
22 | python -m pip install --upgrade pip
23 | git submodule update --init
24 | pip install -e .[testing]
25 |
26 | - name: Run pytest
27 | run: |
28 | pytest
29 |
30 | publish:
31 |
32 | name: Publish to PyPi
33 | needs: [tests]
34 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
35 | runs-on: ubuntu-latest
36 | steps:
37 | - name: Checkout source
38 | uses: actions/checkout@v2
39 | - name: Set up Python 3.7
40 | uses: actions/setup-python@v1
41 | with:
42 | python-version: 3.7
43 | - name: Build package
44 | run: |
45 | pip install wheel
46 | git submodule update --init
47 | python setup.py sdist bdist_wheel
48 | - name: Publish
49 | uses: pypa/gh-action-pypi-publish@v1.1.0
50 | with:
51 | user: __token__
52 | password: ${{ secrets.PYPI_KEY }}
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | *_build
132 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # v0.0.* changes
2 |
3 | ([full changelog](https://github.com/executablebooks/sphinx-comments/compare/57892fa6d89827cc079b979744dd2da95f341bc8...9a4748fdfd1832ef5c2bd35d1ff008e3d7656709))
4 |
5 |
6 | ## Bugs fixed
7 | * 🐛 BUG: fixing multiple script installs [#11](https://github.com/executablebooks/sphinx-comments/pull/11) ([@choldgraf](https://github.com/choldgraf))
8 |
9 | ## Documentation improvements
10 | * 📚 DOCS: Improving documentation [#8](https://github.com/executablebooks/sphinx-comments/pull/8) ([@choldgraf](https://github.com/choldgraf))
11 | * 📚 DOCS: Infra for docs [#7](https://github.com/executablebooks/sphinx-comments/pull/7) ([@choldgraf](https://github.com/choldgraf))
12 |
13 | ## Other merged PRs
14 | * testing infra [#6](https://github.com/executablebooks/sphinx-comments/pull/6) ([@choldgraf](https://github.com/choldgraf))
15 |
16 | ## Contributors to this release
17 | ([GitHub contributors page for this release](https://github.com/executablebooks/sphinx-comments/graphs/contributors?from=2020-08-01&to=2020-08-12&type=c))
18 |
19 | [@choldgraf](https://github.com/search?q=repo%3Aexecutablebooks%2Fsphinx-comments+involves%3Acholdgraf+updated%3A2020-08-01..2020-08-12&type=Issues) | [@welcome](https://github.com/search?q=repo%3Aexecutablebooks%2Fsphinx-comments+involves%3Awelcome+updated%3A2020-08-01..2020-08-12&type=Issues)
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Executable Books Project
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | graft doc/
2 | prune doc/_build
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sphinx Comments
2 |
3 | [](https://pypi.org/project/sphinx_comments/) | [](https://sphinx-comments.readthedocs.io/en/latest/?badge=latest)
4 |
5 | Add comments and annotation functionality to your Sphinx website.
6 |
7 | Currently, these commenting engines are supported:
8 |
9 | - [Hypothes.is](https://hypothes.is/) provides a web overlay that allows you to annotate and comment collaboratively.
10 | - [utteranc.es](https://utteranc.es/) is a web commenting system that uses GitHub Issues to store and manage comments.
11 | - [`dokie.li`](https://dokie.li/) is an open source commenting and annotation overlay built on web standards.
12 |
13 | For examples of each service, as well as instructions for how to activate it,
14 | [see the `sphinx-comments` documentation](https://sphinx-comments.readthedocs.io/en/latest).
15 |
16 | ## Contribute to Sphinx Comments
17 |
18 | Sphinx Comments follows [the Executable Books contributing guide](https://github.com/executablebooks/.github/blob/master/CONTRIBUTING.md).
19 |
20 | ### Install for development
21 |
22 | To install `sphinx-comments` for development, take the following steps:
23 |
24 | ```bash
25 | git clone https://github.com/executablebooks/sphinx-comments
26 | cd sphinx-comments
27 | pip install -e .[testing,sphinx]
28 | ```
29 |
30 | This will install the dependencies needed for development and testing.
31 |
32 | ### Repository structure
33 |
34 | Sphinx Comments is a lightweight Sphinx extension that activates several Javascript libraries for use within Sphinx. All of its functionality is contained in `sphinx_comments/__init__.py`.
35 |
36 | As a general rule, Sphinx Comments tries to be as lightweight as possible. It simply:
37 |
38 | - Loads Javscript libraries for web commenting and annotation platforms
39 | - Provides a configuration layer for platforms that support it
40 |
41 | Note that some of these platforms cannot be activated at the same time, users
42 | will need to choose one or the other.
43 |
44 | Some of the annotation platforms require more complex setup - for example, `utteranc.es` requires its script to be placed in a specific location on the page, and so `sphinx-comments` will place it directly in the doctree of the page (underneath the content).
45 |
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SPHINXPROJ = SphinxComments
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/doc/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Configuration file for the Sphinx documentation builder.
4 | #
5 | # This file does only contain a selection of the most common options. For a
6 | # full list see the documentation:
7 | # http://www.sphinx-doc.org/en/master/config
8 |
9 | # -- Path setup --------------------------------------------------------------
10 |
11 | # If extensions (or modules to document with autodoc) are in another directory,
12 | # add these directories to sys.path here. If the directory is relative to the
13 | # documentation root, use os.path.abspath to make it absolute, like shown here.
14 | #
15 | # import os
16 | # import sys
17 | # sys.path.insert(0, os.path.abspath('.'))
18 |
19 |
20 | # -- Project information -----------------------------------------------------
21 |
22 | project = "Sphinx Comments"
23 | copyright = "2018, Executable Books Project"
24 | author = "Executable Books Project"
25 |
26 | # The short X.Y version
27 | version = ""
28 | # The full version, including alpha/beta/rc tags
29 | release = ""
30 |
31 |
32 | # -- General configuration ---------------------------------------------------
33 |
34 | # If your documentation needs a minimal Sphinx version, state it here.
35 | #
36 | # needs_sphinx = '1.0'
37 |
38 | # Add any Sphinx extension module names here, as strings. They can be
39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
40 | # ones.
41 | extensions = ["sphinx_comments", "myst_parser"]
42 |
43 | comments_config = {
44 | # "hypothesis": True,
45 | # "utterances": {
46 | # "repo": "executablebooks/sphinx-comments",
47 | # },
48 | # "dokieli": True
49 | }
50 |
51 |
52 | # Add any paths that contain templates here, relative to this directory.
53 | templates_path = ["_templates"]
54 |
55 | # The suffix(es) of source filenames.
56 | # You can specify multiple suffix as a list of string:
57 | #
58 | # source_suffix = ['.rst', '.md']
59 | source_suffix = ".rst"
60 |
61 | # The master toctree document.
62 | master_doc = "index"
63 |
64 | # The language for content autogenerated by Sphinx. Refer to documentation
65 | # for a list of supported languages.
66 | #
67 | # This is also used if you do content translation via gettext catalogs.
68 | # Usually you set "language" from the command line for these cases.
69 | language = None
70 |
71 | # List of patterns, relative to source directory, that match files and
72 | # directories to ignore when looking for source files.
73 | # This pattern also affects html_static_path and html_extra_path .
74 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
75 |
76 | # The name of the Pygments (syntax highlighting) style to use.
77 | pygments_style = "sphinx"
78 |
79 |
80 | # -- Options for HTML output -------------------------------------------------
81 |
82 | # The theme to use for HTML and HTML Help pages. See the documentation for
83 | # a list of builtin themes.
84 | #
85 | html_theme = "sphinx_book_theme"
86 | html_theme_options = {
87 | "repository_url": "https://github.com/executablebooks/sphinx-comments",
88 | "use_repository_button": True,
89 | "use_issues_button": True,
90 | "use_edit_page_button": True,
91 | }
92 | # Theme options are theme-specific and customize the look and feel of a theme
93 | # further. For a list of options available for each theme, see the
94 | # documentation.
95 | #
96 | # html_theme_options = {}
97 |
98 | # Add any paths that contain custom static files (such as style sheets) here,
99 | # relative to this directory. They are copied after the builtin static files,
100 | # so a file named "default.css" will overwrite the builtin "default.css".
101 | # html_static_path = ['_static']
102 |
103 | # Custom sidebar templates, must be a dictionary that maps document names
104 | # to template names.
105 | #
106 | # The default sidebars (for documents that don't match any pattern) are
107 | # defined by theme itself. Builtin themes are using these templates by
108 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
109 | # 'searchbox.html']``.
110 | #
111 | # html_sidebars = {}
112 |
113 | # CopyButton configuration
114 | copybutton_prompt_text = ">>> "
115 | # Switches for testing but shouldn't be activated in the live docs
116 | # copybutton_only_copy_prompt_lines = False
117 | # copybutton_remove_prompts = False
118 | # copybutton_image_path = "test/TEST_COPYBUTTON.png"
119 | # copybutton_selector = "div"
120 |
121 |
122 | # -- Options for HTMLHelp output ---------------------------------------------
123 |
124 | # Output file base name for HTML help builder.
125 | htmlhelp_basename = "SphinxCommentsdoc"
126 |
127 |
128 | # -- Options for LaTeX output ------------------------------------------------
129 |
130 | latex_elements = {
131 | # The paper size ('letterpaper' or 'a4paper').
132 | #
133 | # 'papersize': 'letterpaper',
134 | # The font size ('10pt', '11pt' or '12pt').
135 | #
136 | # 'pointsize': '10pt',
137 | # Additional stuff for the LaTeX preamble.
138 | #
139 | # 'preamble': '',
140 | # Latex figure (float) alignment
141 | #
142 | # 'figure_align': 'htbp',
143 | }
144 |
145 | # Grouping the document tree into LaTeX files. List of tuples
146 | # (source start file, target name, title,
147 | # author, documentclass [howto, manual, or own class]).
148 | latex_documents = [
149 | (
150 | master_doc,
151 | "SphinxComments.tex",
152 | "Sphinx Comments Documentation",
153 | "Executable Books Project",
154 | "manual",
155 | ),
156 | ]
157 |
158 |
159 | # -- Options for manual page output ------------------------------------------
160 |
161 | # One entry per manual page. List of tuples
162 | # (source start file, name, description, authors, manual section).
163 | man_pages = [
164 | (master_doc, "SphinxComments", "Sphinx Comments Documentation", [author], 1)
165 | ]
166 |
167 |
168 | # -- Options for Texinfo output ----------------------------------------------
169 |
170 | # Grouping the document tree into Texinfo files. List of tuples
171 | # (source start file, target name, title, author,
172 | # dir menu entry, description, category)
173 | texinfo_documents = [
174 | (
175 | master_doc,
176 | "SphinxComments",
177 | "Sphinx Comments Documentation",
178 | author,
179 | "SphinxComments",
180 | "One line description of project.",
181 | "Miscellaneous",
182 | ),
183 | ]
184 |
--------------------------------------------------------------------------------
/doc/dokieli.md:
--------------------------------------------------------------------------------
1 | # Dokieli
2 |
3 | ```{raw} html
4 |
5 |
6 | ```
7 |
8 | ```{warning}
9 | Dokieli is experimental and may not behave as expected right now!
10 | ```
11 |
12 | [`dokie.li`](https://dokie.li/) is a clientside editor for decentralised article publishing, annotations and social interactions. Dokieli is activated on this page. You can see the web overlay by clicking on the hamburger menu in the upper-right corner of this page.
13 |
14 | ## Activate `dokie.li`
15 |
16 | You can activate [`dokie.li`](https://dokie.li/)
17 | by adding the following to your `conf.py` file:
18 |
19 | ```python
20 | comments_config = {
21 | "dokieli": True
22 | }
23 | ```
24 |
25 | Next, [follow the `dokie.li` configuration instructions](https://dokie.li/).
26 |
27 | When you build your documentation, pages will now have an active dokieli overlay.
28 |
--------------------------------------------------------------------------------
/doc/hypothesis.md:
--------------------------------------------------------------------------------
1 | # Hypothesis
2 |
3 | ```{raw} html
4 |
5 | ```
6 |
7 | Hypothesis is a centralized web services that allows you to comment and annotate arbitrary web pages across the web.
8 |
9 | Hypothesis is activated on this page. You can see the web overlay by clicking on the `<` button in the upper-right corner of this page.
10 |
11 | ## Activate `hypothes.is`
12 |
13 | You can activate `hypothes.is` by adding the following to your `conf.py` file:
14 |
15 | ```python
16 | comments_config = {
17 | "hypothesis": True
18 | }
19 | ```
20 |
21 | This will add a [hypothes.is overlay](https://web.hypothes.is/) to your documentation. This extension simply activates the hypothes.is javascript bundle on your Sphinx site. This will cause the hypothes.is overlay to be shown, allowing your readers to log-in and comment on your documentation if they have questions.
22 |
23 | When you build your documentation, you will see the hypothes.is overlay to the right of your screen.
24 |
--------------------------------------------------------------------------------
/doc/index.md:
--------------------------------------------------------------------------------
1 | # Sphinx Comments
2 |
3 | Add comments and annotation functionality to your Sphinx website.
4 |
5 | Currently, these commenting engines are supported:
6 |
7 | - [Hypothes.is](https://hypothes.is/) provides a web overlay that allows you to annotate and comment collaboratively.
8 | - [utteranc.es](https://utteranc.es/) is a web commenting system that uses GitHub Issues to store and manage comments.
9 | - [`dokie.li`](https://dokie.li/) is an open source commenting and annotation overlay built on web standards.
10 |
11 | For examples of each service, as well as instructions for how to activate it,
12 | click on the links to the left.
13 |
14 | ## Installation
15 |
16 | Clone and install the github reposiory
17 |
18 | ```bash
19 | pip install sphinx-comments
20 | ```
21 |
22 | Next, activate the extension by adding it to your `conf.py` file:
23 |
24 | ```python
25 | ...
26 | extensions = [
27 | "sphinx_comments"
28 | ]
29 | ```
30 |
31 | ## Configuration
32 |
33 | To configure `sphinx-comments` (and to choose the engine you'd like to use),
34 | you should configure the `comments_config` dictionary in `conf.py`. Instructions
35 | for doing so can be found in the page for each of the supported engines below.
36 |
37 | ```{toctree}
38 | :caption: Supported engines
39 | :maxdepth: 2
40 | hypothesis
41 | dokieli
42 | utterances
43 | ```
44 |
--------------------------------------------------------------------------------
/doc/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx>=2
2 | sphinx_book_theme
3 | myst_parser
4 |
5 | # Install ourselves
6 | .
7 |
--------------------------------------------------------------------------------
/doc/utterances.md:
--------------------------------------------------------------------------------
1 | # Utterances
2 |
3 | Utterances is a commenting engine built on top of GitHub issues. It embeds a comment box in your page that users (with a GitHub account) can use to ask questions. These become comments in a GitHub issue in a repository of your choice.
4 |
5 | Utterances is activated on this page. You can see the comment box at the bottom of the page's content. Click the "log in" button and you'll be able to post comments!
6 |
7 | ## Activate `utteranc.es`
8 |
9 | You can activate `utteranc.es` by adding the following to your `conf.py` file:
10 |
11 | ```python
12 | comments_config = {
13 | "utterances": {
14 | "repo": "github-org/github-repo",
15 | "optional": "config",
16 | }
17 | }
18 | ```
19 |
20 | ```{note}
21 | You can pass optional extra configuration for utterances. See
22 | [the utterances documentation for your options](https://utteranc.es/#theme).
23 | ```
24 |
25 | Next, [follow the `utteranc.es` configuration instructions](https://utteranc.es/#configuration).
26 |
27 | When you build your documentation, pages will now have a comment box at the bottom. If readers log in via GitHub they will be able to post comments that will then map onto issues in your GitHub repository.
28 |
29 | ```{raw} html
30 |
40 | ```
41 |
--------------------------------------------------------------------------------
/readthedocs.yml:
--------------------------------------------------------------------------------
1 | name: sphinx-comments
2 | type: sphinx
3 | requirements_file: doc/requirements.txt
4 | python:
5 | version: 3
6 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | license_file = LICENSE
3 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 |
3 | from setuptools import setup, find_packages
4 |
5 | with open("./README.md", "r") as ff:
6 | readme_text = ff.read()
7 |
8 | path_doc_reqs = Path("./doc/requirements.txt")
9 | doc_reqs = [
10 | ii
11 | for ii in path_doc_reqs.read_text(encoding="utf8").split("\n")
12 | if ii and not ii.startswith("#") and ii != "."
13 | ]
14 | # Parse version
15 | init = Path(__file__).parent.joinpath("sphinx_comments", "__init__.py")
16 | for line in init.read_text().split("\n"):
17 | if line.startswith("__version__ ="):
18 | break
19 | version = line.split(" = ")[-1].strip('"')
20 |
21 | setup(
22 | name="sphinx-comments",
23 | version=version,
24 | description="Add comments and annotation to your documentation.",
25 | long_description=readme_text,
26 | long_description_content_type="text/markdown",
27 | author="Executable Book Project",
28 | url="https://github.com/executablebooks/sphinx-comments",
29 | license="MIT License",
30 | packages=find_packages(),
31 | classifiers=["License :: OSI Approved :: MIT License"],
32 | install_requires=["sphinx>=1.8",],
33 | extras_require={
34 | "code_style": ["flake8<3.8.0,>=3.7.0", "black", "pre-commit==1.17.0"],
35 | "sphinx": doc_reqs,
36 | "testing": ["beautifulsoup4", "myst-parser", "pytest", "pytest-regressions",]
37 | + doc_reqs,
38 | },
39 | )
40 |
--------------------------------------------------------------------------------
/sphinx_comments/__init__.py:
--------------------------------------------------------------------------------
1 | """Add a hypothes.is overlay to your Sphinx site."""
2 |
3 | import os
4 | from textwrap import dedent
5 |
6 | __version__ = "0.0.3"
7 |
8 |
9 | def shp_static_path(app):
10 | static_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "_static"))
11 | app.config.html_static_path.append(static_path)
12 |
13 |
14 | def activate_comments(app, config):
15 | """Activate commenting on each page."""
16 | # Grab config instances
17 | com_config = app.config.comments_config.copy()
18 | if not isinstance(com_config, (dict, type(None))):
19 | raise ValueError("Comments configuration must be a dictionary.")
20 |
21 | ut_config = com_config.get("utterances")
22 | dk_config = com_config.get("dokieli")
23 | ht_config = com_config.get("hypothesis")
24 |
25 | extra_config = {"async": "async"}
26 |
27 | # Hypothesis config
28 | if ht_config:
29 | # If hypothesis, we just need to load the js library
30 | app.add_js_file(
31 | "https://hypothes.is/embed.js", kind="hypothesis", **extra_config
32 | )
33 |
34 | # Dokieli config
35 | if dk_config:
36 | app.add_js_file(
37 | "https://dokie.li/scripts/dokieli.js", kind="dokieli", **extra_config
38 | )
39 | app.add_css_file("https://dokie.li/media/css/dokieli.css", media="all")
40 |
41 | # utterances config
42 | if ut_config:
43 | if "repo" not in ut_config:
44 | raise ValueError("To use utterances, you must provide a repository.")
45 | repo = ut_config["repo"]
46 |
47 | # Utterances requires a script + config in a specific place, so do this w/ JS
48 | dom = """
49 | var commentsRunWhenDOMLoaded = cb => {
50 | if (document.readyState != 'loading') {
51 | cb()
52 | } else if (document.addEventListener) {
53 | document.addEventListener('DOMContentLoaded', cb)
54 | } else {
55 | document.attachEvent('onreadystatechange', function() {
56 | if (document.readyState == 'complete') cb()
57 | })
58 | }
59 | }
60 | """
61 | issue_term = ut_config.get("issue-term", "pathname")
62 | theme = ut_config.get("theme", "github-light")
63 | label = ut_config.get("label", "💬 comment")
64 | crossorigin = ut_config.get("crossorigin", "anonymous")
65 | js = dedent(
66 | f"""
67 | {dom}
68 | var addUtterances = () => {{
69 | var script = document.createElement("script");
70 | script.type = "text/javascript";
71 | script.src = "https://utteranc.es/client.js";
72 | script.async = "async";
73 |
74 | script.setAttribute("repo", "{repo}");
75 | script.setAttribute("issue-term", "{issue_term}");
76 | script.setAttribute("theme", "{theme}");
77 | script.setAttribute("label", "{label}");
78 | script.setAttribute("crossorigin", "{crossorigin}");
79 |
80 | sections = document.querySelectorAll("div.section");
81 | if (sections !== null) {{
82 | section = sections[sections.length-1];
83 | section.appendChild(script);
84 | }}
85 | }}
86 | commentsRunWhenDOMLoaded(addUtterances);
87 | """
88 | )
89 | app.add_js_file(None, body=js, kind="utterances")
90 |
91 |
92 | def setup(app):
93 | app.add_config_value("comments_config", {}, "html")
94 |
95 | # Add our static path
96 | app.connect("builder-inited", shp_static_path)
97 | app.connect("config-inited", activate_comments)
98 |
99 | return {
100 | "version": __version__,
101 | "parallel_read_safe": True,
102 | "parallel_write_safe": True,
103 | }
104 |
--------------------------------------------------------------------------------
/tests/config/conf.py:
--------------------------------------------------------------------------------
1 | # -- Project information -----------------------------------------------------
2 |
3 | project = "Test build"
4 | copyright = "2018, Executable Books Project"
5 | author = "Executable Books Project"
6 |
7 | extensions = ["sphinx_comments", "myst_parser"]
8 |
9 | comments_config = {
10 | "hypothesis": True,
11 | "utterances": {"repo": "executablebooks/sphinx-comments", "theme": "footheme",},
12 | "dokieli": True,
13 | }
14 |
15 | # The master toctree document.
16 | master_doc = "index"
17 |
18 | # The language for content autogenerated by Sphinx. Refer to documentation
19 | # for a list of supported languages.
20 | #
21 | # This is also used if you do content translation via gettext catalogs.
22 | # Usually you set "language" from the command line for these cases.
23 | language = None
24 |
25 | # List of patterns, relative to source directory, that match files and
26 | # directories to ignore when looking for source files.
27 | # This pattern also affects html_static_path and html_extra_path .
28 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
29 |
30 | # The name of the Pygments (syntax highlighting) style to use.
31 | pygments_style = "sphinx"
32 |
33 |
34 | # -- Options for HTML output -------------------------------------------------
35 |
36 | # The theme to use for HTML and HTML Help pages. See the documentation for
37 | # a list of builtin themes.
38 | #
39 | html_theme = "sphinx_book_theme"
40 |
--------------------------------------------------------------------------------
/tests/test_comments.py:
--------------------------------------------------------------------------------
1 | from bs4 import BeautifulSoup
2 | from pathlib import Path
3 | from subprocess import run
4 | from shutil import copytree, rmtree
5 | import pytest
6 |
7 |
8 | path_tests = Path(__file__).parent.resolve()
9 | # path_base = path_tests.joinpath("sites", "base")
10 |
11 |
12 | # @pytest.fixture(scope="session")
13 | # def sphinx_build(tmpdir_factory):
14 | # class SphinxBuild:
15 | # path_tmp = Path(tmpdir_factory.mktemp("build"))
16 | # path_book = path_tmp.joinpath("book")
17 | # path_build = path_book.joinpath("_build")
18 | # path_html = path_build.joinpath("html")
19 | # cmd_base =
20 |
21 | # def copy(self, path=None):
22 | # """Copy the specified book to our tests folder for building."""
23 | # if path is None:
24 | # path = path_base
25 | # if not self.path_book.exists():
26 | # copytree(path, self.path_book)
27 |
28 | # def build(self, cmd=None):
29 | # """Build the test book"""
30 | # cmd = [] if cmd is None else cmd
31 | # run(self.cmd_base + cmd, cwd=self.path_book, check=True)
32 |
33 | # def path(self, *args):
34 | # return self.path_html.joinpath(*args)
35 |
36 | # def get(self, *args):
37 | # path_page = self.path(*args)
38 | # if not path_page.exists():
39 | # raise ValueError(f"{path_page} does not exist")
40 | # return BeautifulSoup(path_page.read_text(), "html.parser")
41 |
42 | # def clean(self):
43 | # """Clean the _build folder so files don't clash with new tests."""
44 | # rmtree(self.path_build)
45 |
46 | # return SphinxBuild()
47 |
48 | # def test_build
49 |
50 |
51 | def test_comments(file_regression, tmpdir_factory):
52 | path_docs = path_tests.joinpath("..", "doc")
53 | path_config = path_tests.joinpath("config")
54 | path_tmp = Path(tmpdir_factory.mktemp("build"))
55 | path_build = path_tmp.joinpath("_build", "html")
56 |
57 | cmd = ["sphinx-build", path_docs, path_build, "-a", "-W", "-c", path_config]
58 | run(cmd, check=True)
59 |
60 | # Load the index file to check if libraries are loaded properly
61 | soup = BeautifulSoup(path_build.joinpath("index.html").read_text(), "html.parser")
62 |
63 | hypothesis = soup.find("script", attrs={"kind": "hypothesis"})
64 | file_regression.check(
65 | hypothesis.prettify(), basename="hypothesis", extension=".html"
66 | )
67 |
68 | dokieli = soup.find("script", attrs={"kind": "dokieli"})
69 | file_regression.check(dokieli.prettify(), basename="dokieli", extension=".html")
70 |
71 | utterances = soup.find("script", attrs={"kind": "utterances"})
72 | file_regression.check(
73 | utterances.prettify(), basename="utterances", extension=".html"
74 | )
75 |
--------------------------------------------------------------------------------
/tests/test_comments/dokieli.html:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/tests/test_comments/hypothesis.html:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/tests/test_comments/utterances.html:
--------------------------------------------------------------------------------
1 |
34 |
--------------------------------------------------------------------------------