diff --git a/.cruft.json b/.cruft.json index bdf7830..a0b945a 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/sphinx-notes/cookiecutter", - "commit": "1701bf78ca498d756ce4502aa1712cfe23ed35af", + "commit": "c4f14dab2840eeff6352647a923642b6377d1f49", "checkout": null, "context": { "cookiecutter": { diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..e9a39ba --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,9 @@ +name: Ruff +on: [ push, pull_request ] + +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: chartboost/ruff-action@v1 diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml new file mode 100644 index 0000000..ab30fe4 --- /dev/null +++ b/.github/workflows/pypi.yml @@ -0,0 +1,22 @@ +name: Publish package distributions to PyPI + +on: + push: + tags: + - "*" + +jobs: + pypi: + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/sphinxnotes-isso + permissions: + id-token: write # IMPORTANT: this permission is mandatory for trusted publishing + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + - run: pip install build twine && make dist + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5c14049..1026fd1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,30 +1,12 @@ -name: Publish New Release +name: Publish Github Release on: push: tags: - - "*" + - "[0-9]+.[0-9]+" # MAJOR.MINOR (1.0: y, 1.0a0: n, 1.0.1: n) jobs: - pypi: - name: Publish package distributions to PyPI - runs-on: ubuntu-latest - environment: - name: pypi - url: https://pypi.org/p/sphinxnotes-isso - permissions: - id-token: write # IMPORTANT: this permission is mandatory for trusted publishing - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 - - run: pip install build twine && make dist - - uses: pypa/gh-action-pypi-publish@release/v1 - with: - password: ${{ secrets.PYPI_API_TOKEN }} - release: - name: Publish Github Release - needs: [pypi] runs-on: ubuntu-latest permissions: contents: write @@ -33,4 +15,4 @@ jobs: - uses: ncipollo/release-action@v1 with: body: | - Changelog: https://sphinx.silverrainz.me/isso/changelog.html#version-${{ github.ref_name }} + Changelog: https://sphinx.silverrainz.me/isso/changelog.html diff --git a/.gitignore b/.gitignore index 6f2c745..52736b3 100644 --- a/.gitignore +++ b/.gitignore @@ -133,3 +133,5 @@ poetry.lock # Sphinx docs/_build/ +# sphinxnotes-any >= 2.5 +docs/.any* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0166b6c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.1 + hooks: + - id: ruff + - id: ruff-format diff --git a/.sphinxnotes/template/update.py b/.sphinxnotes/template/update.py deleted file mode 100755 index f7623c3..0000000 --- a/.sphinxnotes/template/update.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 - -from os import path -import subprocess - -from cookiecutter.main import cookiecutter -from github import Github - - -def run_shell(*args: str) -> str: - return subprocess.run(args, capture_output=True, text=True).stdout.strip() - -# Fetch meta information. -root = run_shell('git', 'rev-parse', '--show-toplevel') -repo = path.basename(root) -version = run_shell('git', 'describe', '--tags') -desc = Github().get_user('sphinx-notes').get_repo('isso').description - -# assert repo == 'isso' -print(f'root: {root}') -print(f'repo: {repo}') -print(f'version: {version}') -print(f'desc: {desc}') - -# Create project from the remote repository template. -# .. seealso:: -# - https://cookiecutter.readthedocs.io/en/1.7.2/cookiecutter.html#module-cookiecutter.main -# - https://cookiecutter.readthedocs.io/en/1.7.2/advanced/injecting_context.html -cookiecutter('gh:sphinx-notes/template', - no_input=True, - overwrite_if_exists=True, - output_dir=path.dirname(root), - extra_context={ - 'name': repo, - 'version': version, - 'description': desc, - }) diff --git a/Makefile b/Makefile index 5b37c2f..54930cc 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,28 @@ LANG = en_US.UTF-8 MAKE = make PY = python3 RM = rm -rf +GIT = git +OPEN = xdg-open # Build sphinx documentation. .PHONY: docs docs: $(MAKE) -C docs/ +# View sphinx HTML documentation in browser. +.PHONY: view +view: + $(OPEN) docs/_build/html/index.html + +.PHONY: clean +clean: + $(MAKE) -C docs/ clean | true + $(RM) dist/ | true + +.PHONY: clean +fmt: + ruff format src/ + # Run unittest. .PHONY: test test: @@ -19,8 +35,7 @@ test: # Build distribution package, for "install" or "upload". .PHONY: dist -dist: pyproject.toml - $(RM) dist/ # clean up old dist +dist: pyproject.toml clean $(PY) -m build # Install distribution package to user directory. @@ -51,8 +66,16 @@ upload-test: dist update-template: $(PY) -m cruft update +.PHONY: update-template-done +update-template-done: + $(GIT) commit -m "chore: Update project template to sphinx-notes/cookiecutter@$(shell jq -r '.commit' .cruft.json | head -c8)" + # Update project version. .PHONY: bump-version bump-version: @echo -n "Please enter the version to bump: " @read version && $(PY) -m cruft update --variables-to-update "{ \"version\" : \"$$version\" }" + +# EXTRA TARGETS START + +# EXTRA TARGETS END diff --git a/README.rst b/README.rst index d536363..076550e 100644 --- a/README.rst +++ b/README.rst @@ -5,26 +5,31 @@ sphinxnotes-isso ================ -.. image:: https://img.shields.io/github/actions/workflow/status/sphinx-notes/isso/pages.yml +.. |docs| image:: https://img.shields.io/github/deployments/sphinx-notes/isso/github-pages :target: https://sphinx.silverrainz.me/isso :alt: Documentation Status -.. image:: https://img.shields.io/github/license/sphinx-notes/isso - :target: https://github.com/sphinx-notes/isso/LICENSE +.. |license| image:: https://img.shields.io/github/license/sphinx-notes/isso + :target: https://github.com/sphinx-notes/isso/blob/master/LICENSE :alt: Open Source License -.. image:: https://img.shields.io/pypi/v/sphinxnotes-isso.svg +.. |pypi| image:: https://img.shields.io/pypi/v/sphinxnotes-isso.svg :target: https://pypi.python.org/pypi/sphinxnotes-isso :alt: PyPI Package -.. image:: https://img.shields.io/pypi/dm/sphinxnotes-isso +.. |download| image:: https://img.shields.io/pypi/dm/sphinxnotes-isso :target: https://pypi.python.org/pypi/sphinxnotes-isso :alt: PyPI Package Downloads +|docs| |license| |pypi| |download| + Sphinx extension for embeding Isso comments in documents. -* Documentation: https://sphinx.silverrainz.me/isso -* Source: https://github.com/sphinx-notes/isso -* Changelog: https://sphinx.silverrainz.me/isso/changelog.html -* Tracker: https://github.com/sphinx-notes/isso/issues -* Download: https://pypi.org/project/sphinxnotes-isso/#files +.. INTRODUCTION START + (MUST written in standard reStructuredText, without Sphinx stuff) + +.. INTRODUCTION END + +Please refer to Documentation_ for more details. + +.. _Documentation: https://sphinx.silverrainz.me/isso diff --git a/docs/changelog.rst b/docs/changelog.rst index cc4af6c..20cad45 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,15 +5,19 @@ Change Log ========== +.. hint:: You may want to learn about our `Release Strategy`__ + + __ https://sphinx.silverrainz.me/release.html + .. Example: - 1.0.0 - ===== + 1.0 + === .. version:: _ :date: yyyy-mm-dd - Change log here. + Change log here. Version 1.x =========== diff --git a/docs/conf.py b/docs/conf.py index acd8139..82c1cf4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -127,6 +127,24 @@ extensions.append('sphinxcontrib.gtagjs') gtagjs_ids = ['G-E4SNX0WZYV'] +extensions.append('sphinx.ext.autodoc') +autoclass_content = 'init' +autodoc_typehints = 'description' + +extensions.append('sphinx.ext.intersphinx') +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), + 'sphinx': ('https://www.sphinx-doc.org/en/master', None), + 'jinja': ('https://jinja.palletsprojects.com/en/latest/', None), +} + +# +extensions.append('sphinxnotes.comboroles') +comboroles_roles = { + 'parsed_literal': (['literal'], True), +} +# + # # -- Eat your own dog food -------------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index a52d29e..ce27a8e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,18 +1,38 @@ .. This file is generated from sphinx-notes/cookiecutter. You need to consider modifying the TEMPLATE or modifying THIS FILE. -.. include:: ../README.rst +================ +sphinxnotes-isso +================ + +.. |docs| image:: https://img.shields.io/github/deployments/sphinx-notes/isso/github-pages + :target: https://sphinx.silverrainz.me/isso + :alt: Documentation Status + +.. |license| image:: https://img.shields.io/github/license/sphinx-notes/isso + :target: https://github.com/sphinx-notes/isso/blob/master/LICENSE + :alt: Open Source License + +.. |pypi| image:: https://img.shields.io/pypi/v/sphinxnotes-isso.svg + :target: https://pypi.python.org/pypi/sphinxnotes-isso + :alt: PyPI Package + +.. |download| image:: https://img.shields.io/pypi/dm/sphinxnotes-isso + :target: https://pypi.python.org/pypi/sphinxnotes-isso + :alt: PyPI Package Downloads + +|docs| |license| |pypi| |download| Introduction ============ -.. ADDITIONAL CONTENT START +.. INTRODUCTION START The extension allows your embedding Isso_ comments in your Sphinx documentation: .. _Isso: https://isso-comments.de/ -.. ADDITIONAL CONTENT END +.. INTRODUCTION END Getting Started =============== @@ -28,7 +48,8 @@ First, downloading extension from PyPI: $ pip install sphinxnotes-isso -Then, add the extension name to ``extensions`` configuration item in your conf.py_: +Then, add the extension name to ``extensions`` configuration item in your +:parsed_literal:`conf.py_`: .. code-block:: python diff --git a/pyproject.toml b/pyproject.toml index 823e43e..977399e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,8 @@ dev = [ "build", "twine", "cruft", + "ruff", + "pre-commit" ] test = [ "pytest", @@ -48,6 +50,7 @@ docs = [ "sphinx_design", "sphinx_copybutton", "sphinxcontrib-gtagjs", + "sphinxnotes-comboroles", ] [project.urls] diff --git a/ruff.toml b/ruff.toml new file mode 100644 index 0000000..08e71c6 --- /dev/null +++ b/ruff.toml @@ -0,0 +1,9 @@ +# This file is generated from sphinx-notes/cookiecutter. +# You need to consider modifying the TEMPLATE or modifying THIS FILE. + +exclude = [ + "docs/conf.py", +] + +[format] +quote-style = "single" diff --git a/src/sphinxnotes/isso/__init__.py b/src/sphinxnotes/isso/__init__.py index 29b839e..d0a4aa5 100644 --- a/src/sphinxnotes/isso/__init__.py +++ b/src/sphinxnotes/isso/__init__.py @@ -1,12 +1,12 @@ """ - sphinxnotes.isso - ~~~~~~~~~~~~~~~~ +sphinxnotes.isso +~~~~~~~~~~~~~~~~ - This extension is modified from sphinxcontrib-disqus. +This extension is modified from sphinxcontrib-disqus. - :copyright: Copyright 2021 Shengyu Zhang - :copyright: Copyright 2016 Robpol86 - :license: BSD, see LICENSE for details. +:copyright: Copyright 2021 Shengyu Zhang +:copyright: Copyright 2016 Robpol86 +:license: BSD, see LICENSE for details. """ from __future__ import annotations @@ -22,7 +22,7 @@ from sphinx.application import Sphinx from sphinx.util import logging -__title__= 'sphinxnotes-isso' +__title__ = 'sphinxnotes-isso' __license__ = 'BSD' __version__ = '1.0' __author__ = 'Shengyu Zhang' @@ -32,16 +32,27 @@ # Isso client configuration items # https://posativ.org/isso/docs/configuration/client/ -CONFIG_ITEMS = ['isso_css', 'isso_lang', 'isso_reply_to_self', - 'isso_require_author', 'isso_require_email', - 'isso_max_comments_top', 'isso_max_comments_nested', - 'isso_reveal_on_click', 'isso_avatar', 'isso_avatar_bg', - 'isso_avatar_fg', 'isso_vote', 'isso_vote_levels', - 'isso_feed'] +CONFIG_ITEMS = [ + 'isso_css', + 'isso_lang', + 'isso_reply_to_self', + 'isso_require_author', + 'isso_require_email', + 'isso_max_comments_top', + 'isso_max_comments_nested', + 'isso_reveal_on_click', + 'isso_avatar', + 'isso_avatar_bg', + 'isso_avatar_fg', + 'isso_vote', + 'isso_vote_levels', + 'isso_feed', +] logger = logging.getLogger(__name__) -def ext_config_to_isso_config(key:str, value:Any) -> Tuple[str,str]: + +def ext_config_to_isso_config(key: str, value: Any) -> Tuple[str, str]: assert key in CONFIG_ITEMS key = 'data-' + key.replace('_', '-') if isinstance(value, str): @@ -53,7 +64,9 @@ def ext_config_to_isso_config(key:str, value:Any) -> Tuple[str,str]: return (key, value) -class IssoNode(nodes.General, nodes.Element): pass +class IssoNode(nodes.General, nodes.Element): + pass + def html_visit_isso_node(self: HTML5Translator, node): docname = node['docname'] @@ -66,11 +79,11 @@ def html_visit_isso_node(self: HTML5Translator, node): if 'nocomments' in metadata: raise nodes.SkipNode - thread_id = node.get('thread-id') or \ - metadata.get('isso-id') or \ - '/' + docname + thread_id = node.get('thread-id') or metadata.get('isso-id') or '/' + docname if not thread_id.startswith('/'): - logger.warning(f'isso thread-id {thread_id} doesn\'t start with slash', location=node) + logger.warning( + f"isso thread-id {thread_id} doesn't start with slash", location=node + ) kwargs = { 'data-isso-id': thread_id, @@ -100,7 +113,7 @@ def run(self): node = IssoNode() node['ids'] = ['isso-thread'] - # Save docname for later looking up :attr:`self.env.metadata`, + # Save docname for later looking up :attr:`self.env.metadata`, # which is not yet available now. node['docname'] = self.env.docname @@ -118,8 +131,9 @@ def run(self): return [node] -def on_html_page_context(app:Sphinx, pagename:str, templatename:str, context, - doctree:nodes.document) -> None: +def on_html_page_context( + app: Sphinx, pagename: str, templatename: str, context, doctree: nodes.document +) -> None: """Called when the HTML builder has created a context dictionary to render a template with. Conditionally adding isso client script to if the directive is used in a page. @@ -140,14 +154,14 @@ def on_html_page_context(app:Sphinx, pagename:str, templatename:str, context, } for cfg in CONFIG_ITEMS: val = getattr(app.config, cfg) - if val is not None: # Maybe 0, False, '' or anything + if val is not None: # Maybe 0, False, '' or anything issocfg, issoval = ext_config_to_isso_config(cfg, val) kwargs[issocfg] = issoval js_path = posixpath.join(app.config.isso_url, 'js/embed.min.js') app.add_js_file(js_path, **kwargs) -def setup(app:Sphinx): +def setup(app: Sphinx): app.add_config_value('isso_url', None, '') for cfg in CONFIG_ITEMS: app.add_config_value(cfg, None, '')