rtfc 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. {rtfc-0.1.0 → rtfc-0.2.0}/.github/workflows/ci.yml +3 -3
  2. {rtfc-0.1.0 → rtfc-0.2.0}/.gitignore +2 -2
  3. {rtfc-0.1.0 → rtfc-0.2.0}/.readthedocs.yml +1 -1
  4. rtfc-0.2.0/.yamlfmt.yaml +5 -0
  5. {rtfc-0.1.0 → rtfc-0.2.0}/PKG-INFO +7 -7
  6. {rtfc-0.1.0 → rtfc-0.2.0}/README.rst +5 -5
  7. {rtfc-0.1.0 → rtfc-0.2.0}/changelog/entry.rst.jinja +1 -1
  8. rtfc-0.2.0/docs/source/changelog.rst +25 -0
  9. rtfc-0.2.0/docs/source/cli.rst +21 -0
  10. {rtfc-0.1.0 → rtfc-0.2.0}/docs/source/conf.py +24 -15
  11. {rtfc-0.1.0 → rtfc-0.2.0}/docs/source/configuration.rst +40 -4
  12. rtfc-0.2.0/docs/source/export.rst +88 -0
  13. {rtfc-0.1.0 → rtfc-0.2.0}/docs/source/index.rst +1 -0
  14. {rtfc-0.1.0 → rtfc-0.2.0}/docs/source/usage.rst +26 -7
  15. {rtfc-0.1.0 → rtfc-0.2.0}/prek.toml +1 -1
  16. {rtfc-0.1.0 → rtfc-0.2.0}/pyproject.toml +11 -1
  17. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_changelog.py +7 -7
  18. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_cli.py +30 -6
  19. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_config.py +47 -4
  20. rtfc-0.2.0/src/rtfc/_export/__init__.py +130 -0
  21. rtfc-0.2.0/src/rtfc/_export/_sphinx.py +299 -0
  22. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_format/base.py +8 -7
  23. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_format/rst.py +5 -0
  24. rtfc-0.2.0/src/rtfc/_render/__init__.py +17 -0
  25. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_render/base.py +4 -4
  26. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_render/jinja.py +3 -3
  27. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_validation.py +35 -0
  28. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/sphinx.py +2 -2
  29. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_cli.py +1 -1
  30. rtfc-0.2.0/tests/test_export.py +179 -0
  31. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_render.py +22 -22
  32. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_validation.py +54 -0
  33. {rtfc-0.1.0 → rtfc-0.2.0}/uv.lock +4 -4
  34. rtfc-0.1.0/DESIGN.md +0 -188
  35. rtfc-0.1.0/PLAN.md +0 -16
  36. rtfc-0.1.0/changelog/aa9e0244.feature.rtfc +0 -6
  37. rtfc-0.1.0/docs/source/changelog.rst +0 -8
  38. rtfc-0.1.0/docs/source/cli.rst +0 -12
  39. rtfc-0.1.0/src/rtfc/_render/__init__.py +0 -15
  40. {rtfc-0.1.0 → rtfc-0.2.0}/.github/workflows/lint.yml +0 -0
  41. {rtfc-0.1.0 → rtfc-0.2.0}/LICENSE +0 -0
  42. {rtfc-0.1.0 → rtfc-0.2.0}/docs/Makefile +0 -0
  43. {rtfc-0.1.0 → rtfc-0.2.0}/docs/make.bat +0 -0
  44. {rtfc-0.1.0 → rtfc-0.2.0}/docs/source/sphinx.rst +0 -0
  45. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/__init__.py +0 -0
  46. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/__main__.py +0 -0
  47. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_entry.py +0 -0
  48. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/_format/__init__.py +0 -0
  49. {rtfc-0.1.0 → rtfc-0.2.0}/src/rtfc/py.typed +0 -0
  50. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_changelog.py +0 -0
  51. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_config.py +0 -0
  52. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_entry.py +0 -0
  53. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_format.py +0 -0
  54. {rtfc-0.1.0 → rtfc-0.2.0}/tests/test_sphinx.py +0 -0
