mkdocstrings-nim 0.1.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 (99) hide show
  1. mkdocstrings_nim-0.1.0/.gitignore +55 -0
  2. mkdocstrings_nim-0.1.0/LICENSE +21 -0
  3. mkdocstrings_nim-0.1.0/PKG-INFO +116 -0
  4. mkdocstrings_nim-0.1.0/README.md +84 -0
  5. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/__init__.py +2 -0
  6. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/__init__.py +27 -0
  7. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/collector.py +267 -0
  8. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/docstring.py +129 -0
  9. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/extractor/extractor.nim +244 -0
  10. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/extractor/nimdocinfo.nim +16 -0
  11. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/handler.py +163 -0
  12. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/attribute.html.jinja +128 -0
  13. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/backlinks.html.jinja +66 -0
  14. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/children.html.jinja +197 -0
  15. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/class.html.jinja +288 -0
  16. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/const.html.jinja +31 -0
  17. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/admonition.html.jinja +20 -0
  18. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/attributes.html.jinja +109 -0
  19. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/classes.html.jinja +86 -0
  20. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/examples.html.jinja +28 -0
  21. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/functions.html.jinja +92 -0
  22. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/modules.html.jinja +86 -0
  23. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/other_parameters.html.jinja +109 -0
  24. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/parameters.html.jinja +175 -0
  25. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/raises.html.jinja +102 -0
  26. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/receives.html.jinja +122 -0
  27. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/returns.html.jinja +122 -0
  28. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/type_aliases.html.jinja +86 -0
  29. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/type_parameters.html.jinja +208 -0
  30. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/warns.html.jinja +102 -0
  31. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring/yields.html.jinja +122 -0
  32. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/docstring.html.jinja +59 -0
  33. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/expression.html.jinja +172 -0
  34. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/func.html.jinja +1 -0
  35. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/iterator.html.jinja +1 -0
  36. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/labels.html.jinja +25 -0
  37. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/language.html.jinja +18 -0
  38. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/languages/en.html.jinja +56 -0
  39. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/languages/ja.html.jinja +56 -0
  40. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/languages/zh.html.jinja +56 -0
  41. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/macro.html.jinja +1 -0
  42. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/module.html.jinja +30 -0
  43. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/proc.html.jinja +80 -0
  44. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/signature.html.jinja +135 -0
  45. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/summary/attributes.html.jinja +23 -0
  46. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/summary/classes.html.jinja +23 -0
  47. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/summary/functions.html.jinja +23 -0
  48. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/summary/modules.html.jinja +23 -0
  49. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/summary/type_aliases.html.jinja +23 -0
  50. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/summary.html.jinja +30 -0
  51. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/template.html.jinja +1 -0
  52. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/type.html.jinja +31 -0
  53. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/type_alias.html.jinja +117 -0
  54. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/_base/type_parameters.html.jinja +87 -0
  55. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/attribute.html.jinja +1 -0
  56. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/backlinks.html.jinja +1 -0
  57. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/children.html.jinja +1 -0
  58. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/class.html.jinja +1 -0
  59. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/const.html.jinja +1 -0
  60. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/admonition.html.jinja +1 -0
  61. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/attributes.html.jinja +1 -0
  62. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/classes.html.jinja +1 -0
  63. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/examples.html.jinja +1 -0
  64. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/functions.html.jinja +1 -0
  65. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/modules.html.jinja +1 -0
  66. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/other_parameters.html.jinja +1 -0
  67. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/parameters.html.jinja +1 -0
  68. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/raises.html.jinja +1 -0
  69. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/receives.html.jinja +1 -0
  70. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/returns.html.jinja +1 -0
  71. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/type_aliases.html.jinja +1 -0
  72. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/type_parameters.html.jinja +1 -0
  73. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/warns.html.jinja +1 -0
  74. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring/yields.html.jinja +1 -0
  75. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/docstring.html.jinja +1 -0
  76. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/expression.html.jinja +1 -0
  77. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/func.html.jinja +1 -0
  78. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/iterator.html.jinja +1 -0
  79. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/labels.html.jinja +1 -0
  80. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/language.html.jinja +1 -0
  81. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/languages/en.html.jinja +1 -0
  82. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/languages/ja.html.jinja +1 -0
  83. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/languages/zh.html.jinja +1 -0
  84. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/macro.html.jinja +1 -0
  85. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/module.html.jinja +1 -0
  86. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/proc.html.jinja +1 -0
  87. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/signature.html.jinja +1 -0
  88. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/style.css +236 -0
  89. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/summary/attributes.html.jinja +1 -0
  90. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/summary/classes.html.jinja +1 -0
  91. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/summary/functions.html.jinja +1 -0
  92. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/summary/modules.html.jinja +1 -0
  93. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/summary/type_aliases.html.jinja +1 -0
  94. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/summary.html.jinja +1 -0
  95. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/template.html.jinja +1 -0
  96. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/type.html.jinja +1 -0
  97. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/type_alias.html.jinja +1 -0
  98. mkdocstrings_nim-0.1.0/mkdocstrings_handlers/nim/templates/material/type_parameters.html.jinja +1 -0
  99. mkdocstrings_nim-0.1.0/pyproject.toml +61 -0
