nortl 1.4.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 (115) hide show
  1. nortl-1.4.0/.gitattributes +3 -0
  2. nortl-1.4.0/.github/workflows/deploy_pages.yml +31 -0
  3. nortl-1.4.0/.github/workflows/test_and_publish.yml +39 -0
  4. nortl-1.4.0/.gitignore +18 -0
  5. nortl-1.4.0/.python-version +1 -0
  6. nortl-1.4.0/.vscode/extensions.json +8 -0
  7. nortl-1.4.0/.vscode/settings.json +23 -0
  8. nortl-1.4.0/LICENSE +11 -0
  9. nortl-1.4.0/PKG-INFO +105 -0
  10. nortl-1.4.0/README.md +89 -0
  11. nortl-1.4.0/docs/scripts/gen_ref_pages.py +70 -0
  12. nortl-1.4.0/docs/src/assets/Overview.svg +385 -0
  13. nortl-1.4.0/docs/src/assets/logo.svg +18 -0
  14. nortl-1.4.0/docs/src/index.md +52 -0
  15. nortl-1.4.0/docs/src/stylesheets/extra.css +11 -0
  16. nortl-1.4.0/docs/src/stylesheets/mkdocstrings.css +91 -0
  17. nortl-1.4.0/docs/src/user_guide/assets/Engine_Model.svg +451 -0
  18. nortl-1.4.0/docs/src/user_guide/assets/Stategraph_condition.svg +342 -0
  19. nortl-1.4.0/docs/src/user_guide/data_model.md +74 -0
  20. nortl-1.4.0/docs/src/user_guide/engine.md +158 -0
  21. nortl-1.4.0/docs/src/user_guide/installation.md +40 -0
  22. nortl-1.4.0/docs/templates/python/material/module.html.jinja +15 -0
  23. nortl-1.4.0/mkdocs.yml +178 -0
  24. nortl-1.4.0/pyproject.toml +129 -0
  25. nortl-1.4.0/src/nortl/__init__.py +85 -0
  26. nortl-1.4.0/src/nortl/components/__init__.py +8 -0
  27. nortl-1.4.0/src/nortl/components/channel.py +132 -0
  28. nortl-1.4.0/src/nortl/components/timer.py +73 -0
  29. nortl-1.4.0/src/nortl/core/__init__.py +40 -0
  30. nortl-1.4.0/src/nortl/core/checker.py +135 -0
  31. nortl-1.4.0/src/nortl/core/common/__init__.py +4 -0
  32. nortl-1.4.0/src/nortl/core/common/access.py +25 -0
  33. nortl-1.4.0/src/nortl/core/common/debug.py +6 -0
  34. nortl-1.4.0/src/nortl/core/common/naming_helper.py +33 -0
  35. nortl-1.4.0/src/nortl/core/constructs/__init__.py +13 -0
  36. nortl-1.4.0/src/nortl/core/constructs/condition.py +143 -0
  37. nortl-1.4.0/src/nortl/core/constructs/fork_join.py +84 -0
  38. nortl-1.4.0/src/nortl/core/constructs/loop.py +138 -0
  39. nortl-1.4.0/src/nortl/core/engine.py +575 -0
  40. nortl-1.4.0/src/nortl/core/exceptions.py +139 -0
  41. nortl-1.4.0/src/nortl/core/manager/__init__.py +6 -0
  42. nortl-1.4.0/src/nortl/core/manager/scratch_manager.py +128 -0
  43. nortl-1.4.0/src/nortl/core/manager/signal_manager.py +71 -0
  44. nortl-1.4.0/src/nortl/core/modifiers.py +136 -0
  45. nortl-1.4.0/src/nortl/core/module.py +181 -0
  46. nortl-1.4.0/src/nortl/core/operations.py +834 -0
  47. nortl-1.4.0/src/nortl/core/parameter.py +88 -0
  48. nortl-1.4.0/src/nortl/core/process.py +451 -0
  49. nortl-1.4.0/src/nortl/core/protocols.py +628 -0
  50. nortl-1.4.0/src/nortl/core/renderers/__init__.py +0 -0
  51. nortl-1.4.0/src/nortl/core/renderers/operations/__init__.py +34 -0
  52. nortl-1.4.0/src/nortl/core/renderers/operations/arithmetics.py +38 -0
  53. nortl-1.4.0/src/nortl/core/renderers/operations/base.py +111 -0
  54. nortl-1.4.0/src/nortl/core/renderers/operations/comparison.py +44 -0
  55. nortl-1.4.0/src/nortl/core/renderers/operations/logic.py +38 -0
  56. nortl-1.4.0/src/nortl/core/renderers/operations/misc.py +26 -0
  57. nortl-1.4.0/src/nortl/core/renderers/operations/slice.py +30 -0
  58. nortl-1.4.0/src/nortl/core/signal.py +878 -0
  59. nortl-1.4.0/src/nortl/core/state.py +201 -0
  60. nortl-1.4.0/src/nortl/py.typed +0 -0
  61. nortl-1.4.0/src/nortl/renderer/__init__.py +5 -0
  62. nortl-1.4.0/src/nortl/renderer/mermaid_renderer.py +38 -0
  63. nortl-1.4.0/src/nortl/renderer/networkx_renderer.py +29 -0
  64. nortl-1.4.0/src/nortl/renderer/verilog_renderer.py +325 -0
  65. nortl-1.4.0/src/nortl/renderer/verilog_utils/__init__.py +6 -0
  66. nortl-1.4.0/src/nortl/renderer/verilog_utils/formatter.py +29 -0
  67. nortl-1.4.0/src/nortl/renderer/verilog_utils/process.py +226 -0
  68. nortl-1.4.0/src/nortl/renderer/verilog_utils/structural.py +146 -0
  69. nortl-1.4.0/src/nortl/renderer/verilog_utils/utils.py +23 -0
  70. nortl-1.4.0/src/nortl/utils/__init__.py +0 -0
  71. nortl-1.4.0/src/nortl/utils/parse_utils.py +37 -0
  72. nortl-1.4.0/src/nortl/utils/templates/testbench.sv +41 -0
  73. nortl-1.4.0/src/nortl/utils/test_wrapper.py +218 -0
  74. nortl-1.4.0/src/nortl/utils/type_aliases.py +15 -0
  75. nortl-1.4.0/src/nortl/verilog_library/__init__.py +74 -0
  76. nortl-1.4.0/src/nortl/verilog_library/nortl_clock_gate.sv +20 -0
  77. nortl-1.4.0/src/nortl/verilog_library/nortl_count_down_timer.sv +50 -0
  78. nortl-1.4.0/src/nortl/verilog_library/nortl_delay.sv +66 -0
  79. nortl-1.4.0/src/nortl/verilog_library/nortl_edge_detector.sv +34 -0
  80. nortl-1.4.0/src/nortl/verilog_library/nortl_sync.sv +28 -0
  81. nortl-1.4.0/stubs/.gitkeep +0 -0
  82. nortl-1.4.0/tests/.gitkeep +0 -0
  83. nortl-1.4.0/tests/components/artifacts/.gitignore +1 -0
  84. nortl-1.4.0/tests/components/artifacts/.gitkeep +0 -0
  85. nortl-1.4.0/tests/components/test_channel.py +194 -0
  86. nortl-1.4.0/tests/components/test_timer.py +133 -0
  87. nortl-1.4.0/tests/components/verilog/tb_timer.sv +51 -0
  88. nortl-1.4.0/tests/constructs/artifacts/.gitignore +2 -0
  89. nortl-1.4.0/tests/constructs/artifacts/.gitkeep +0 -0
  90. nortl-1.4.0/tests/constructs/test_access_control.py +217 -0
  91. nortl-1.4.0/tests/constructs/test_fork.py +255 -0
  92. nortl-1.4.0/tests/constructs/verilog/testbench.sv +48 -0
  93. nortl-1.4.0/tests/examples/__init__.py +0 -0
  94. nortl-1.4.0/tests/examples/conftest.py +10 -0
  95. nortl-1.4.0/tests/examples/test_video_controller.py +43 -0
  96. nortl-1.4.0/tests/fsm/artifacts/.gitignore +1 -0
  97. nortl-1.4.0/tests/fsm/artifacts/.gitkeep +0 -0
  98. nortl-1.4.0/tests/fsm/test_fsm.py +316 -0
  99. nortl-1.4.0/tests/fsm/test_scratch_manager.py +230 -0
  100. nortl-1.4.0/tests/fsm/test_verilog_integration.py +483 -0
  101. nortl-1.4.0/tests/fsm/verilog/testbench.sv +48 -0
  102. nortl-1.4.0/tests/operations/__init__.py +0 -0
  103. nortl-1.4.0/tests/operations/conftest.py +42 -0
  104. nortl-1.4.0/tests/operations/test_concat.py +58 -0
  105. nortl-1.4.0/tests/operations/test_const.py +86 -0
  106. nortl-1.4.0/tests/operations/test_logical.py +56 -0
  107. nortl-1.4.0/tests/operations/test_operations.py +199 -0
  108. nortl-1.4.0/tests/renderers/test_mermaid_renderer.py +84 -0
  109. nortl-1.4.0/tests/renderers/test_networkx_renderer.py +88 -0
  110. nortl-1.4.0/tests/test_utils/test_test_wrapper.py +63 -0
  111. nortl-1.4.0/tests/utils/test_compatibility.py +48 -0
  112. nortl-1.4.0/tests/utils/test_condition.py +23 -0
  113. nortl-1.4.0/tests/verilog_utils/test_declaration.py +45 -0
  114. nortl-1.4.0/tox.ini +43 -0
  115. nortl-1.4.0/uv.lock +1185 -0