@@ -31,7 +31,7 @@ jobs:
31
31
 
32
32
  - name: Install tox
33
33
  run: uv tool install --managed-python --python 3.13 tox --with tox-uv --with tox-gh
34
-
34
+
35
35
  - name: Install Python ${{ matrix.python-version }}
36
36
  run: uv python install --managed-python ${{ matrix.python-version }}
37
37
 
@@ -53,6 +53,7 @@ jobs:
53
53
  uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
54
54
  with:
55
55
  python-version: '3.14'
56
+ enable-cache: true # zizmor: ignore[cache-poisoning] (Job does not produce release artifacts and does not have sensitive permissions)
56
57
 
57
58
  - name: Install dependencies
58
59
  run: uv sync --group docs
@@ -65,8 +66,7 @@ jobs:
65
66
  run: |
66
67
  uv run sphinx-build --builder linkcheck --fail-on-warning "source" "build"
67
68
  uv run sphinx-build --builder html --fail-on-warning "source" "build"
68
- working-directory:
69
- ./docs
69
+ working-directory: ./docs
70
70
 
71
71
  build:
72
72
  name: Build project
@@ -197,9 +197,9 @@ cython_debug/
197
197
  .abstra/
198
198
 
199
199
  # Visual Studio Code
200
- # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
200
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
201
201
  # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
202
- # and can be added to the global gitignore or merged into this file. However, if you prefer,
202
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
203
203
  # you could uncomment the following to ignore the entire vscode folder
204
204
  # .vscode/
205
205
  # Temporary file for partial code execution
@@ -9,7 +9,7 @@ version: 2
9
9
  build:
10
10
  os: ubuntu-24.04
11
11
  tools:
12
- python: "3.14"
12
+ python: '3.14'
13
13
  # https://docs.readthedocs.com/platform/stable/build-customization.html#install-dependencies-with-uv
14
14
  jobs:
15
15
  pre_create_environment:
@@ -0,0 +1,5 @@
1
+ formatter:
2
+ type: basic
3
+ retain_line_breaks_single: true
4
+ scan_folded_as_literal: true
5
+ force_quote_style: single
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: rtfc
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Author-email: Victorien <contact@vctrn.dev>
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -28,13 +28,13 @@ rtfc
28
28
 
29
29
  |Pythons| |PyPI| |Docs| |Ruff|
30
30
 
31
- .. |Pythons| image:: https://img.shields.io/pypi/pyversions/rdfm.svg
31
+ .. |Pythons| image:: https://img.shields.io/pypi/pyversions/rtfc.svg
32
32
  :alt: Supported Python versions
33
- :target: https://pypi.org/project/rdfm/
33
+ :target: https://pypi.org/project/rtfc/
34
34
 
35
- .. |PyPI| image:: https://img.shields.io/pypi/v/rdfm.svg
35
+ .. |PyPI| image:: https://img.shields.io/pypi/v/rtfc.svg
36
36
  :alt: PyPI - Version
37
- :target: https://pypi.org/project/rdfm/
37
+ :target: https://pypi.org/project/rtfc/
38
38
 
39
39
  .. |Docs| image:: https://img.shields.io/readthedocs/rtfc.svg
40
40
  :alt: Documentation status
@@ -110,7 +110,7 @@ Validate the configuration and the entries, typically in CI:
110
110
  $ rtfc check
111
111
  OK: 1 valid entries
112
112
 
113
- On release, combine the entries into the changelog. The version block is
113
+ On release, combine the entries into the changelog. The release notes are
114
114
  inserted after the marker, and the entry files are deleted:
115
115
 
116
116
  .. code:: console
@@ -4,13 +4,13 @@ rtfc
4
4
 
5
5
  |Pythons| |PyPI| |Docs| |Ruff|
6
6
 
7
- .. |Pythons| image:: https://img.shields.io/pypi/pyversions/rdfm.svg
7
+ .. |Pythons| image:: https://img.shields.io/pypi/pyversions/rtfc.svg
8
8
  :alt: Supported Python versions
9
- :target: https://pypi.org/project/rdfm/
9
+ :target: https://pypi.org/project/rtfc/
10
10
 
