diff --git a/.cruft.json b/.cruft.json index e63f218..a8d188e 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/sphinx-notes/cookiecutter", - "commit": "4c6b17aec1a4b8ddca95c4882c6bed2bc230d595", + "commit": "463b120aec3391878cf9453ca26280bf5258c08d", "checkout": null, "context": { "cookiecutter": { @@ -12,6 +12,8 @@ "version": "0.1.0", "github_owner": "sphinx-notes", "github_repo": "poc", + "generated_file_header": "This file is generated from sphinx-notes/cookiecutter.", + "dont_edit_header": "DO NOT EDIT.", "pypi_name": "sphinxnotes-poc", "pypi_owner": "SilverRainZ", "is_python_project": true, @@ -20,7 +22,7 @@ "sphinx_version": "7.0", "development_status": "3 - Alpha", "_template": "https://github.com/sphinx-notes/cookiecutter", - "_commit": "4c6b17aec1a4b8ddca95c4882c6bed2bc230d595" + "_commit": "233a8daa4e276a9559975a51178f29e7079dcafd" } }, "directory": null diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index e9a39ba..eb63db9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + name: Ruff on: [ push, pull_request ] @@ -5,5 +7,5 @@ jobs: ruff: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: chartboost/ruff-action@v1 diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 0cf70c8..a7e42c9 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + name: Deploy Sphinx documentation to Pages # Runs on pushes targeting the default branch diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index a984f89..a7cee6e 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + name: Publish package distributions to PyPI on: @@ -14,8 +16,8 @@ jobs: permissions: id-token: write # IMPORTANT: this permission is mandatory for trusted publishing steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 - run: pip install build twine && make dist - uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5b38d7..8cdfc27 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + name: Publish Github Release on: @@ -11,7 +13,7 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - uses: ncipollo/release-action@v1 with: body: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7f56f2c..829b804 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + name: Test on: push: @@ -8,8 +10,8 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: python-version-file: 'pyproject.toml' - run: python3 -m pip install .[test] @@ -17,9 +19,10 @@ jobs: doctest: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 with: python-version-file: 'pyproject.toml' - - run: python3 -m pip install .[docs] + - run: python3 -m pip install .[test] + - run: python3 -m pip install -r docs/requirements.txt - run: make doctest diff --git a/.gitignore b/.gitignore index 52736b3..7d4bcd8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7dc6a12..ba69c68 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,5 @@ +# This file is generated from sphinx-notes/cookiecutter. + repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.11 diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..508fca6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,40 @@ + + +## 基本说明 + +这是一个由 SphinxNotes 开发的 Sphinx Extension,由 `sphinxnotes/cookiecutter` 生成,很多基础文件来自模板。 + +## 首先阅读 + +- 开始了解项目时,优先阅读 `docs/index.rst`。 +- 如果任务和文档、Sphinx 配置或示例有关,继续阅读 `docs/` 下的其他文件 + +## 通用知识 + +- 使用 `make` 会构建 `docs/` 下的文档,文档自依赖当前项目,因此文档构建成功也意味着项目基本能正常构建 + - `docs/_build` 存放构建好的文档,`make clean` 清除所有构建结果 + - `make test` 运行测试,测试位于 `tests/`,可能的 e2e 测试位于 `tests/test_e2e.py` + - `make doctest` 运行 Sphinx 文档测试 + - `make install` 使用 `pip install --user` 将项目安装到本地,跨项目测试时常用 +- `make tmpl-*` 用于模板同步,参看 "模板同步" 小节 + +## 关于 SphinxNotes 项目 + +- 同为 `sphinxnotes` 项目的其他仓库通常位于当前项目的上一级目录 +- 如果你在阅读代码时遇到本地依赖、模板来源或跨仓库复用关系,可以直接读取这些本地仓库文件,不必先猜测实现,也不必优先去远程搜索。 +- 当我提到 "所有项目" 的时候,请从当前项目的上一级目录的 `cookiecutter/project-list.txt` 获取项目列表 +- `docs/conf.py` 往往会直接从源码树导入当前项目,因此排查文档构建问题时,要同时检查运行时依赖和文档依赖。 + +## 模板同步 + +- 先确认任务是当前项目问题,还是模板问题;如果是模板问题,优先在 `sphinxnotes/cookiecutter` 中修复。 +- 模板变更完成后,优先使用 `make tmpl-update` 把改动同步回项目,而不是手工重复修改生成文件。 +- 如果 `make tmpl-update` 产生 `.rej`、冲突或三方合并失败,优先尝试 `make tmpl-apply-rej`,再手工解决冲突。 +- 手工解决冲突时,重点检查 `README.rst`、`pyproject.toml`、`.github/workflows/`、`docs/conf.py`、`docs/requirements.txt` 这些常见受影响文件。 +- 当模板同步结果确认无误后,优先使用 `make tmpl-update-done` 完成后续收尾步骤。 + +### 修改约定 + +- 修改模板生成文件时,保留原有注释,除非模板本身已经统一移除了这些注释。 +- 遇到 `CUSTOM ... START` / `END` 这类用户自定义区块时,必须保留这些锚点,并尽量保留区块中的用户内容。 +- 如果模板更新和项目内手工修改发生冲突,优先保护用户自定义内容,再整理模板变更。 diff --git a/MANIFEST.in b/MANIFEST.in index 4c868dc..98f33c8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,4 @@ # This file is generated from sphinx-notes/cookiecutter. -# You need to consider modifying the TEMPLATE or modifying THIS FILE. include LICENSE include README.rst diff --git a/Makefile b/Makefile index 6e7539a..0604b4f 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,4 @@ # This file is generated from sphinx-notes/cookiecutter. -# You need to consider modifying the TEMPLATE or modifying THIS FILE. LANG = en_US.UTF-8 diff --git a/README.rst b/README.rst index 9d06963..759b275 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,4 @@ .. This file is generated from sphinx-notes/cookiecutter. - You need to consider modifying the TEMPLATE or modifying THIS FILE. =============== sphinxnotes-poc diff --git a/docs/Makefile b/docs/Makefile index 57d350d..c6a9589 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -1,5 +1,4 @@ # This file is generated from sphinx-notes/cookiecutter. -# You need to consider modifying the TEMPLATE or modifying THIS FILE. # Minimal makefile for Sphinx documentation diff --git a/docs/_images/.gitkeep b/docs/_images/.gitkeep index e69de29..cc71341 100644 --- a/docs/_images/.gitkeep +++ b/docs/_images/.gitkeep @@ -0,0 +1 @@ +# This file is generated from sphinx-notes/cookiecutter. diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep index e69de29..cc71341 100644 --- a/docs/_static/.gitkeep +++ b/docs/_static/.gitkeep @@ -0,0 +1 @@ +# This file is generated from sphinx-notes/cookiecutter. diff --git a/docs/changelog.rst b/docs/changelog.rst index a76cab9..f96a100 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,5 +1,4 @@ .. This file is generated from sphinx-notes/cookiecutter. - You need to consider modifying the TEMPLATE or modifying THIS FILE. ========== Change Log diff --git a/docs/conf.py b/docs/conf.py index 5801c27..8281c4d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,5 +1,4 @@ # This file is generated from sphinx-notes/cookiecutter. -# You need to consider modifying the TEMPLATE or modifying THIS FILE. # Configuration file for the Sphinx documentation builder. # @@ -91,6 +90,9 @@ extensions.append('sphinx.ext.autodoc') autoclass_content = 'init' autodoc_typehints = 'description' +autodoc_default_options = { + 'member-order': 'bysource', +} extensions.append('sphinx.ext.intersphinx') intersphinx_mapping = {} @@ -109,6 +111,7 @@ 'parsed_literal': (['literal'], True), } + extensions.append('sphinxnotes.project') primary_domain = 'any' diff --git a/docs/index.rst b/docs/index.rst index dd6d9b7..5185700 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,5 +1,4 @@ .. This file is generated from sphinx-notes/cookiecutter. - You need to consider modifying the TEMPLATE or modifying THIS FILE. =============== sphinxnotes-poc diff --git a/docs/make.bat b/docs/make.bat index b158787..ebe7703 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -1,37 +1,38 @@ -REM This file is generated from sphinx-notes/cookiecutter. DO NOT EDIT. - -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=python -msphinx -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The Sphinx module was not found. Make sure you have Sphinx installed, - echo.then set the SPHINXBUILD environment variable to point to the full - echo.path of the 'sphinx-build' executable. Alternatively you may add the - echo.Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd +REM This file is generated from sphinx-notes/cookiecutter. +REM DO NOT EDIT. + +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=python -msphinx +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The Sphinx module was not found. Make sure you have Sphinx installed, + echo.then set the SPHINXBUILD environment variable to point to the full + echo.path of the 'sphinx-build' executable. Alternatively you may add the + echo.Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..f58d7fb --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,19 @@ +# This file is generated from sphinx-notes/cookiecutter. + +# Documentation build dependencies. +# Keep these out of pyproject optional-dependencies to avoid resolver issues. +furo +sphinx_copybutton +sphinxcontrib-gtagjs +sphinx-sitemap +sphinxext-opengraph +sphinx-last-updated-by-git +sphinxnotes-project +sphinxnotes-comboroles + +# NOTE: Not used by docs (docs import extension from ../src), +# only to resolve its optional dependencies. +sphinxnotes-poc + +# CUSTOM DOCS DEPENDENCIES START +# CUSTOM DOCS DEPENDENCIES END diff --git a/pyproject.toml b/pyproject.toml index 0d72ff6..ad4f8e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,4 @@ # This file is generated from sphinx-notes/cookiecutter. -# You need to consider modifying the TEMPLATE or modifying THIS FILE. # This file is used to configure your project. # Read more about the various options under: @@ -61,22 +60,6 @@ dev = [ test = [ "pytest", ] -docs = [ - "furo", - "sphinx_design", - "sphinx_copybutton", - "sphinxcontrib-gtagjs", - "sphinx-sitemap", - "sphinxext-opengraph", - "sphinx-last-updated-by-git", - - # Dependencies of sphinxnotes projcts. - "sphinxnotes-project", - "sphinxnotes-comboroles", - - # CUSTOM DOCS DEPENDENCIES START - # CUSTOM DOCS DEPENDENCIES END -] [project.urls] homepage = "https://sphinx.silverrainz.me/poc" diff --git a/ruff.toml b/ruff.toml index 1774a67..9633cdd 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,5 +1,4 @@ # This file is generated from sphinx-notes/cookiecutter. -# You need to consider modifying the TEMPLATE or modifying THIS FILE. exclude = [ "docs/conf.py", diff --git a/src/sphinxnotes/poc/__init__.py b/src/sphinxnotes/poc/__init__.py index d4d97fc..f730db2 100644 --- a/src/sphinxnotes/poc/__init__.py +++ b/src/sphinxnotes/poc/__init__.py @@ -15,10 +15,12 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + def setup(app: Sphinx): """Sphinx extension entrypoint.""" from . import progress + progress.setup(app) return {'version': version('sphinxnotes.poc')} diff --git a/src/sphinxnotes/poc/alias.py b/src/sphinxnotes/poc/alias.py index 3f44615..0fec4b6 100644 --- a/src/sphinxnotes/poc/alias.py +++ b/src/sphinxnotes/poc/alias.py @@ -7,6 +7,7 @@ from sphinx.application import Sphinx from sphinx.config import Config + def _config_inited(app: Sphinx, cfg: Config) -> None: for name, alias in cfg.alias_directives: directive = directives._directives[name] # type: ignore[attr-defined] diff --git a/src/sphinxnotes/poc/meta.py b/src/sphinxnotes/poc/meta.py index 57752f5..4a46c14 100644 --- a/src/sphinxnotes/poc/meta.py +++ b/src/sphinxnotes/poc/meta.py @@ -1,5 +1,5 @@ # This file is generated from sphinx-notes/cookiecutter. -# DO NOT EDIT!!! +# DO NOT EDIT. ################################################################################ # Project meta infos. diff --git a/src/sphinxnotes/poc/progress.py b/src/sphinxnotes/poc/progress.py index bc65bfd..03abb18 100644 --- a/src/sphinxnotes/poc/progress.py +++ b/src/sphinxnotes/poc/progress.py @@ -1,6 +1,5 @@ from __future__ import annotations from typing import TYPE_CHECKING -from importlib.metadata import version from math import pi, cos, sin, ceil from urllib.parse import quote import base64 @@ -18,25 +17,28 @@ # less -> more DEFAULT_FG_COLORS = ['#aceebb', '#4ac26b', '#2da44e', '#116329'] -DEFAULT_BG_COLOR1= '#ffffff' +DEFAULT_BG_COLOR1 = '#ffffff' DEFAULT_BG_COLOR2 = '#eff2f5' + def generate_pie_svg(pct: int, fg_colors: list[str], bg_color1: str, bg_color2) -> str: RADIUS = 50 pct = max(0, min(100, pct)) - fg_color = fg_colors[ceil(len(fg_colors)*pct/100) -1] + fg_color = fg_colors[ceil(len(fg_colors) * pct / 100) - 1] # Generate SVG frame. # https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorials/SVG_from_scratch/Positions svg = [ - f'', - f'' + f'', + f'', ] if pct == 100: - svg.append(f'') + svg.append( + f'' + ) elif pct > 0: - angle = - 2 * pi * (pct / 100) + pi / 2 + angle = -2 * pi * (pct / 100) + pi / 2 x = RADIUS + RADIUS * cos(angle) y = RADIUS - RADIUS * sin(angle) # 注意Y轴方向 large_arc = 1 if (pct > RADIUS) else 0 @@ -51,17 +53,19 @@ def generate_pie_svg(pct: int, fg_colors: list[str], bg_color1: str, bg_color2) # sweep-flag=1: clockwise f'A {RADIUS} {RADIUS} 0 {large_arc} 1 {x} {y}', # [L]ine back to circle center to close(Z) the shape. - f'L {RADIUS} {RADIUS} Z' + f'L {RADIUS} {RADIUS} Z', ] - svg.append(f'') + svg.append(f'') - svg.append(f'') + svg.append( + f'' + ) svg.append('') svg = ''.join(svg) return svg -class ProgressRole(SphinxRole): +class ProgressRole(SphinxRole): @staticmethod def text_to_pct(v: str) -> int: pct = 0 @@ -69,30 +73,35 @@ def text_to_pct(v: str) -> int: if v.endswith('%'): pct = float(v.rstrip('%')) elif v.startswith('0.'): - pct = float(v)*100 + pct = float(v) * 100 elif '/' in v: [num, den] = v.split('/', maxsplit=1) - pct = 100*float(num)/float(den) + pct = 100 * float(num) / float(den) except Exception as e: logger.warning('failed to convert %s to percentage: %s', e) return round(pct) - def run(self) -> tuple[list[Node], list[system_message]]: pct = self.text_to_pct(self.text) - svg = quote(generate_pie_svg(pct, - self.config.progress_fg_colors, - self.config.progress_bg_color1, - self.config.progress_bg_color2, - )) + svg = quote( + generate_pie_svg( + pct, + self.config.progress_fg_colors, + self.config.progress_bg_color1, + self.config.progress_bg_color2, + ) + ) svg = base64.b64encode(svg.encode('utf-8')) nodes = [] - nodes.append(image(self.rawtext, - uri = construct_data_url('image/svg+xml', True, svg), - alt = f'Progress: {self.text}', - width = '1em', - CLASS = 'sphinxnotes-progress', - )) + nodes.append( + image( + self.rawtext, + uri=construct_data_url('image/svg+xml', True, svg), + alt=f'Progress: {self.text}', + width='1em', + CLASS='sphinxnotes-progress', + ) + ) if self.config.progress_with_label: nodes.append(Text(' ')) @@ -100,8 +109,11 @@ def run(self) -> tuple[list[Node], list[system_message]]: return nodes, [] + def setup(app: Sphinx): - app.add_config_value('progress_fg_colors', DEFAULT_FG_COLORS, 'html', types=list[str]) + app.add_config_value( + 'progress_fg_colors', DEFAULT_FG_COLORS, 'html', types=list[str] + ) app.add_config_value('progress_bg_color1', DEFAULT_BG_COLOR1, 'html', types=str) app.add_config_value('progress_bg_color2', DEFAULT_BG_COLOR2, 'html', types=str) app.add_config_value('progress_with_label', True, 'html', types=bool) diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..cc71341 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1 @@ +# This file is generated from sphinx-notes/cookiecutter.