sphinx-hackerrank 2026.10.30.1__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.
- sphinx_hackerrank-2026.10.30.1/.gitattributes +1 -0
- sphinx_hackerrank-2026.10.30.1/.github/workflows/ci.yml +41 -0
- sphinx_hackerrank-2026.10.30.1/.github/workflows/release.yml +34 -0
- sphinx_hackerrank-2026.10.30.1/.gitignore +10 -0
- sphinx_hackerrank-2026.10.30.1/LICENSE +21 -0
- sphinx_hackerrank-2026.10.30.1/PKG-INFO +185 -0
- sphinx_hackerrank-2026.10.30.1/README.rst +162 -0
- sphinx_hackerrank-2026.10.30.1/examples/minimal/manual/conf.py +18 -0
- sphinx_hackerrank-2026.10.30.1/examples/minimal/manual/index.rst +7 -0
- sphinx_hackerrank-2026.10.30.1/examples/minimal/manual/topics/widgets-mini-map.rst +28 -0
- sphinx_hackerrank-2026.10.30.1/examples/minimal/manual/topics/widgets-mini-map.yml +6 -0
- sphinx_hackerrank-2026.10.30.1/examples/minimal/manual/topics/widgets.rst +37 -0
- sphinx_hackerrank-2026.10.30.1/pyproject.toml +54 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/__init__.py +31 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/builder.py +117 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/html.py +54 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/py.typed +0 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/sections.py +182 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/static/mini_map.css +36 -0
- sphinx_hackerrank-2026.10.30.1/src/sphinx_hackerrank/targets.py +49 -0
- sphinx_hackerrank-2026.10.30.1/tests/conftest.py +1 -0
- sphinx_hackerrank-2026.10.30.1/tests/test_example.py +46 -0
- sphinx_hackerrank-2026.10.30.1/tests/test_html.py +44 -0
- sphinx_hackerrank-2026.10.30.1/tests/test_sections.py +240 -0
- sphinx_hackerrank-2026.10.30.1/tests/test_targets.py +44 -0
- sphinx_hackerrank-2026.10.30.1/tests/wheel_smoke.py +43 -0
- sphinx_hackerrank-2026.10.30.1/uv.lock +1543 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.rst conflict-marker-size=32
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
pull_request:
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
strategy:
|
|
10
|
+
fail-fast: false
|
|
11
|
+
matrix:
|
|
12
|
+
python: ['3.12', '3.13', '3.14']
|
|
13
|
+
os: [ubuntu-latest, windows-latest]
|
|
14
|
+
runs-on: ${{ matrix.os }}
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v7
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: astral-sh/setup-uv@v7
|
|
20
|
+
- run: uv run --locked --python ${{ matrix.python }} pytest --cov --cov-report=term-missing
|
|
21
|
+
- run: uv build
|
|
22
|
+
- run: uv run twine check dist/*
|
|
23
|
+
- name: Install the wheel and build outside the checkout
|
|
24
|
+
run: uv run --python ${{ matrix.python }} python tests/wheel_smoke.py
|
|
25
|
+
lint:
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v7
|
|
29
|
+
with:
|
|
30
|
+
persist-credentials: false
|
|
31
|
+
- uses: astral-sh/setup-uv@v7
|
|
32
|
+
- run: uv run ruff check .
|
|
33
|
+
- run: uv run ruff format --check .
|
|
34
|
+
sphinx-8:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v7
|
|
38
|
+
with:
|
|
39
|
+
persist-credentials: false
|
|
40
|
+
- uses: astral-sh/setup-uv@v7
|
|
41
|
+
- run: uv run --python 3.12 --with 'sphinx==8.2.3' pytest --cov --cov-report=term-missing
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
workflow_dispatch:
|
|
6
|
+
inputs:
|
|
7
|
+
tag:
|
|
8
|
+
description: Release tag to publish
|
|
9
|
+
required: true
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
jobs:
|
|
13
|
+
publish:
|
|
14
|
+
if: vars.PYPI_PUBLISH_ENABLED == 'true'
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
environment: release
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
id-token: write
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v7
|
|
22
|
+
with:
|
|
23
|
+
persist-credentials: false
|
|
24
|
+
ref: ${{ inputs.tag || github.ref_name }}
|
|
25
|
+
- uses: astral-sh/setup-uv@v7
|
|
26
|
+
- run: uv run pytest --cov --cov-report=term-missing
|
|
27
|
+
- run: uv build
|
|
28
|
+
- run: uv run twine check dist/*
|
|
29
|
+
- run: uv run python tests/wheel_smoke.py
|
|
30
|
+
- uses: actions/upload-artifact@v7
|
|
31
|
+
with:
|
|
32
|
+
name: distributions
|
|
33
|
+
path: dist/
|
|
34
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rippling
|
|
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.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sphinx-hackerrank
|
|
3
|
+
Version: 2026.10.30.1
|
|
4
|
+
Summary: Build portable HackerRank interviewer mini-maps from Sphinx documentation
|
|
5
|
+
Project-URL: Source, https://github.com/adamtheturtle/sphinx-hackerrank
|
|
6
|
+
Project-URL: Issues, https://github.com/adamtheturtle/sphinx-hackerrank/issues
|
|
7
|
+
Author-email: Adam Dangoor <adamdangoor@gmail.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Framework :: Sphinx :: Extension
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Requires-Python: >=3.12
|
|
17
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
18
|
+
Requires-Dist: pyyaml>=6
|
|
19
|
+
Requires-Dist: sphinx-jinja2>=0.0.1
|
|
20
|
+
Requires-Dist: sphinx-toolbox<5,>=4.3
|
|
21
|
+
Requires-Dist: sphinx<10,>=8.2
|
|
22
|
+
Description-Content-Type: text/x-rst
|
|
23
|
+
|
|
24
|
+
sphinx-hackerrank
|
|
25
|
+
=================
|
|
26
|
+
|
|
27
|
+
Build portable interviewer mini-maps from maintained Sphinx guides.
|
|
28
|
+
The ``hackerrank`` builder reuses Sphinx's HTML renderer and exports one
|
|
29
|
+
standalone HTML fragment per question and language, plus a local preview index.
|
|
30
|
+
No HackerRank login or API token is required to build or preview.
|
|
31
|
+
|
|
32
|
+
Installation
|
|
33
|
+
------------
|
|
34
|
+
|
|
35
|
+
.. code-block:: console
|
|
36
|
+
|
|
37
|
+
pip install sphinx-hackerrank
|
|
38
|
+
|
|
39
|
+
Built wheels are also published as GitHub release assets:
|
|
40
|
+
|
|
41
|
+
.. code-block:: console
|
|
42
|
+
|
|
43
|
+
pip install https://github.com/adamtheturtle/sphinx-hackerrank/releases/download/2026.10.30.1/sphinx_hackerrank-2026.10.30.1-py3-none-any.whl
|
|
44
|
+
|
|
45
|
+
Enable the installed extension in ``conf.py``:
|
|
46
|
+
|
|
47
|
+
.. code-block:: python
|
|
48
|
+
|
|
49
|
+
extensions = ["sphinx_hackerrank"]
|
|
50
|
+
|
|
51
|
+
No ``sys.path`` changes are needed.
|
|
52
|
+
|
|
53
|
+
Authoring
|
|
54
|
+
---------
|
|
55
|
+
|
|
56
|
+
Keep the full guide and its mini-map RST beside each other. Include native
|
|
57
|
+
sections by exact heading path or an existing RST section label:
|
|
58
|
+
|
|
59
|
+
.. code-block:: rst
|
|
60
|
+
|
|
61
|
+
.. container:: hr-mini-map mini-map-python
|
|
62
|
+
|
|
63
|
+
.. collapse:: Prompt
|
|
64
|
+
|
|
65
|
+
.. mini-map-section:: widgets.rst
|
|
66
|
+
:section: Part 1 / Prompt
|
|
67
|
+
:language: python
|
|
68
|
+
|
|
69
|
+
Use ``:section: #widget-prompt`` for a labelled section and
|
|
70
|
+
``:include-heading:`` to retain the selected section's heading.
|
|
71
|
+
Nested headings become rubrics inside disclosures. Missing or ambiguous
|
|
72
|
+
selections are reported as directive errors; build with ``-W`` to reject them.
|
|
73
|
+
The guide does not need extraction markers or duplicated content.
|
|
74
|
+
|
|
75
|
+
The directive uses native includes, substitutions, and the guide's existing
|
|
76
|
+
Jinja templates. Variants are cached within each mini-map read and discarded
|
|
77
|
+
before Sphinx persists the document tree. Guide and included-file dependencies
|
|
78
|
+
are tracked for incremental builds.
|
|
79
|
+
|
|
80
|
+
Language contexts
|
|
81
|
+
-----------------
|
|
82
|
+
|
|
83
|
+
Configure how each language renders the guide's Jinja context:
|
|
84
|
+
|
|
85
|
+
.. code-block:: python
|
|
86
|
+
|
|
87
|
+
hackerrank_jinja_context = "snippets"
|
|
88
|
+
hackerrank_languages = {
|
|
89
|
+
"python": {
|
|
90
|
+
"name": "Python",
|
|
91
|
+
"context": {"variants": [{"name": "Python", "lexer": "python"}]},
|
|
92
|
+
},
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
``context`` overrides values in the named Jinja context while that variant is
|
|
96
|
+
parsed. The original configuration is restored afterwards.
|
|
97
|
+
``name`` identifies redundant language disclosures to flatten in copied content.
|
|
98
|
+
All other part, category, and test-alternative disclosures remain intact.
|
|
99
|
+
|
|
100
|
+
By default, admonitions are omitted within ``hr-mini-map`` containers.
|
|
101
|
+
Set ``hackerrank_exclude_admonitions = False`` to retain them.
|
|
102
|
+
The original guide's admonitions remain unchanged.
|
|
103
|
+
|
|
104
|
+
Question mappings
|
|
105
|
+
-----------------
|
|
106
|
+
|
|
107
|
+
Create a mapping beside each mini-map, such as ``widgets-mini-map.yml`` beside
|
|
108
|
+
``widgets-mini-map.rst``:
|
|
109
|
+
|
|
110
|
+
.. code-block:: yaml
|
|
111
|
+
|
|
112
|
+
version: 1
|
|
113
|
+
questions:
|
|
114
|
+
- language: python
|
|
115
|
+
name: Widgets - Python
|
|
116
|
+
|
|
117
|
+
The default ``hackerrank_manifest_pattern`` is ``**/*-mini-map.yml``, relative
|
|
118
|
+
to Sphinx's source directory. Nested directories and custom source layouts are
|
|
119
|
+
supported. Extra fields such as question IDs can be managed by your publishing
|
|
120
|
+
tool; the builder reads only the language and name.
|
|
121
|
+
|
|
122
|
+
Build and preview
|
|
123
|
+
-----------------
|
|
124
|
+
|
|
125
|
+
.. code-block:: console
|
|
126
|
+
|
|
127
|
+
sphinx-build -W -b hackerrank docs build/hackerrank
|
|
128
|
+
|
|
129
|
+
Open ``build/hackerrank/mini-maps/index.html`` to select a question and language.
|
|
130
|
+
Each preview uses the same self-contained HTML that can be saved as HackerRank
|
|
131
|
+
interviewer notes. Native disclosure elements work without JavaScript.
|
|
132
|
+
The builder also produces ordinary themed HTML pages. The extension's directives
|
|
133
|
+
work in the standard ``html`` builder too.
|
|
134
|
+
|
|
135
|
+
Sphinx's native ``only`` directive can select ``builder_hackerrank``,
|
|
136
|
+
``builder_html``, or the shared ``html`` format tag.
|
|
137
|
+
|
|
138
|
+
Source links
|
|
139
|
+
------------
|
|
140
|
+
|
|
141
|
+
By default, links to full guide pages point back into the local HTML build.
|
|
142
|
+
To target a hosted documentation or source site, configure:
|
|
143
|
+
|
|
144
|
+
.. code-block:: python
|
|
145
|
+
|
|
146
|
+
hackerrank_source_url = "https://example.org/guides/"
|
|
147
|
+
hackerrank_source_suffix = ".html"
|
|
148
|
+
hackerrank_source_anchors = True
|
|
149
|
+
|
|
150
|
+
A source repository can use a different suffix, such as ``.rst``, and disable
|
|
151
|
+
anchors. External URLs and links within a fragment are retained.
|
|
152
|
+
|
|
153
|
+
Publishing
|
|
154
|
+
----------
|
|
155
|
+
|
|
156
|
+
Publishing is separate from rendering. This package does not call the HackerRank
|
|
157
|
+
API or manage credentials, question identities, candidate prompts, or projects.
|
|
158
|
+
Your publishing tool can read the generated fragments and verify saved notes.
|
|
159
|
+
|
|
160
|
+
Development
|
|
161
|
+
-----------
|
|
162
|
+
|
|
163
|
+
.. code-block:: console
|
|
164
|
+
|
|
165
|
+
uv run pytest --cov --cov-report=term-missing
|
|
166
|
+
uv run ruff check .
|
|
167
|
+
uv run ruff format --check .
|
|
168
|
+
uv build
|
|
169
|
+
uv run python tests/wheel_smoke.py
|
|
170
|
+
|
|
171
|
+
The minimal example under ``examples/minimal/manual`` uses a custom Jinja context
|
|
172
|
+
and nested guide files. The wheel smoke test installs the built wheel into a
|
|
173
|
+
fresh environment and builds that example outside the checkout.
|
|
174
|
+
|
|
175
|
+
To release, update the version in ``pyproject.toml`` and
|
|
176
|
+
``src/sphinx_hackerrank/__init__.py``, then publish a matching GitHub release.
|
|
177
|
+
The release workflow builds and checks distributions before uploading with a
|
|
178
|
+
PyPI trusted publisher configured for ``release.yml`` and environment ``release``.
|
|
179
|
+
Set the repository variable ``PYPI_PUBLISH_ENABLED`` to ``true`` after configuring
|
|
180
|
+
the publisher. The workflow can also be dispatched with a release ``tag``.
|
|
181
|
+
|
|
182
|
+
License
|
|
183
|
+
-------
|
|
184
|
+
|
|
185
|
+
MIT. See ``LICENSE``.
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
sphinx-hackerrank
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
Build portable interviewer mini-maps from maintained Sphinx guides.
|
|
5
|
+
The ``hackerrank`` builder reuses Sphinx's HTML renderer and exports one
|
|
6
|
+
standalone HTML fragment per question and language, plus a local preview index.
|
|
7
|
+
No HackerRank login or API token is required to build or preview.
|
|
8
|
+
|
|
9
|
+
Installation
|
|
10
|
+
------------
|
|
11
|
+
|
|
12
|
+
.. code-block:: console
|
|
13
|
+
|
|
14
|
+
pip install sphinx-hackerrank
|
|
15
|
+
|
|
16
|
+
Built wheels are also published as GitHub release assets:
|
|
17
|
+
|
|
18
|
+
.. code-block:: console
|
|
19
|
+
|
|
20
|
+
pip install https://github.com/adamtheturtle/sphinx-hackerrank/releases/download/2026.10.30.1/sphinx_hackerrank-2026.10.30.1-py3-none-any.whl
|
|
21
|
+
|
|
22
|
+
Enable the installed extension in ``conf.py``:
|
|
23
|
+
|
|
24
|
+
.. code-block:: python
|
|
25
|
+
|
|
26
|
+
extensions = ["sphinx_hackerrank"]
|
|
27
|
+
|
|
28
|
+
No ``sys.path`` changes are needed.
|
|
29
|
+
|
|
30
|
+
Authoring
|
|
31
|
+
---------
|
|
32
|
+
|
|
33
|
+
Keep the full guide and its mini-map RST beside each other. Include native
|
|
34
|
+
sections by exact heading path or an existing RST section label:
|
|
35
|
+
|
|
36
|
+
.. code-block:: rst
|
|
37
|
+
|
|
38
|
+
.. container:: hr-mini-map mini-map-python
|
|
39
|
+
|
|
40
|
+
.. collapse:: Prompt
|
|
41
|
+
|
|
42
|
+
.. mini-map-section:: widgets.rst
|
|
43
|
+
:section: Part 1 / Prompt
|
|
44
|
+
:language: python
|
|
45
|
+
|
|
46
|
+
Use ``:section: #widget-prompt`` for a labelled section and
|
|
47
|
+
``:include-heading:`` to retain the selected section's heading.
|
|
48
|
+
Nested headings become rubrics inside disclosures. Missing or ambiguous
|
|
49
|
+
selections are reported as directive errors; build with ``-W`` to reject them.
|
|
50
|
+
The guide does not need extraction markers or duplicated content.
|
|
51
|
+
|
|
52
|
+
The directive uses native includes, substitutions, and the guide's existing
|
|
53
|
+
Jinja templates. Variants are cached within each mini-map read and discarded
|
|
54
|
+
before Sphinx persists the document tree. Guide and included-file dependencies
|
|
55
|
+
are tracked for incremental builds.
|
|
56
|
+
|
|
57
|
+
Language contexts
|
|
58
|
+
-----------------
|
|
59
|
+
|
|
60
|
+
Configure how each language renders the guide's Jinja context:
|
|
61
|
+
|
|
62
|
+
.. code-block:: python
|
|
63
|
+
|
|
64
|
+
hackerrank_jinja_context = "snippets"
|
|
65
|
+
hackerrank_languages = {
|
|
66
|
+
"python": {
|
|
67
|
+
"name": "Python",
|
|
68
|
+
"context": {"variants": [{"name": "Python", "lexer": "python"}]},
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
``context`` overrides values in the named Jinja context while that variant is
|
|
73
|
+
parsed. The original configuration is restored afterwards.
|
|
74
|
+
``name`` identifies redundant language disclosures to flatten in copied content.
|
|
75
|
+
All other part, category, and test-alternative disclosures remain intact.
|
|
76
|
+
|
|
77
|
+
By default, admonitions are omitted within ``hr-mini-map`` containers.
|
|
78
|
+
Set ``hackerrank_exclude_admonitions = False`` to retain them.
|
|
79
|
+
The original guide's admonitions remain unchanged.
|
|
80
|
+
|
|
81
|
+
Question mappings
|
|
82
|
+
-----------------
|
|
83
|
+
|
|
84
|
+
Create a mapping beside each mini-map, such as ``widgets-mini-map.yml`` beside
|
|
85
|
+
``widgets-mini-map.rst``:
|
|
86
|
+
|
|
87
|
+
.. code-block:: yaml
|
|
88
|
+
|
|
89
|
+
version: 1
|
|
90
|
+
questions:
|
|
91
|
+
- language: python
|
|
92
|
+
name: Widgets - Python
|
|
93
|
+
|
|
94
|
+
The default ``hackerrank_manifest_pattern`` is ``**/*-mini-map.yml``, relative
|
|
95
|
+
to Sphinx's source directory. Nested directories and custom source layouts are
|
|
96
|
+
supported. Extra fields such as question IDs can be managed by your publishing
|
|
97
|
+
tool; the builder reads only the language and name.
|
|
98
|
+
|
|
99
|
+
Build and preview
|
|
100
|
+
-----------------
|
|
101
|
+
|
|
102
|
+
.. code-block:: console
|
|
103
|
+
|
|
104
|
+
sphinx-build -W -b hackerrank docs build/hackerrank
|
|
105
|
+
|
|
106
|
+
Open ``build/hackerrank/mini-maps/index.html`` to select a question and language.
|
|
107
|
+
Each preview uses the same self-contained HTML that can be saved as HackerRank
|
|
108
|
+
interviewer notes. Native disclosure elements work without JavaScript.
|
|
109
|
+
The builder also produces ordinary themed HTML pages. The extension's directives
|
|
110
|
+
work in the standard ``html`` builder too.
|
|
111
|
+
|
|
112
|
+
Sphinx's native ``only`` directive can select ``builder_hackerrank``,
|
|
113
|
+
``builder_html``, or the shared ``html`` format tag.
|
|
114
|
+
|
|
115
|
+
Source links
|
|
116
|
+
------------
|
|
117
|
+
|
|
118
|
+
By default, links to full guide pages point back into the local HTML build.
|
|
119
|
+
To target a hosted documentation or source site, configure:
|
|
120
|
+
|
|
121
|
+
.. code-block:: python
|
|
122
|
+
|
|
123
|
+
hackerrank_source_url = "https://example.org/guides/"
|
|
124
|
+
hackerrank_source_suffix = ".html"
|
|
125
|
+
hackerrank_source_anchors = True
|
|
126
|
+
|
|
127
|
+
A source repository can use a different suffix, such as ``.rst``, and disable
|
|
128
|
+
anchors. External URLs and links within a fragment are retained.
|
|
129
|
+
|
|
130
|
+
Publishing
|
|
131
|
+
----------
|
|
132
|
+
|
|
133
|
+
Publishing is separate from rendering. This package does not call the HackerRank
|
|
134
|
+
API or manage credentials, question identities, candidate prompts, or projects.
|
|
135
|
+
Your publishing tool can read the generated fragments and verify saved notes.
|
|
136
|
+
|
|
137
|
+
Development
|
|
138
|
+
-----------
|
|
139
|
+
|
|
140
|
+
.. code-block:: console
|
|
141
|
+
|
|
142
|
+
uv run pytest --cov --cov-report=term-missing
|
|
143
|
+
uv run ruff check .
|
|
144
|
+
uv run ruff format --check .
|
|
145
|
+
uv build
|
|
146
|
+
uv run python tests/wheel_smoke.py
|
|
147
|
+
|
|
148
|
+
The minimal example under ``examples/minimal/manual`` uses a custom Jinja context
|
|
149
|
+
and nested guide files. The wheel smoke test installs the built wheel into a
|
|
150
|
+
fresh environment and builds that example outside the checkout.
|
|
151
|
+
|
|
152
|
+
To release, update the version in ``pyproject.toml`` and
|
|
153
|
+
``src/sphinx_hackerrank/__init__.py``, then publish a matching GitHub release.
|
|
154
|
+
The release workflow builds and checks distributions before uploading with a
|
|
155
|
+
PyPI trusted publisher configured for ``release.yml`` and environment ``release``.
|
|
156
|
+
Set the repository variable ``PYPI_PUBLISH_ENABLED`` to ``true`` after configuring
|
|
157
|
+
the publisher. The workflow can also be dispatched with a release ``tag``.
|
|
158
|
+
|
|
159
|
+
License
|
|
160
|
+
-------
|
|
161
|
+
|
|
162
|
+
MIT. See ``LICENSE``.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""A standalone consumer with custom paths and Jinja context names."""
|
|
2
|
+
|
|
3
|
+
extensions = ["sphinx_hackerrank"]
|
|
4
|
+
project = "Widget exercise"
|
|
5
|
+
exclude_patterns = []
|
|
6
|
+
jinja2_contexts = {
|
|
7
|
+
"snippets": {
|
|
8
|
+
"variants": [
|
|
9
|
+
{"name": "Python", "lexer": "python", "prompt": "print('widget')"},
|
|
10
|
+
{"name": "JavaScript", "lexer": "javascript", "prompt": "console.log('widget');"},
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
hackerrank_jinja_context = "snippets"
|
|
15
|
+
hackerrank_languages = {
|
|
16
|
+
variant["lexer"]: {"name": variant["name"], "context": {"variants": [variant]}}
|
|
17
|
+
for variant in jinja2_contexts["snippets"]["variants"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
Widget mini-map
|
|
2
|
+
===============
|
|
3
|
+
|
|
4
|
+
.. jinja:: snippets
|
|
5
|
+
|
|
6
|
+
{% for variant in variants %}
|
|
7
|
+
|
|
8
|
+
.. container:: hr-mini-map mini-map-{{ variant.lexer }}
|
|
9
|
+
|
|
10
|
+
.. rubric:: Widgets: {{ variant.name }}
|
|
11
|
+
|
|
12
|
+
See the :doc:`full guide <widgets>`.
|
|
13
|
+
|
|
14
|
+
.. collapse:: Part 1
|
|
15
|
+
|
|
16
|
+
.. collapse:: Prompt
|
|
17
|
+
|
|
18
|
+
.. mini-map-section:: widgets.rst
|
|
19
|
+
:section: #widget-prompt
|
|
20
|
+
:language: {{ variant.lexer }}
|
|
21
|
+
|
|
22
|
+
.. collapse:: FAQ
|
|
23
|
+
|
|
24
|
+
.. mini-map-section:: widgets.rst
|
|
25
|
+
:section: Part 1 / FAQ
|
|
26
|
+
:language: {{ variant.lexer }}
|
|
27
|
+
|
|
28
|
+
{% endfor %}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
Widgets
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
Part 1
|
|
5
|
+
------
|
|
6
|
+
|
|
7
|
+
.. _widget-prompt:
|
|
8
|
+
|
|
9
|
+
Prompt
|
|
10
|
+
~~~~~~
|
|
11
|
+
|
|
12
|
+
Print a widget's name.
|
|
13
|
+
|
|
14
|
+
.. jinja:: snippets
|
|
15
|
+
|
|
16
|
+
{% for variant in variants %}
|
|
17
|
+
|
|
18
|
+
.. collapse:: {{ variant.name }}
|
|
19
|
+
|
|
20
|
+
.. code-block:: {{ variant.lexer }}
|
|
21
|
+
|
|
22
|
+
{{ variant.prompt }}
|
|
23
|
+
|
|
24
|
+
{% endfor %}
|
|
25
|
+
|
|
26
|
+
.. collapse:: Alternate inputs
|
|
27
|
+
|
|
28
|
+
.. code-block:: text
|
|
29
|
+
|
|
30
|
+
widget = ""
|
|
31
|
+
|
|
32
|
+
.. tip:: Ask the participant to explain their choice.
|
|
33
|
+
|
|
34
|
+
FAQ
|
|
35
|
+
~~~
|
|
36
|
+
|
|
37
|
+
The widget's name is always a string.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "sphinx-hackerrank"
|
|
7
|
+
version = "2026.10.30.1"
|
|
8
|
+
description = "Build portable HackerRank interviewer mini-maps from Sphinx documentation"
|
|
9
|
+
readme = "README.rst"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{name = "Adam Dangoor", email = "adamdangoor@gmail.com"}]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Framework :: Sphinx :: Extension",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Programming Language :: Python :: 3.13",
|
|
19
|
+
"Programming Language :: Python :: 3.14",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"sphinx>=8.2,<10",
|
|
23
|
+
"beautifulsoup4>=4.12",
|
|
24
|
+
"pyyaml>=6",
|
|
25
|
+
"sphinx-jinja2>=0.0.1",
|
|
26
|
+
"sphinx-toolbox>=4.3,<5",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Source = "https://github.com/adamtheturtle/sphinx-hackerrank"
|
|
31
|
+
Issues = "https://github.com/adamtheturtle/sphinx-hackerrank/issues"
|
|
32
|
+
|
|
33
|
+
[dependency-groups]
|
|
34
|
+
dev = ["pytest>=9", "pytest-cov>=7", "ruff>=0.17", "build>=1.2", "twine>=6"]
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
target-version = "py312"
|
|
38
|
+
line-length = 120
|
|
39
|
+
lint.select = ["E", "F", "I", "UP", "B"]
|
|
40
|
+
|
|
41
|
+
[tool.pytest.ini_options]
|
|
42
|
+
testpaths = ["tests"]
|
|
43
|
+
|
|
44
|
+
[tool.coverage.run]
|
|
45
|
+
branch = true
|
|
46
|
+
source = ["sphinx_hackerrank"]
|
|
47
|
+
|
|
48
|
+
[tool.coverage.report]
|
|
49
|
+
show_missing = true
|
|
50
|
+
fail_under = 100
|
|
51
|
+
exclude_also = ["if TYPE_CHECKING:"]
|
|
52
|
+
|
|
53
|
+
[tool.hatch.build.targets.wheel]
|
|
54
|
+
packages = ["src/sphinx_hackerrank"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Sphinx extension for portable HackerRank interviewer mini-maps."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
7
|
+
from sphinx_hackerrank.builder import HackerRankBuilder
|
|
8
|
+
from sphinx_hackerrank.sections import MiniMapSection, discard_guide_cache, simplify_mini_map
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from sphinx.application import Sphinx
|
|
12
|
+
|
|
13
|
+
__version__ = "2026.10.30.1"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def setup(app: Sphinx) -> dict[str, object]:
|
|
17
|
+
"""Register the builder, directive, and project-independent settings."""
|
|
18
|
+
app.setup_extension("sphinx_jinja2")
|
|
19
|
+
app.setup_extension("sphinx_toolbox.collapse")
|
|
20
|
+
app.add_config_value("hackerrank_manifest_pattern", "**/*-mini-map.yml", "env", types=str)
|
|
21
|
+
app.add_config_value("hackerrank_languages", {}, "env", types=dict)
|
|
22
|
+
app.add_config_value("hackerrank_jinja_context", "languages", "env", types=str)
|
|
23
|
+
app.add_config_value("hackerrank_source_url", None, "html", types=(str, type(None)))
|
|
24
|
+
app.add_config_value("hackerrank_source_suffix", ".html", "html", types=str)
|
|
25
|
+
app.add_config_value("hackerrank_source_anchors", True, "html", types=bool)
|
|
26
|
+
app.add_config_value("hackerrank_exclude_admonitions", True, "html", types=bool)
|
|
27
|
+
app.add_builder(HackerRankBuilder)
|
|
28
|
+
app.add_directive("mini-map-section", MiniMapSection)
|
|
29
|
+
app.connect("doctree-read", discard_guide_cache)
|
|
30
|
+
app.connect("doctree-resolved", simplify_mini_map)
|
|
31
|
+
return {"version": __version__, "parallel_read_safe": True, "parallel_write_safe": True}
|