11
- .. |PyPI| image:: https://img.shields.io/pypi/v/rdfm.svg
11
+ .. |PyPI| image:: https://img.shields.io/pypi/v/rtfc.svg
12
12
  :alt: PyPI - Version
13
- :target: https://pypi.org/project/rdfm/
13
+ :target: https://pypi.org/project/rtfc/
14
14
 
15
15
  .. |Docs| image:: https://img.shields.io/readthedocs/rtfc.svg
16
16
  :alt: Documentation status
@@ -86,7 +86,7 @@ Validate the configuration and the entries, typically in CI:
86
86
  $ rtfc check
87
87
  OK: 1 valid entries
88
88
 
89
- On release, combine the entries into the changelog. The version block is
89
+ On release, combine the entries into the changelog. The release notes are
90
90
  inserted after the marker, and the entry files are deleted:
91
91
 
92
92
  .. code:: console
@@ -1,4 +1,4 @@
1
1
  {% set refs = [] %}
2
2
  {% if metadata.gh_issue %}{% set _ = refs.append("Issue :issue:`%s`" % metadata.gh_issue) %}{% endif %}
3
3
  {% if metadata.gh_pr %}{% set _ = refs.append("PR :pr:`%s`" % metadata.gh_pr) %}{% endif %}
4
- {{ content }}{% if refs %} ({{ refs | join(", ") }}){% endif %}
4
+ {{ content }}{% if refs %} ({{ refs | join(", ") }}).{% endif %}
@@ -0,0 +1,25 @@
1
+ Changelog
2
+ =========
3
+
4
+ .. rtfc-unreleased::
5
+
6
+ These changes are not yet released and are under active development.
7
+
8
+ .. rtfc-insert
9
+
10
+ v0.2.0 (2026-08-29)
11
+ -------------------
12
+
13
+ Features
14
+ ~~~~~~~~
15
+
16
+ - Add the :commands:command:`export <rtfc-export>` command, exporting entries as markdown through the project's sphinx build.
17
+ See :ref:`configuration` for setup.
18
+
19
+ v0.1.0 (2026-08-06)
20
+ -------------------
21
+
22
+ Features
23
+ ~~~~~~~~
24
+
25
+ - Initial release.
@@ -0,0 +1,21 @@
1
+ .. _cli:
2
+
3
+ Command line interface
4
+ ======================
5
+
6
+ All commands require a valid :ref:`configuration <configuration>` in the
7
+ current working directory.
8
+
9
+ .. argparse::
10
+ :module: rtfc._cli
11
+ :func: _docs_parser
12
+ :prog: rtfc
13
+
14
+ Environment variables
15
+ ---------------------
16
+
17
+ .. envvar:: EDITOR
18
+
19
+ The editor ``rtfc new`` opens the created entry in, when ``--content`` is
20
+ not given. When unset, the entry is created with a placeholder content
21
+ to edit afterwards.
@@ -3,13 +3,19 @@
3
3
  # For the full list of built-in configuration values, see the documentation:
4
4
  # https://www.sphinx-doc.org/en/master/usage/configuration.html
5
5
 
6
+ from textwrap import indent
7
+
8
+ from docutils import nodes
9
+ from sphinx.application import Sphinx
10
+ from sphinx.util.docutils import SphinxDirective
11
+
6
12
  # -- Project information -----------------------------------------------------
7
13
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8
14
 
9
- project = 'rtfc'
10
- copyright = '2026-%Y, Victorien'
11
- author = 'Victorien'
12
- release = '0.1.0'
15
+ project = "rtfc"
16
+ copyright = "2026-%Y, Victorien"
17
+ author = "Victorien"
18
+ release = "0.2.0"
13
19
 
14
20
  # -- General configuration ---------------------------------------------------