@@ -0,0 +1,3 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+ *.lock -text
@@ -0,0 +1,31 @@
1
+ name: Build and deploy pages
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ build-and-deploy:
10
+ name: Build and deploy pages
11
+ runs-on: ubuntu-latest
12
+
13
+ permissions:
14
+ pages: write
15
+ id-token: write
16
+
17
+ environment:
18
+ name: github-pages
19
+ url: ${{ steps.deployment.outputs.page_url }}
20
+
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+ - uses: astral-sh/setup-uv@v7
24
+ - name: Build Documentation
25
+ run: uv run mkdocs build --site-dir site --strict
26
+ - name: Upload to GitHub Pages
27
+ uses: actions/upload-pages-artifact@v4
28
+ with:
29
+ path: site
30
+ - name: Deploy to GitHub Pages
31
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,39 @@
1
+ name: Test and Publish to Pypi
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ test:
7
+ name: Run Tests
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v6
11
+ - uses: astral-sh/setup-uv@v7
12
+ - name: Install Icarus Verilog
13
+ run: |
14
+ sudo apt-get -y update
15
+ sudo apt-get -y install iverilog
16
+ - name: Run tox
17
+ run: uv run tox
18
+
19
+ publish:
20
+ name: Publish on Pypi
21
+ needs: test
22
+ runs-on: ubuntu-latest
23
+ environment:
24
+ name: pypi
25
+ url: https://pypi.org/p/nortl
26
+ permissions:
27
+ id-token: write
28
+ contents: read
29
+
30
+ # Only publish to PyPi on tag pushes
31
+ if: github.ref_type == 'tag'
32
+
33
+ steps:
34
+ - uses: actions/checkout@v6
35
+ - uses: astral-sh/setup-uv@v7
36
+ - name: Build Project
37
+ run: uv build
38
+ - name: Publish on Pypi
39
+ run: uv publish
nortl-1.4.0/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ .cache
2
+ .mypy_cache
3
+ .pytest_cache
4
+ .ruff_cache
5
+ .tox
6
+ .venv
7
+ __pycache__
8
+ build
9
+ dist
10
+ reports
11
+ wheels
12
+ docs/site
13
+ .coverage*
14
+ *.py[ocd]
15
+ *.egg-info
16
+ a.out
17
+ scratchpad
18
+ *.vcd
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,8 @@
1
+ {
2
+ "recommendations": [
3
+ "ms-python.python",
4
+ "ms-python.mypy-type-checker",
5
+ "tamasfe.even-better-toml",
6
+ "charliermarsh.ruff"
7
+ ]
8
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "[python]": {
3
+ "editor.defaultFormatter": "charliermarsh.ruff",
4
+ "editor.formatOnSave": true,
5
+ "editor.codeActionsOnSave": {
6
+ "source.organizeImports": "explicit"
7
+ }
8
+ },
9
+ "python.testing.pytestEnabled": true,
10
+ "files.insertFinalNewline": true,
11
+ "files.exclude": {
12
+ "**/__pycache__": true,
13
+ "**/.mypy_cache": true,
14
+ "**/.pytest_cache": true,
15
+ "**/.tox": true,
16
+ "**/.venv": true,
17
+ "**/*.egg-info": true,
18
+ "**/*.pyd": true,
19
+ },
20
+ "files.trimFinalNewlines": true,
21
+ "files.trimTrailingWhitespace": true,
22
+ "mypy-type-checker.importStrategy": "fromEnvironment"
23
+ }
nortl-1.4.0/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright 2026 Institut für Mikroelektronik- und Mechatronik-Systeme gemeinnützige GmbH (IMMS GmbH)
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
nortl-1.4.0/PKG-INFO ADDED
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.4
2
+ Name: nortl
3
+ Version: 1.4.0
4
+ Summary: Not-only RTL.
5
+ Project-URL: Homepage, https://github.com/IMMS-Ilmenau/nortl
6
+ Project-URL: Documentation, https://IMMS-Ilmenau.github.io/nortl
7
+ Author-email: Florian Koegler <florian.koegler@imms.de>, Georg Glaeser <georg.glaeser@imms.de>
8
+ License-File: LICENSE
9
+ Requires-Python: >=3.12
10
+ Requires-Dist: more-itertools>=10.8.0
11
+ Requires-Dist: networkx>=3.4.2
12
+ Provides-Extra: type-stubs
13
+ Requires-Dist: pytest-stub; extra == 'type-stubs'
14
+ Requires-Dist: types-networkx; extra == 'type-stubs'
15
+ Description-Content-Type: text/markdown
16
+
17
+ # noRTL - Hardware design beyond register transfer level
18
+
19
+ **noRTL** (Not-only RTL) is a Python-based code generation framework for designing and implementing hardware description language (HDL) modules, particularly SystemVerilog state machines. It provides a high-level, Pythonic API for describing sets of finite state machines (FSMs) and hardware components with built-in correctness guarantees.
20
+
21
+ **noRTL** aims to make the design of complex digital systems easier by reducing the shortcommings of current hardware description languages that use the register transfer level (RTL) to model digital circuit's behavior. This tool goes beyond this level of abstraction: We digital designers want to describe behavior with cycle-level accuracy but do not want do deal with the complexity of state naming, state coding, starting parallel processes, etc. **noRTL** realizes this tedious part of digital design inside its core.
22
+
23
+ The code that is written for **noRTL** is pure Python code. The **noRTL** package realizes state handling and data structure assembly for you while the Python code is executed. **noRTL** can be understood as a fancy generator that assembles state machines and provides the tooling to render it to SystemVerilog and tools for verifying your code.
24
+
25
+ ## Main ideas
26
+
27
+ **noRTL** is built with the following concepts and ideas.
28
+
29
+ * Each hardware description is an executable Python program. The hardware structure is assembled during execution. There is no need for static code analysis or parsing.
30
+ * There should be no need to declare states explicitely. The number of states is determined during execution of the code.
31
+ * The behavior description should be easily readable and feel procedural. Control structures should work similar to Python equivalents.
32
+ * Checks and Optimizations are to be done during runtime of the Python code. Post-Optimization has not been necessary (yet).
33
+
34
+ ## Installation
35
+
36
+ A prerequisite for noRTL is the availablility of icarus Verilog in your path. This can be installed using your system's package manager or using the *oss-cad-suite* (https://github.com/YosysHQ/oss-cad-suite-build)
37
+
38
+ ### Method 1: Using pip (Public Registry)
39
+
40
+ ```bash
41
+ # Install nortl
42
+ pip install nortl
43
+ ```
44
+
45
+ ### Method 2: Using uv (Recommended)
46
+
47
+ ```bash
48
+ # Clone the repository
49
+ git clone https://github.com/IMMS-Ilmenau/nortl
50
+ cd nortl
51
+
52
+ # Install dependencies
53
+ uv sync
54
+
55
+ # Activate the virtual environment
56
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
57
+ ```
58
+
59
+ ### Method 3: Development Installation
60
+
61
+ For development work, install in editable mode:
62
+
63
+ ```bash
64
+ # Clone the repository
65
+ git clone https://github.com/IMMS-Ilmenau/nortl
66
+ cd nortl
67
+
68
+ # Install development dependencies
69
+ uv sync --all-extras
70
+
71
+ # Activate the virtual environment
72
+ source .venv/bin/activate
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Your First State Machine
78
+
79
+ Let's create a simple state machine that toggles an output based on an input.
80
+
81
+ ```python
82
+ from nortl import Engine, Const
83
+
84
+ # Create an engine with a module name -- Clock and reset signal is automatically included
85
+ engine = Engine("my_first_engine")
86
+
87
+ # Define input and output signals
88
+ enable = engine.define_input("enable", width=1)
89
+ output = engine.define_output("output", width=1, reset_value=0)
90
+
91
+ # Don't define states -- define behavior!
92
+ with engine.while_loop(Const(1)):
93
+ engine.wait_for(enable == 1)
94
+ engine.set(output, 1)
95
+ engine.sync() # Wait one clock cycle
96
+ engine.set(output, 0)
97
+ engine.wait_for(enable == 0)
98
+
99
+ # Generate SystemVerilog code
100
+ from nortl.renderer import VerilogRenderer
101
+ renderer = VerilogRenderer()
102
+ verilog_code = renderer.render(engine)
103
+
104
+ print(verilog_code)
105
+ ```
nortl-1.4.0/README.md ADDED
@@ -0,0 +1,89 @@
1
+ # noRTL - Hardware design beyond register transfer level
2
+
3
+ **noRTL** (Not-only RTL) is a Python-based code generation framework for designing and implementing hardware description language (HDL) modules, particularly SystemVerilog state machines. It provides a high-level, Pythonic API for describing sets of finite state machines (FSMs) and hardware components with built-in correctness guarantees.
4
+
5
+ **noRTL** aims to make the design of complex digital systems easier by reducing the shortcommings of current hardware description languages that use the register transfer level (RTL) to model digital circuit's behavior. This tool goes beyond this level of abstraction: We digital designers want to describe behavior with cycle-level accuracy but do not want do deal with the complexity of state naming, state coding, starting parallel processes, etc. **noRTL** realizes this tedious part of digital design inside its core.
6
+
7
+ The code that is written for **noRTL** is pure Python code. The **noRTL** package realizes state handling and data structure assembly for you while the Python code is executed. **noRTL** can be understood as a fancy generator that assembles state machines and provides the tooling to render it to SystemVerilog and tools for verifying your code.
8
+
9
+ ## Main ideas
10
+
11
+ **noRTL** is built with the following concepts and ideas.
12
+
13
+ * Each hardware description is an executable Python program. The hardware structure is assembled during execution. There is no need for static code analysis or parsing.
14
+ * There should be no need to declare states explicitely. The number of states is determined during execution of the code.
15
+ * The behavior description should be easily readable and feel procedural. Control structures should work similar to Python equivalents.
16
+ * Checks and Optimizations are to be done during runtime of the Python code. Post-Optimization has not been necessary (yet).
17
+
18
+ ## Installation
19
+
20
+ A prerequisite for noRTL is the availablility of icarus Verilog in your path. This can be installed using your system's package manager or using the *oss-cad-suite* (https://github.com/YosysHQ/oss-cad-suite-build)
21
+
22
+ ### Method 1: Using pip (Public Registry)
23
+
24
+ ```bash
25
+ # Install nortl
26
+ pip install nortl
27
+ ```
28
+
29
+ ### Method 2: Using uv (Recommended)
30
+
31
+ ```bash
32
+ # Clone the repository
33
+ git clone https://github.com/IMMS-Ilmenau/nortl
34
+ cd nortl
35
+
36
+ # Install dependencies
37
+ uv sync
38
+
39
+ # Activate the virtual environment
40
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
41
+ ```
42
+
43
+ ### Method 3: Development Installation
44
+
45
+ For development work, install in editable mode:
46
+
47
+ ```bash
48
+ # Clone the repository
49
+ git clone https://github.com/IMMS-Ilmenau/nortl
50
+ cd nortl
51
+
52
+ # Install development dependencies
53
+ uv sync --all-extras
54
+
55
+ # Activate the virtual environment
56
+ source .venv/bin/activate
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Your First State Machine
62
+
63
+ Let's create a simple state machine that toggles an output based on an input.
64
+
65
+ ```python
66
+ from nortl import Engine, Const
67
+
68
+ # Create an engine with a module name -- Clock and reset signal is automatically included
69
+ engine = Engine("my_first_engine")
70
+
71
+ # Define input and output signals
72
+ enable = engine.define_input("enable", width=1)
73
+ output = engine.define_output("output", width=1, reset_value=0)
74
+
75
+ # Don't define states -- define behavior!
76
+ with engine.while_loop(Const(1)):
77
+ engine.wait_for(enable == 1)
78
+ engine.set(output, 1)
79
+ engine.sync() # Wait one clock cycle
80
+ engine.set(output, 0)
81
+ engine.wait_for(enable == 0)
82
+
83
+ # Generate SystemVerilog code
84
+ from nortl.renderer import VerilogRenderer
85
+ renderer = VerilogRenderer()
86
+ verilog_code = renderer.render(engine)
87
+
88
+ print(verilog_code)
89
+ ```
@@ -0,0 +1,70 @@
1
+ """Generate the code reference pages."""
2
+
3
+ from pathlib import Path
4
+ from typing import Sequence
5
+
6
+ import mkdocs_gen_files
7
+
8
+ INIT_TEMPLATE = """
9
+ ::: {identifier}
10
+ options:
11
+ members: [{members}]
12
+ members_order: alphabetical
13
+ """
14
+
15
+
16
+ def find_submodules(dir: Path) -> Sequence[str]:
17
+ """Find submodules within a directory."""
18
+ submodules = []
19
+ for path in dir.iterdir():
20
+ if path.is_dir():
21
+ if (path / '__init__.py').exists():
22
+ submodules.append(path.name)
23
+ elif path.suffix == '.py' and path.stem != '__init__':
24
+ submodules.append(path.stem)
25
+ return sorted(submodules)
26
+
27
+
28
+ def gen_ref_pages():
29
+ nav = mkdocs_gen_files.Nav()
30
+ mod_symbol = '<code class="doc-symbol doc-symbol-nav doc-symbol-module"></code>'
31
+
32
+ root = Path(__file__).parent.parent.parent
33
+ src = root / 'src'
34
+
35
+ for path in sorted(src.rglob('*.py')):
36
+ # Skip Python files that are not in a module
37
+ if not (path.parent / '__init__.py').exists():
38
+ continue
39
+
40
+ module_path = path.relative_to(src).with_suffix('')
41
+ doc_path = path.relative_to(src).with_suffix('.md')
42
+ full_doc_path = Path('reference', doc_path)
43
+
44
+ parts = tuple(module_path.parts)
45
+
46
+ if is_init := parts[-1] == '__init__':
47
+ parts = parts[:-1]
48
+ doc_path = doc_path.with_name('index.md')
49
+ full_doc_path = full_doc_path.with_name('index.md')
50
+ elif parts[-1] == '__main__':
51
+ continue
52
+
53
+ nav_parts = [f'{mod_symbol} {part}' for part in parts]
54
+ nav[tuple(nav_parts)] = doc_path.as_posix()
55
+
56
+ with mkdocs_gen_files.open(full_doc_path, 'w') as fd:
57
+ identifier = '.'.join(parts)
58
+ if is_init:
59
+ text = INIT_TEMPLATE.format(identifier=identifier, members=','.join(find_submodules(path.parent)))
60
+ else:
61
+ text = f'::: {identifier}\n'
62
+ print(text, file=fd)
63
+
64
+ mkdocs_gen_files.set_edit_path(full_doc_path, Path('../../') / path.relative_to(root))
65
+
66
+ with mkdocs_gen_files.open('reference/summary.nav', 'w') as nav_file:
67
+ nav_file.writelines(nav.build_literate_nav())
68
+
69
+
70
+ gen_ref_pages()