@@ -0,0 +1,55 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .env
25
+ .venv
26
+ env/
27
+ venv/
28
+ ENV/
29
+
30
+ # IDE
31
+ .idea/
32
+ .vscode/
33
+ *.swp
34
+ *.swo
35
+
36
+ # Testing
37
+ .pytest_cache/
38
+ .coverage
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+
43
+ # Nim
44
+ nimcache/
45
+ *.exe
46
+ *.out
47
+ src/nimdocinfo/nimdocinfo
48
+
49
+ # MkDocs
50
+ site/
51
+ docs/plans/
52
+
53
+ # OS
54
+ .DS_Store
55
+ Thumbs.db
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Elijah Rutschman
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,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: mkdocstrings-nim
3
+ Version: 0.1.0
4
+ Summary: A Nim handler for mkdocstrings
5
+ Author: Elijah Rutschman
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Documentation
16
+ Classifier: Topic :: Software Development :: Documentation
17
+ Requires-Python: >=3.9
18
+ Requires-Dist: docstring-parser>=0.15
19
+ Requires-Dist: jinja2>=3.0
20
+ Requires-Dist: mkdocstrings>=0.20
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest-cov; extra == 'dev'
23
+ Requires-Dist: pytest>=7.0; extra == 'dev'
24
+ Provides-Extra: docs
25
+ Requires-Dist: mike>=2.0; extra == 'docs'
26
+ Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2; extra == 'docs'
27
+ Requires-Dist: mkdocs-glightbox>=0.3; extra == 'docs'
28
+ Requires-Dist: mkdocs-material>=9.0; extra == 'docs'
29
+ Requires-Dist: mkdocs>=1.5; extra == 'docs'
30
+ Requires-Dist: pymdown-extensions>=10.0; extra == 'docs'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # mkdocstrings-nim
34
+
35
+ [![PyPI](https://img.shields.io/pypi/v/mkdocstrings-nim)](https://pypi.org/project/mkdocstrings-nim/)
36
+ [![Python](https://img.shields.io/pypi/pyversions/mkdocstrings-nim)](https://pypi.org/project/mkdocstrings-nim/)
37
+ [![License](https://img.shields.io/github/license/elijahr/mkdocstrings-nim)](https://github.com/elijahr/mkdocstrings-nim/blob/main/LICENSE)
38
+ [![Docs](https://img.shields.io/badge/docs-elijahr.github.io%2Fmkdocstrings--nim-blue)](https://elijahr.github.io/mkdocstrings-nim/)
39
+
40
+ A [mkdocstrings](https://mkdocstrings.github.io/) handler for [Nim](https://nim-lang.org/).
41
+
42
+ Parses Nim source files using the Nim compiler's AST to extract module docstrings, procedure signatures, parameter types, return types, and `{.raises.}` pragma annotations. Renders the extracted documentation as HTML within [MkDocs](https://www.mkdocs.org/) using the `::: module` directive syntax.
43
+
44
+ **[Documentation](https://elijahr.github.io/mkdocstrings-nim/)**
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install mkdocstrings-nim
50
+ ```
51
+
52
+ **Requirements:** Nim compiler must be installed and available in PATH.
53
+
54
+ ## Quick Start
55
+
56
+ 1. Add to your `mkdocs.yml`:
57
+
58
+ ```yaml
59
+ plugins:
60
+ - mkdocstrings:
61
+ handlers:
62
+ nim:
63
+ paths: [src]
64
+ ```
65
+
66
+ 2. Use in your markdown:
67
+
68
+ ```markdown
69
+ # API Reference
70
+
71
+ ::: mymodule
72
+ ```
73
+
74
+ 3. Build your docs:
75
+
76
+ ```bash
77
+ mkdocs build
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ ### Handler Options
83
+
84
+ | Option | Default | Description |
85
+ |--------|---------|-------------|
86
+ | `paths` | `["src"]` | Search paths for Nim source files |
87
+ | `docstring_style` | `"rst"` | Docstring format: `rst`, `google`, `numpy`, `epydoc`, or `auto` |
88
+ | `show_source` | `true` | Show source line numbers |
89
+ | `show_signature` | `true` | Show full signatures |
90
+ | `show_pragmas` | `true` | Show pragma annotations |
91
+
92
+ ### Docstring Format
93
+
94
+ Use RST-style docstrings in your Nim code:
95
+
96
+ ```nim
97
+ proc greet*(name: string): string =
98
+ ## Greet someone by name.
99
+ ##
100
+ ## :param name: The name to greet
101
+ ## :returns: A greeting message
102
+ result = "Hello, " & name & "!"
103
+ ```
104
+
105
+ ## Development
106
+
107
+ ```bash
108
+ git clone https://github.com/elijahr/mkdocstrings-nim
109
+ cd mkdocstrings-nim
110
+ pip install -e ".[dev]"
111
+ pytest
112
+ ```
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,84 @@
1
+ # mkdocstrings-nim
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/mkdocstrings-nim)](https://pypi.org/project/mkdocstrings-nim/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/mkdocstrings-nim)](https://pypi.org/project/mkdocstrings-nim/)
5
+ [![License](https://img.shields.io/github/license/elijahr/mkdocstrings-nim)](https://github.com/elijahr/mkdocstrings-nim/blob/main/LICENSE)
6
+ [![Docs](https://img.shields.io/badge/docs-elijahr.github.io%2Fmkdocstrings--nim-blue)](https://elijahr.github.io/mkdocstrings-nim/)
7
+
8
+ A [mkdocstrings](https://mkdocstrings.github.io/) handler for [Nim](https://nim-lang.org/).
9
+
10
+ Parses Nim source files using the Nim compiler's AST to extract module docstrings, procedure signatures, parameter types, return types, and `{.raises.}` pragma annotations. Renders the extracted documentation as HTML within [MkDocs](https://www.mkdocs.org/) using the `::: module` directive syntax.
11
+
12
+ **[Documentation](https://elijahr.github.io/mkdocstrings-nim/)**
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install mkdocstrings-nim
18
+ ```
19
+
20
+ **Requirements:** Nim compiler must be installed and available in PATH.
21
+
22
+ ## Quick Start
23
+
24
+ 1. Add to your `mkdocs.yml`:
25
+
26
+ ```yaml
27
+ plugins:
28
+ - mkdocstrings:
29
+ handlers:
30
+ nim:
31
+ paths: [src]
32
+ ```
33
+
34
+ 2. Use in your markdown:
35
+
36
+ ```markdown
37
+ # API Reference
38
+
39
+ ::: mymodule
40
+ ```
41
+
42
+ 3. Build your docs:
43
+
44
+ ```bash
45
+ mkdocs build
46
+ ```
47
+
48
+ ## Configuration
49
+
50
+ ### Handler Options
51
+
52
+ | Option | Default | Description |
53
+ |--------|---------|-------------|
54
+ | `paths` | `["src"]` | Search paths for Nim source files |
55
+ | `docstring_style` | `"rst"` | Docstring format: `rst`, `google`, `numpy`, `epydoc`, or `auto` |
56
+ | `show_source` | `true` | Show source line numbers |
57
+ | `show_signature` | `true` | Show full signatures |
58
+ | `show_pragmas` | `true` | Show pragma annotations |
59
+
60
+ ### Docstring Format
61
+
62
+ Use RST-style docstrings in your Nim code:
63
+
64
+ ```nim
65
+ proc greet*(name: string): string =
66
+ ## Greet someone by name.
67
+ ##
68
+ ## :param name: The name to greet
69
+ ## :returns: A greeting message
70
+ result = "Hello, " & name & "!"
71
+ ```
72
+
73
+ ## Development
74
+
75
+ ```bash
76
+ git clone https://github.com/elijahr/mkdocstrings-nim
77
+ cd mkdocstrings-nim
78
+ pip install -e ".[dev]"
79
+ pytest
80
+ ```
81
+
82
+ ## License
83
+
84
+ MIT
@@ -0,0 +1,2 @@
1
+ """mkdocstrings handlers namespace package."""
2
+ __path__ = __import__("pkgutil").extend_path(__path__, __name__)
@@ -0,0 +1,27 @@
1
+ """Nim handler for mkdocstrings."""
2
+
3
+ from mkdocstrings_handlers.nim.handler import NimHandler, get_handler
4
+ from mkdocstrings_handlers.nim.collector import NimCollector, NimModule, NimEntry, NimParam
5
+ from mkdocstrings_handlers.nim.docstring import (
6
+ parse_docstring,
7
+ DocstringStyle,
8
+ ParsedDocstring,
9
+ ParamDoc,
10
+ ReturnsDoc,
11
+ RaisesDoc,
12
+ )
13
+
14
+ __all__ = [
15
+ "NimHandler",
16
+ "get_handler",
17
+ "NimCollector",
18
+ "NimModule",
19
+ "NimEntry",
20
+ "NimParam",
21
+ "parse_docstring",
22
+ "DocstringStyle",
23
+ "ParsedDocstring",
24
+ "ParamDoc",
25
+ "ReturnsDoc",
26
+ "RaisesDoc",
27
+ ]
@@ -0,0 +1,267 @@
1
+ """Collector for Nim documentation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import shutil
7
+ import subprocess
8
+ import sys
9
+ import tempfile
10
+ from dataclasses import dataclass, field
11
+ from importlib.resources import files, as_file
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+ from mkdocstrings import CollectionError
16
+
17
+ # Cache directory for compiled nimdocinfo binary
18
+ _CACHE_DIR = Path(tempfile.gettempdir()) / "mkdocstrings-nim-cache"
19
+
20
+
21
+ @dataclass
22
+ class NimParam:
23
+ """A Nim parameter."""
24
+ name: str
25
+ type: str
26
+ description: str = ""
27
+
28
+
29
+ @dataclass
30
+ class NimEntry:
31
+ """A documented Nim entry (proc, type, const, etc.)."""
32
+ name: str
33
+ kind: str
34
+ line: int
35
+ signature: str
36
+ doc: str = ""
37
+ params: list[NimParam] = field(default_factory=list)
38
+ returns: str = ""
39
+ returns_doc: str = ""
40
+ pragmas: list[str] = field(default_factory=list)
41
+ raises: list[str] = field(default_factory=list)
42
+
43
+
44
+ @dataclass
45
+ class NimModule:
46
+ """A documented Nim module."""
47
+ module: str
48
+ file: str
49
+ doc: str = ""
50
+ entries: list[NimEntry] = field(default_factory=list)
51
+
52
+
53
+ class NimCollector:
54
+ """Collects documentation from Nim source files."""
55
+
56
+ def __init__(self, paths: list[str], base_dir: Path):
57
+ """Initialize the collector.
58
+
59
+ Args:
60
+ paths: Search paths for Nim source files.
61
+ base_dir: Base directory of the project.
62
+ """
63
+ self.paths = paths
64
+ self.base_dir = base_dir
65
+ self._cache: dict[str, NimModule] = {}
66
+ # Use importlib.resources for reliable path resolution
67
+ extractor_files = files("mkdocstrings_handlers.nim").joinpath("extractor")
68
+ self._nimdocinfo_source = extractor_files.joinpath("nimdocinfo.nim")
69
+
70
+ def _resolve_identifier(self, identifier: str) -> Path:
71
+ """Resolve a module identifier to a file path.
72
+
73
+ Args:
74
+ identifier: Module identifier like 'lockfreequeues.ops'
75
+
76
+ Returns:
77
+ Path to the Nim source file.
78
+
79
+ Raises:
80
+ CollectionError: If the file cannot be found.
81
+ """
82
+ # Convert dots to path separators
83
+ rel_path = identifier.replace(".", "/") + ".nim"
84
+
85
+ for search_path in self.paths:
86
+ full_path = self.base_dir / search_path / rel_path
87
+ if full_path.exists():
88
+ return full_path
89
+
90
+ # Try without nested path (just filename)
91
+ filename = identifier.split(".")[-1] + ".nim"
92
+ for search_path in self.paths:
93
+ full_path = self.base_dir / search_path / filename
94
+ if full_path.exists():
95
+ return full_path
96
+
97
+ raise CollectionError(f"Could not find Nim file for identifier: {identifier}")
98
+
99
+ def _ensure_nimdocinfo_compiled(self) -> Path:
100
+ """Ensure nimdocinfo is compiled and return path to binary.
101
+
102
+ Copies Nim source files to a cache directory and compiles them there.
103
+ This avoids writing to the installed package directory.
104
+
105
+ Returns:
106
+ Path to the compiled nimdocinfo binary.
107
+
108
+ Raises:
109
+ CollectionError: If compilation fails.
110
+ """
111
+ _CACHE_DIR.mkdir(parents=True, exist_ok=True)
112
+
113
+ # Get the extractor package files
114
+ extractor_pkg = files("mkdocstrings_handlers.nim").joinpath("extractor")
115
+
116
+ # Copy source files to cache if needed
117
+ with as_file(extractor_pkg.joinpath("nimdocinfo.nim")) as src_main:
118
+ with as_file(extractor_pkg.joinpath("extractor.nim")) as src_extractor:
119
+ cache_main = _CACHE_DIR / "nimdocinfo.nim"
120
+ cache_extractor = _CACHE_DIR / "extractor.nim"
121
+ cache_binary = _CACHE_DIR / "nimdocinfo"
122
+
123
+ # Check if we need to recompile (source newer than binary)
124
+ needs_compile = not cache_binary.exists()
125
+ if not needs_compile:
126
+ binary_mtime = cache_binary.stat().st_mtime
127
+ if src_main.stat().st_mtime > binary_mtime:
128
+ needs_compile = True
129
+ elif src_extractor.stat().st_mtime > binary_mtime:
130
+ needs_compile = True
131
+
132
+ if needs_compile:
133
+ # Copy source files
134
+ shutil.copy2(src_main, cache_main)
135
+ shutil.copy2(src_extractor, cache_extractor)
136
+
137
+ # Compile (first run is slow, ~15s; subsequent runs use cache)
138
+ result = subprocess.run(
139
+ ["nim", "c", "--outdir:" + str(_CACHE_DIR), str(cache_main)],
140
+ capture_output=True,
141
+ text=True,
142
+ timeout=120, # First compile can be slow
143
+ )
144
+
145
+ if result.returncode != 0:
146
+ raise CollectionError(
147
+ f"Failed to compile nimdocinfo:\n{result.stderr}"
148
+ )
149
+
150
+ return cache_binary
151
+
152
+ def _run_nimdocinfo(self, filepath: Path) -> dict[str, Any]:
153
+ """Run nimdocinfo on a Nim file.
154
+
155
+ Args:
156
+ filepath: Path to the Nim source file.
157
+
158
+ Returns:
159
+ Parsed JSON output from nimdocinfo.
160
+
161
+ Raises:
162
+ CollectionError: If nimdocinfo fails.
163
+ """
164
+ try:
165
+ binary_path = self._ensure_nimdocinfo_compiled()
166
+
167
+ result = subprocess.run(
168
+ [str(binary_path), str(filepath)],
169
+ capture_output=True,
170
+ text=True,
171
+ cwd=str(self.base_dir),
172
+ timeout=60,
173
+ )
174
+
175
+ if result.returncode != 0:
176
+ raise CollectionError(
177
+ f"nimdocinfo failed:\n{result.stderr}\n\n"
178
+ f"To debug, run manually:\n"
179
+ f" {binary_path} {filepath}"
180
+ )
181
+
182
+ # Parse JSON from stdout
183
+ lines = result.stdout.strip().split("\n")
184
+ json_lines = []
185
+ in_json = False
186
+ for line in lines:
187
+ if line.strip().startswith("{"):
188
+ in_json = True
189
+ if in_json:
190
+ json_lines.append(line)
191
+ if in_json and line.strip().startswith("}") and len(json_lines) > 1:
192
+ try:
193
+ return json.loads("\n".join(json_lines))
194
+ except json.JSONDecodeError:
195
+ continue
196
+
197
+ if not json_lines:
198
+ raise CollectionError(f"No JSON output from nimdocinfo: {result.stdout}")
199
+
200
+ return json.loads("\n".join(json_lines))
201
+
202
+ except FileNotFoundError:
203
+ raise CollectionError(
204
+ "Nim compiler not found. Install from https://nim-lang.org/install.html\n"
205
+ "Then verify installation: nim --version"
206
+ )
207
+ except subprocess.TimeoutExpired:
208
+ raise CollectionError(
209
+ f"nimdocinfo timed out processing {filepath}. "
210
+ "The file may be too complex or have circular imports."
211
+ )
212
+ except json.JSONDecodeError as e:
213
+ raise CollectionError(f"Invalid JSON from nimdocinfo: {e}")
214
+
215
+ def _parse_module(self, data: dict[str, Any]) -> NimModule:
216
+ """Parse JSON data into NimModule.
217
+
218
+ Args:
219
+ data: JSON data from nimdocinfo.
220
+
221
+ Returns:
222
+ Parsed NimModule.
223
+ """
224
+ entries = []
225
+ for entry_data in data.get("entries", []):
226
+ params = [
227
+ NimParam(name=p["name"], type=p["type"])
228
+ for p in entry_data.get("params", [])
229
+ ]
230
+
231
+ entries.append(NimEntry(
232
+ name=entry_data["name"],
233
+ kind=entry_data["kind"],
234
+ line=entry_data["line"],
235
+ signature=entry_data["signature"],
236
+ doc=entry_data.get("doc", ""),
237
+ params=params,
238
+ returns=entry_data.get("returns", ""),
239
+ pragmas=entry_data.get("pragmas", []),
240
+ raises=entry_data.get("raises", []),
241
+ ))
242
+
243
+ return NimModule(
244
+ module=data["module"],
245
+ file=data["file"],
246
+ doc=data.get("doc", ""),
247
+ entries=entries,
248
+ )
249
+
250
+ def collect(self, identifier: str) -> NimModule:
251
+ """Collect documentation for a module identifier.
252
+
253
+ Args:
254
+ identifier: Module identifier like 'lockfreequeues.ops'
255
+
256
+ Returns:
257
+ NimModule with documentation.
258
+ """
259
+ if identifier in self._cache:
260
+ return self._cache[identifier]
261
+
262
+ filepath = self._resolve_identifier(identifier)
263
+ data = self._run_nimdocinfo(filepath)
264
+ module = self._parse_module(data)
265
+
266
+ self._cache[identifier] = module
267
+ return module
@@ -0,0 +1,129 @@
1
+ """Docstring parsing for Nim documentation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from enum import Enum
7
+ from typing import Optional
8
+
9
+ import docstring_parser
10
+ from docstring_parser import DocstringStyle as DPStyle
11
+
12
+
13
+ class DocstringStyle(Enum):
14
+ """Supported docstring styles."""
15
+ RST = "rst"
16
+ GOOGLE = "google"
17
+ NUMPY = "numpy"
18
+ EPYDOC = "epydoc"
19
+ AUTO = "auto"
20
+
21
+
22
+ @dataclass
23
+ class ParamDoc:
24
+ """Parsed parameter documentation."""
25
+ name: str
26
+ description: str = ""
27
+ type: str = ""
28
+
29
+
30
+ @dataclass
31
+ class ReturnsDoc:
32
+ """Parsed return value documentation."""
33
+ description: str = ""
34
+ type: str = ""
35
+
36
+
37
+ @dataclass
38
+ class RaisesDoc:
39
+ """Parsed raises documentation."""
40
+ type: str
41
+ description: str = ""
42
+
43
+
44
+ @dataclass
45
+ class ParsedDocstring:
46
+ """Parsed docstring with structured sections."""
47
+ description: str = ""
48
+ params: list[ParamDoc] = field(default_factory=list)
49
+ returns: Optional[ReturnsDoc] = None
50
+ raises: list[RaisesDoc] = field(default_factory=list)
51
+ examples: list[str] = field(default_factory=list)
52
+
53
+
54
+ # Map our style enum to docstring_parser's style enum
55
+ _STYLE_MAP = {
56
+ DocstringStyle.RST: DPStyle.REST,
57
+ DocstringStyle.GOOGLE: DPStyle.GOOGLE,
58
+ DocstringStyle.NUMPY: DPStyle.NUMPYDOC,
59
+ DocstringStyle.EPYDOC: DPStyle.EPYDOC,
60
+ DocstringStyle.AUTO: DPStyle.AUTO,
61
+ }
62
+
63
+
64
+ def parse_docstring(doc: str, style: DocstringStyle = DocstringStyle.RST) -> ParsedDocstring:
65
+ """Parse a docstring according to the specified style.
66
+
67
+ Uses the docstring_parser library for robust parsing of RST, Google,
68
+ and NumPy docstring formats.
69
+
70
+ Args:
71
+ doc: Raw docstring text.
72
+ style: Docstring style to use for parsing.
73
+
74
+ Returns:
75
+ Parsed docstring structure.
76
+ """
77
+ if not doc:
78
+ return ParsedDocstring()
79
+
80
+ dp_style = _STYLE_MAP.get(style, DPStyle.REST)
81
+
82
+ try:
83
+ parsed = docstring_parser.parse(doc, style=dp_style)
84
+ except Exception:
85
+ # Fall back to auto-detection if specified style fails
86
+ try:
87
+ parsed = docstring_parser.parse(doc)
88
+ except Exception:
89
+ # If all parsing fails, just return description
90
+ return ParsedDocstring(description=doc.strip())
91
+
92
+ result = ParsedDocstring()
93
+
94
+ # Extract description (short + long)
95
+ desc_parts = []
96
+ if parsed.short_description:
97
+ desc_parts.append(parsed.short_description)
98
+ if parsed.long_description:
99
+ desc_parts.append(parsed.long_description)
100
+ result.description = "\n\n".join(desc_parts)
101
+
102
+ # Extract parameters
103
+ for param in parsed.params:
104
+ result.params.append(ParamDoc(
105
+ name=param.arg_name,
106
+ description=param.description or "",
107
+ type=param.type_name or "",
108
+ ))
109
+
110
+ # Extract returns
111
+ if parsed.returns:
112
+ result.returns = ReturnsDoc(
113
+ description=parsed.returns.description or "",
114
+ type=parsed.returns.type_name or "",
115
+ )
116
+
117
+ # Extract raises
118
+ for raises in parsed.raises:
119
+ result.raises.append(RaisesDoc(
120
+ type=raises.type_name or "",
121
+ description=raises.description or "",
122
+ ))
123
+
124
+ # Extract examples
125
+ for example in parsed.examples:
126
+ if example.description:
127
+ result.examples.append(example.description)
128
+
129
+ return result