15
21
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
@@ -25,11 +31,11 @@ extensions = [
25
31
 
26
32
  rtfc_config_directory = "../.."
27
33
 
28
- templates_path = ['_templates']
29
34
  exclude_patterns = []
30
35
 
31
36
  intersphinx_mapping = {
32
37
  "packaging": ("https://packaging.python.org/en/latest", None),
38
+ "sphinx": ("https://www.sphinx-doc.org/en/master", None),
33
39
  }
34
40
 
35
41
  issues_github_path = "Viicos/rtfc"
@@ -37,23 +43,29 @@ issues_github_path = "Viicos/rtfc"
37
43
  # -- Options for HTML output -------------------------------------------------
38
44
  # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
39
45
 
46
+ html_baseurl = "https://rtfc.readthedocs.io/en/latest/"
40
47
  html_theme = "furo"
41
- html_static_path = ['_static']
42
48
  html_theme_options = {
43
49
  "source_repository": "https://github.com/Viicos/rtfc/",
44
50
  "source_branch": "main",
45
51
  "source_directory": "docs/source/",
52
+ "footer_icons": [
53
+ {
54
+ "name": "GitHub",
55
+ "url": "https://github.com/Viicos/rtfc/",
56
+ "html": """
57
+ <svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 16 16">
58
+ <path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
59
+ </svg>
60
+ """,
61
+ "class": "",
62
+ },
63
+ ],
46
64
  }
47
65
 
48
66
 
49
67
  # -- Custom directives --------------------------------------------------------
50
68
 
51
- from textwrap import indent
52
-
53
- from docutils import nodes
54
- from sphinx.application import Sphinx
55
- from sphinx.util.docutils import SphinxDirective
56
-
57
69
 
58
70
  def _pyproject_variant(toml: str) -> str:
59
71
  """Derive the ``pyproject.toml`` form of an ``rtfc.toml`` example."""
@@ -88,6 +100,3 @@ class RtfcConfigExample(SphinxDirective):
88
100
 
89
101
  def setup(app: Sphinx) -> None:
90
102
  app.add_directive("rtfc-config-example", RtfcConfigExample)
91
-
92
- # Workaround for https://github.com/sphinx-doc/sphinx-argparse/issues/98:
93
- app.extensions["sphinxarg.ext"].parallel_read_safe = False
@@ -11,7 +11,7 @@ Relative paths are resolved against the directory the configuration is discovere
11
11
  .. confval:: changelog
12
12
  :type: path
13
13
 
14
- The changelog file version blocks are inserted into on release. Required;
14
+ The changelog file the release notes are inserted into on release. Required;
15
15
  the file must exist and contain the insert marker comment
16
16
  (``.. rtfc-insert`` for the rst format).
17
17
 
@@ -96,12 +96,12 @@ Relative paths are resolved against the directory the configuration is discovere
96
96
  :type: string
97
97
  :default: the template below
98
98
 
99
- The Jinja template rendering a whole version block. The template receives:
99
+ The Jinja template rendering the whole release notes of a version. The template receives:
100
100
 
101
101
  ``header``
102
102
  The already-formatted version header.
103
103
  ``entries``
104
- All the entries of the block.
104
+ All the entries of the release notes.
105
105
  ``sections``
106
106
  The entries grouped by section: the unsectioned group first, then the
107
107
  configured sections in order. Each group has ``id``, ``label``
@@ -146,7 +146,7 @@ Relative paths are resolved against the directory the configuration is discovere
146
146
  :type: path
147
147
  :default: unset
148
148
 
149
- A file containing the version block template, as an alternative to
149
+ A file containing the release notes template, as an alternative to
150
150
  :confval:`render.template`.
151
151
 
152
152
  .. rtfc-config-example::
@@ -179,6 +179,42 @@ Relative paths are resolved against the directory the configuration is discovere
179
179
  [rtfc.render]
180
180
  entry_template_file = "entry.rst.jinja"
181
181
 
182
+ .. confval:: export.<exporter>.engine
183
+ :type: table
184
+
185
+ :ref:`Exporters <export>`, converting the release notes to another format,
186
+ are configured with one table per exporter id. The ``engine`` table selects
187
+ and configures the format engine used to convert the format-specific syntax
188
+ of the entries; its ``name`` key discriminates the engine and its remaining
189
+ keys. The built-in ``markdown``, ``github-markdown`` and ``gitlab-markdown``
190
+ exporters all support the ``sphinx`` engine.
191
+
192
+ .. rtfc-config-example::
193
+
194
+ [rtfc.export.markdown.engine]
195
+ name = "sphinx"
196
+ sphinx_directory = "docs/source"
197
+
198
+ .. confval:: export.<exporter>.engine.sphinx_directory
199
+ :type: path
200
+
201
+ The Sphinx source directory (containing :file:`conf.py`). Required.
202
+
203
+ .. TODO use ``:confval:sphinx:html_baseurl`` once https://github.com/sphinx-doc/sphinx/issues/14117 is fixed.
204
+
205
+ .. confval:: export.<exporter>.engine.base_url
206
+ :type: string
207
+ :default: the ``html_baseurl`` Sphinx configuration value
208
+
209
+ Absolute URL of the published documentation, used to resolve relative links.
210
+
211
+ .. rtfc-config-example::
212
+
213
+ [rtfc.export.markdown.engine]
214
+ name = "sphinx"
215
+ sphinx_directory = "docs/source"
216
+ base_url = "https://rtfc.readthedocs.io/en/latest"
217
+
182
218
  .. seealso::
183
219
 
184
220
  The :ref:`sphinx extension <sphinx_extension>` has its own configuration
@@ -0,0 +1,88 @@
1
+ .. _export:
2
+
3
+ Exporting release notes
4
+ =======================
5
+
6
+ Besides being inserted into the changelog document, the release notes of a
7
+ version can be *exported* to another format (typically markdown).
8
+
9
+ This is particularly useful when publishing release notes in separate places,
10
+ e.g. `GitHub releases <https://docs.github.com/en/repositories/releasing-projects-on-github>`_.
11
+
12
+ rtfc supports multiple exporters (see below). The exporter to use must first be
13
+ :confval:`configured <export.<exporter>.engine>`, e.g. the ``github-markdown``
14
+ exporter with the ``sphinx`` format engine:
15
+
16
+ .. rtfc-config-example::
17
+
18
+ [rtfc.export.github-markdown.engine]
19
+ name = "sphinx"
20
+ sphinx_directory = "docs/source"
21
+
22
+ The :commands:command:`export <rtfc-export>` command can then be used to produce
23
+ the exported release notes:
24
+
25
+ .. code-block:: console
26
+
27
+ $ rtfc export github-markdown --version 1.2.0 > release-notes.md
28
+
29
+ Run the export *before* ``rtfc build``, which deletes the entry files on
30
+ release.
31
+
32
+ Exporters and format engines
33
+ ----------------------------
34
+
35
+ Exporters are responsible for converting changelog entries (present in your
36
+ :confval:`entry directory <directory>`) into a single text block, that can then
37
+ be published separately. An exporter is defined for a specific
38
+ :ref:`documentation format <documentation-format>`, and delegates the conversion
39
+ of the format-specific syntax to a *format engine*.
40
+
41
+ A *format engine* encapsulates the logic required to run your documentation engine/framework.
42
+ While :ref:`formats <documentation-format>` are agnostic of the documentation framework [#f1]_,
43
+ exporters need to use the semantics of your documentation engine, for example to resolve
44
+ references as HTML links.
45
+
46
+ rtfc provides hree built in exporters:
47
+
48
+ ``markdown``
49
+ `CommonMark <https://spec.commonmark.org/>`_ output. Admonitions are
50
+ rendered as block quotes opened by a bold label.
51
+ ``github-markdown``
52
+ `GitHub Flavored Markdown <https://github.github.com/gfm/>`_ output,
53
+ extended with the GitHub markdown extensions. Suitable for
54
+ `GitHub releases <https://docs.github.com/en/repositories/releasing-projects-on-github>`_.
55
+ ``gitlab-markdown``
56
+ `GitLab Flavored Markdown <https://docs.gitlab.com/user/markdown/>`_ output. Suitable for
57
+ `GitHub releases <https://docs.gitlab.com/user/project/releases/>`_.
58
+
59
+ All three support the ``sphinx`` format engine.
60
+
61
+ The sphinx engine
62
+ -----------------
63
+
64
+ The ``sphinx`` engine requires `Sphinx <https://www.sphinx-doc.org/>`_ to be
65
+ installed, and converts the Sphinx-flavored rst of the entries by building
66
+ them through the project's own Sphinx documentation (i.e. by using the project's
67
+ :ref:`Sphinx configuration <sphinx:build-config>`). Headings, paragraphs,
68
+ lists, code blocks, inline markup, links, images and admonitions are
69
+ supported. Other nodes are left as is. Relative links are joined onto
70
+ the :confval:`base URL <export.<exporter>.engine.base_url>` of the
71
+ published documentation.
72
+
73
+ .. rtfc-config-example::
74
+
75
+ [rtfc.export.github-markdown.engine]
76
+ name = "sphinx"
77
+ sphinx_directory = "docs/source"
78
+ base_url = "https://rtfc.readthedocs.io/en/latest"
79
+
80
+ .. note::
81
+
82
+ Each export runs a Sphinx build of the whole project, as resolving
83
+ cross-references requires the complete environment.
84
+
85
+ .. rubric:: Footnotes
86
+
87
+ .. [#f1] For instance, the builtin ``rst`` format doesn't necessarily assume
88
+ `Sphinx <https://www.sphinx-doc.org/>`_ is used.
@@ -16,4 +16,5 @@ rtfc documentation
16
16
  configuration
17
17
  cli
18
18
  sphinx
19
+ export
19
20
  changelog
@@ -29,6 +29,21 @@ The ``[tool.rtfc]`` table can be used in the :file:`pyproject.toml` of your proj
29
29
 
30
30
  ``changelog`` is the only required configuration value. See :ref:`configuration` for more details.
31
31
 
32
+ .. _documentation-format:
33
+
34
+ Documentation format
35
+ --------------------
36
+
37
+ rtfc is not tied to a documentation framework: changelog entries are written
38
+ in the documentation format of your project, and rtfc only combines them
39
+ (their content is never parsed). The :confval:`format` configuration value
40
+ selects the format, which determines the structure rtfc produces (headings,
41
+ list items, the insert marker comment). reStructuredText (``rst``) is built in
42
+ and the default. Other formats can be provided by third-party packages, through
43
+ the ``rtfc.formats`` :ref:`entry point group <packaging:entry-points>`.
44
+
45
+ The examples below use the default ``rst`` format.
46
+
32
47
  Setting up a project
33
48
  --------------------
34
49
 
@@ -55,25 +70,26 @@ Besides the configuration file, rtfc expects two things to exist:
55
70
  Workflow
56
71
  --------
57
72
 
58
- Create a changelog entry along the changes of a pull request. When run from
59
- a terminal, missing values are prompted for, and the entry is opened in
60
- :envvar:`EDITOR`:
73
+ Create a changelog entry along the changes of a pull request with the
74
+ :commands:command:`new <rtfc-new>` command. When run from a terminal,
75
+ missing values are prompted for, and the entry is opened in :envvar:`EDITOR`:
61
76
 
62
77
  .. code-block:: console
63
78
 
64
79
  $ rtfc new --section bugfix --meta gh_issue=123 --content "Fix a bug."
65
80
  Created changelog/d0592011.bugfix.rtfc
66
81
 
67
- Validate the configuration and all entries, typically in CI:
82
+ Validate the configuration and all entries with the :commands:command:`check <rtfc-check>`
83
+ command, typically in CI:
68
84
 
69
85
  .. code-block:: console
70
86
 
71
87
  $ rtfc check
72
88
  OK: 3 valid entries
73
89
 
74
- On release, combine the entries into the changelog. The version block is
75
- inserted after the marker and the entry files are deleted. Use ``--dry-run``
76
- first to preview the block without touching anything:
90
+ On release, combine the entries into the changelog with the :commands:command:`build <rtfc-build>`
91
+ command. The release notes are inserted after the marker and the entry files are deleted. Use
92
+ ``--dry-run`` first to preview the release notes without touching anything:
77
93
 
78
94
  .. code-block:: console
79
95
 
@@ -81,6 +97,9 @@ first to preview the block without touching anything:
81
97
  $ rtfc build --version 1.2.0
82
98
  Updated docs/source/changelog.rst
83
99
 
100
+ Entries can also be :ref:`exported <export>` in alternative formats, e.g. as
101
+ markdown for GitHub or GitLab release notes.
102
+
84
103
  See the :ref:`command line interface reference <cli>` for all options.
85
104
 
86
105
 
@@ -1,7 +1,7 @@
1
1
  [[repos]]
2
2
  repo = "builtin"
3
3
  hooks = [
4
- { id = "end-of-file-fixer", args = ["--fix"] },
4
+ { id = "end-of-file-fixer" },
5
5
  { id = "trailing-whitespace" },
6
6
  ]
7
7
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "rtfc"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  authors = [
9
9
  {name = "Victorien", email = "contact@vctrn.dev"}
10
10
  ]
@@ -35,6 +35,9 @@ dependencies = [
35
35
  [project.scripts]
36
36
  rtfc = "rtfc._cli:main"
37
37
 
38
+ [project.entry-points."sphinx.builders"]
39
+ rtfc-export = "rtfc._export._sphinx"
40
+
38
41
  [dependency-groups]
39
42
  dev = [
40
43
  "pyright",
@@ -95,6 +98,7 @@ ignore = [
95
98
  ]
96
99
 
97
100
  [tool.ruff.lint.per-file-ignores]
101
+ "docs/source/conf.py" = ["E501"]
98
102
  "src/rtfc/_cli.py" = ["T20"]
99
103
 
100
104
  [tool.ruff.lint.isort]
@@ -106,8 +110,14 @@ strict = true
106
110
 
107
111
  [tool.rtfc]
108
112
  changelog = "docs/source/changelog.rst"
113
+
109
114
  [tool.rtfc.render]
110
115
  entry_template_file = "changelog/entry.rst.jinja"
116
+
117
+ [tool.rtfc.export.github-markdown.engine]
118
+ name = "sphinx"
119
+ sphinx_directory = "docs/source"
120
+
111
121
  [tool.rtfc.metadata]
112
122
  gh_issue = {type = "integer"}
113
123
  gh_pr = {type = "integer"}
@@ -1,8 +1,8 @@
1
- """Assembly of version blocks into the changelog document.
1
+ """Assembly of release notes into the changelog document.
2
2
 
3
3
  The changelog document must contain an insert marker (a format comment, e.g.
4
- ``.. rtfc-insert`` for rst): released version blocks are inserted right after
5
- it, newest first.
4
+ ``.. rtfc-insert`` for rst). The release notes of released versions are inserted
5
+ right after it.
6
6
  """
7
7
 
8
8
  from __future__ import annotations
@@ -21,12 +21,12 @@ def _with_trailing_newline(lines: list[str]) -> str:
21
21
  return text if text.endswith("\n") else text + "\n"
22
22
 
23
23
 
24
- def insert_version(changelog: str, block: str, *, fmt: Format) -> str:
25
- """Insert a released version block right after the insert marker.
24
+ def insert_version(changelog: str, notes: str, *, fmt: Format) -> str:
25
+ """Insert the release notes of a version right after the insert marker.
26
26
 
27
27
  Args:
28
28
  changelog: The current changelog text.
29
- block: The rendered version block.
29
+ notes: The rendered release notes.
30
30
  fmt: The documentation format.
31
31
 
32
32
  Raises:
@@ -39,7 +39,7 @@ def insert_version(changelog: str, block: str, *, fmt: Format) -> str:
39
39
  rest = lines[index + 1 :]
40
40
  while rest and not rest[0].strip():
41
41
  rest.pop(0)
42
- inserted = [*lines[: index + 1], "", *block.split("\n")]
42
+ inserted = [*lines[: index + 1], "", *notes.split("\n")]
43
43
  if rest:
44
44
  inserted += ["", *rest]
45
45
  return _with_trailing_newline(inserted)