mkdocstrings-matlab 0.1.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- mkdocstrings_matlab-0.1.0/.gitignore +196 -0
- mkdocstrings_matlab-0.1.0/LICENSE +21 -0
- mkdocstrings_matlab-0.1.0/PKG-INFO +17 -0
- mkdocstrings_matlab-0.1.0/README.md +3 -0
- mkdocstrings_matlab-0.1.0/debug.py +17 -0
- mkdocstrings_matlab-0.1.0/docs/index.md +25 -0
- mkdocstrings_matlab-0.1.0/mkdocs.yml +28 -0
- mkdocstrings_matlab-0.1.0/pyproject.toml +30 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/__init__.py +5 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/handler.py +383 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+case/builtin.m +8 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+case/class.m +12 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+case/func.m +5 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+case/method.m +6 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+case/namespace.m +28 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/argument.m +58 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m +44 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/func.m +14 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/namespace.m +14 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/property.m +41 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/script.m +15 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+utils/dedent.m +34 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+utils/get_namespace_path.m +26 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+utils/parse_doc.m +21 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/exception.m +7 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/resolve.m +94 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/matlab_startup.m +21 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/models.py +127 -0
- mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/py.typed +0 -0
@@ -0,0 +1,196 @@
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
2
|
+
__pycache__/
|
3
|
+
*.py[cod]
|
4
|
+
*$py.class
|
5
|
+
|
6
|
+
# C extensions
|
7
|
+
*.so
|
8
|
+
|
9
|
+
# Distribution / packaging
|
10
|
+
.Python
|
11
|
+
build/
|
12
|
+
develop-eggs/
|
13
|
+
dist/
|
14
|
+
downloads/
|
15
|
+
eggs/
|
16
|
+
.eggs/
|
17
|
+
lib/
|
18
|
+
lib64/
|
19
|
+
parts/
|
20
|
+
sdist/
|
21
|
+
var/
|
22
|
+
wheels/
|
23
|
+
share/python-wheels/
|
24
|
+
*.egg-info/
|
25
|
+
.installed.cfg
|
26
|
+
*.egg
|
27
|
+
MANIFEST
|
28
|
+
|
29
|
+
# PyInstaller
|
30
|
+
# Usually these files are written by a python script from a template
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32
|
+
*.manifest
|
33
|
+
*.spec
|
34
|
+
|
35
|
+
# Installer logs
|
36
|
+
pip-log.txt
|
37
|
+
pip-delete-this-directory.txt
|
38
|
+
|
39
|
+
# Unit test / coverage reports
|
40
|
+
htmlcov/
|
41
|
+
.tox/
|
42
|
+
.nox/
|
43
|
+
.coverage
|
44
|
+
.coverage.*
|
45
|
+
.cache
|
46
|
+
nosetests.xml
|
47
|
+
coverage.xml
|
48
|
+
*.cover
|
49
|
+
*.py,cover
|
50
|
+
.hypothesis/
|
51
|
+
.pytest_cache/
|
52
|
+
cover/
|
53
|
+
|
54
|
+
# Translations
|
55
|
+
*.mo
|
56
|
+
*.pot
|
57
|
+
|
58
|
+
# Django stuff:
|
59
|
+
*.log
|
60
|
+
local_settings.py
|
61
|
+
db.sqlite3
|
62
|
+
db.sqlite3-journal
|
63
|
+
|
64
|
+
# Flask stuff:
|
65
|
+
instance/
|
66
|
+
.webassets-cache
|
67
|
+
|
68
|
+
# Scrapy stuff:
|
69
|
+
.scrapy
|
70
|
+
|
71
|
+
# Sphinx documentation
|
72
|
+
docs/_build/
|
73
|
+
|
74
|
+
# PyBuilder
|
75
|
+
.pybuilder/
|
76
|
+
target/
|
77
|
+
|
78
|
+
# Jupyter Notebook
|
79
|
+
.ipynb_checkpoints
|
80
|
+
|
81
|
+
# IPython
|
82
|
+
profile_default/
|
83
|
+
ipython_config.py
|
84
|
+
|
85
|
+
# pyenv
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
88
|
+
# .python-version
|
89
|
+
|
90
|
+
# pipenv
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94
|
+
# install all needed dependencies.
|
95
|
+
#Pipfile.lock
|
96
|
+
|
97
|
+
# poetry
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100
|
+
# commonly ignored for libraries.
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
102
|
+
#poetry.lock
|
103
|
+
|
104
|
+
# pdm
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
106
|
+
#pdm.lock
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
108
|
+
# in version control.
|
109
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
110
|
+
.pdm.toml
|
111
|
+
.pdm-python
|
112
|
+
.pdm-build/
|
113
|
+
|
114
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
115
|
+
__pypackages__/
|
116
|
+
|
117
|
+
# Celery stuff
|
118
|
+
celerybeat-schedule
|
119
|
+
celerybeat.pid
|
120
|
+
|
121
|
+
# SageMath parsed files
|
122
|
+
*.sage.py
|
123
|
+
|
124
|
+
# Environments
|
125
|
+
.env
|
126
|
+
.venv
|
127
|
+
env/
|
128
|
+
venv/
|
129
|
+
ENV/
|
130
|
+
env.bak/
|
131
|
+
venv.bak/
|
132
|
+
|
133
|
+
# Spyder project settings
|
134
|
+
.spyderproject
|
135
|
+
.spyproject
|
136
|
+
|
137
|
+
# Rope project settings
|
138
|
+
.ropeproject
|
139
|
+
|
140
|
+
# mkdocs documentation
|
141
|
+
/site
|
142
|
+
|
143
|
+
# mypy
|
144
|
+
.mypy_cache/
|
145
|
+
.dmypy.json
|
146
|
+
dmypy.json
|
147
|
+
|
148
|
+
# Pyre type checker
|
149
|
+
.pyre/
|
150
|
+
|
151
|
+
# pytype static type analyzer
|
152
|
+
.pytype/
|
153
|
+
|
154
|
+
# Cython debug symbols
|
155
|
+
cython_debug/
|
156
|
+
|
157
|
+
# PyCharm
|
158
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
159
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
160
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
161
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
162
|
+
#.idea/
|
163
|
+
|
164
|
+
|
165
|
+
# Windows default autosave extension
|
166
|
+
*.asv
|
167
|
+
|
168
|
+
# OSX / *nix default autosave extension
|
169
|
+
*.m~
|
170
|
+
|
171
|
+
# Compiled MEX binaries (all platforms)
|
172
|
+
*.mex*
|
173
|
+
|
174
|
+
# Packaged app and toolbox files
|
175
|
+
*.mlappinstall
|
176
|
+
*.mltbx
|
177
|
+
|
178
|
+
# Generated helpsearch folders
|
179
|
+
helpsearch*/
|
180
|
+
|
181
|
+
# Simulink code generation folders
|
182
|
+
slprj/
|
183
|
+
sccprj/
|
184
|
+
|
185
|
+
# Matlab code generation folders
|
186
|
+
codegen/
|
187
|
+
|
188
|
+
# Simulink autosave extension
|
189
|
+
*.autosave
|
190
|
+
|
191
|
+
# Simulink cache files
|
192
|
+
*.slxc
|
193
|
+
|
194
|
+
# Octave session info
|
195
|
+
octave-workspace
|
196
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2024 Mark Shui Hu
|
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,17 @@
|
|
1
|
+
Metadata-Version: 2.3
|
2
|
+
Name: mkdocstrings-matlab
|
3
|
+
Version: 0.1.0
|
4
|
+
Summary: Add your description here
|
5
|
+
Author-email: Mark Hu <mark.hu@asml.com>
|
6
|
+
License-File: LICENSE
|
7
|
+
Requires-Dist: griffe>=1.2.0
|
8
|
+
Requires-Dist: markdown>=3.7
|
9
|
+
Requires-Dist: mkdocs-material>=9.5.33
|
10
|
+
Requires-Dist: mkdocs>=1.6.0
|
11
|
+
Requires-Dist: mkdocstrings>=0.25.2
|
12
|
+
Requires-Dist: mkdocstrings[python]>=0.18
|
13
|
+
Description-Content-Type: text/markdown
|
14
|
+
|
15
|
+
# mkdocstrings-matlab
|
16
|
+
|
17
|
+
Describe your project here.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from mkdocs.commands import serve
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
config_file = str(Path(__file__).parent / "mkdocs.yml")
|
5
|
+
|
6
|
+
kwargs = {
|
7
|
+
"dev_addr": None,
|
8
|
+
"open_in_browser": False,
|
9
|
+
"livereload": True,
|
10
|
+
"build_type": None,
|
11
|
+
"watch_theme": True,
|
12
|
+
"config_file": config_file,
|
13
|
+
"strict": None,
|
14
|
+
"theme": None,
|
15
|
+
"use_directory_urls": None,
|
16
|
+
}
|
17
|
+
serve.serve(**kwargs)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
# Docs
|
3
|
+
|
4
|
+
<!-- ::: matlab_startupP455W0rd
|
5
|
+
|
6
|
+
handler: matlab -->
|
7
|
+
|
8
|
+
<!-- ::: docstring.resolve
|
9
|
+
handler: matlab -->
|
10
|
+
|
11
|
+
<!-- ::: mkdocstrings_handlers.matlab.handler.MatlabHandler
|
12
|
+
handler: python
|
13
|
+
options:
|
14
|
+
show_source: false
|
15
|
+
members:
|
16
|
+
- collect -->
|
17
|
+
|
18
|
+
::: ghtest.testrunner
|
19
|
+
handler: matlab
|
20
|
+
options:
|
21
|
+
members:
|
22
|
+
- run
|
23
|
+
- get_suite
|
24
|
+
- get_runner
|
25
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
site_name: "mkdocstrings-matlab"
|
2
|
+
repo_name: "watermarkhu/mkdocstrings-matlab"
|
3
|
+
site_dir: "site"
|
4
|
+
|
5
|
+
nav:
|
6
|
+
- Home: index.md
|
7
|
+
|
8
|
+
theme:
|
9
|
+
name: material
|
10
|
+
|
11
|
+
watch:
|
12
|
+
- src
|
13
|
+
|
14
|
+
plugins:
|
15
|
+
- search
|
16
|
+
- autorefs
|
17
|
+
- mkdocstrings:
|
18
|
+
default_handler: python
|
19
|
+
handlers:
|
20
|
+
# python:
|
21
|
+
# paths: ["src"]
|
22
|
+
# options:
|
23
|
+
# show_root_heading: true
|
24
|
+
# show_docstring_attributes: false
|
25
|
+
matlab:
|
26
|
+
paths: ["/home/mahu/repositories/github-matlab-test-action/src"]
|
27
|
+
options:
|
28
|
+
show_root_heading: true
|
@@ -0,0 +1,30 @@
|
|
1
|
+
[project]
|
2
|
+
name = "mkdocstrings-matlab"
|
3
|
+
version = "0.1.0"
|
4
|
+
description = "Add your description here"
|
5
|
+
authors = [
|
6
|
+
{ name = "Mark Hu", email = "mark.hu@asml.com" }
|
7
|
+
]
|
8
|
+
dependencies = [
|
9
|
+
"mkdocs>=1.6.0",
|
10
|
+
"mkdocstrings>=0.25.2",
|
11
|
+
"mkdocstrings[python]>=0.18",
|
12
|
+
"griffe>=1.2.0",
|
13
|
+
"mkdocs-material>=9.5.33",
|
14
|
+
"markdown>=3.7",
|
15
|
+
]
|
16
|
+
readme = "README.md"
|
17
|
+
|
18
|
+
[build-system]
|
19
|
+
requires = ["hatchling"]
|
20
|
+
build-backend = "hatchling.build"
|
21
|
+
|
22
|
+
[tool.rye]
|
23
|
+
managed = true
|
24
|
+
dev-dependencies = []
|
25
|
+
|
26
|
+
[tool.hatch.metadata]
|
27
|
+
allow-direct-references = true
|
28
|
+
|
29
|
+
[tool.hatch.build.targets.wheel]
|
30
|
+
packages = ["src/mkdocstrings_handlers"]
|
@@ -0,0 +1,383 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
from collections import ChainMap
|
3
|
+
from markdown import Markdown
|
4
|
+
from mkdocstrings.handlers.base import BaseHandler, CollectorItem, CollectionError
|
5
|
+
from mkdocstrings_handlers.python import rendering
|
6
|
+
from typing import Any, ClassVar, Mapping
|
7
|
+
from griffe import Docstring, Parameters, Parameter, ParameterKind
|
8
|
+
from pprint import pprint
|
9
|
+
|
10
|
+
|
11
|
+
import json
|
12
|
+
|
13
|
+
|
14
|
+
from mkdocstrings_handlers.matlab_engine import MatlabEngine, MatlabExecutionError
|
15
|
+
from mkdocstrings_handlers.matlab.models import Function, Class, Classfolder, Namespace, Property
|
16
|
+
|
17
|
+
|
18
|
+
ROOT_NAMESPACE = Namespace("", filepath="")
|
19
|
+
MODELS = {}
|
20
|
+
|
21
|
+
|
22
|
+
class MatlabHandler(BaseHandler):
|
23
|
+
"""The `MatlabHandler` class is a handler for processing Matlab code documentation.
|
24
|
+
|
25
|
+
Attributes:
|
26
|
+
name (str): The handler's name.
|
27
|
+
domain (str): The cross-documentation domain/language for this handler.
|
28
|
+
enable_inventory (bool): Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file.
|
29
|
+
fallback_theme (str): The fallback theme.
|
30
|
+
fallback_config (ClassVar[dict]): The configuration used to collect item during autorefs fallback.
|
31
|
+
default_config (ClassVar[dict]): The default configuration for the handler.
|
32
|
+
|
33
|
+
Methods:
|
34
|
+
__init__(self, *args, config_file_path=None, paths=None, startup_expression="", locale="en", **kwargs): Initializes a new instance of the `MatlabHandler` class.
|
35
|
+
get_templates_dir(self, handler=None): Returns the templates directory for the handler.
|
36
|
+
collect(self, identifier, config): Collects the documentation for the given identifier.
|
37
|
+
render(self, data, config): Renders the collected documentation data.
|
38
|
+
update_env(self, md, config): Updates the Jinja environment with custom filters and tests.
|
39
|
+
"""
|
40
|
+
|
41
|
+
name: str = "matlab"
|
42
|
+
"""The handler's name."""
|
43
|
+
domain: str = "mat" # to match Sphinx's default domain
|
44
|
+
"""The cross-documentation domain/language for this handler."""
|
45
|
+
enable_inventory: bool = True
|
46
|
+
"""Whether this handler is interested in enabling the creation of the `objects.inv` Sphinx inventory file."""
|
47
|
+
fallback_theme = "material"
|
48
|
+
"""The fallback theme."""
|
49
|
+
fallback_config: ClassVar[dict] = {"fallback": True}
|
50
|
+
"""The configuration used to collect item during autorefs fallback."""
|
51
|
+
default_config: ClassVar[dict] = {
|
52
|
+
# https://mkdocstrings.github.io/python/usage/
|
53
|
+
# General options
|
54
|
+
# "find_stubs_package": False,
|
55
|
+
# "allow_inspection": True,
|
56
|
+
"show_bases": True,
|
57
|
+
"show_inheritance_diagram": False, # not implemented
|
58
|
+
"show_source": False, # not implemented
|
59
|
+
# "preload_modules": None,
|
60
|
+
# Heading options
|
61
|
+
"heading_level": 2,
|
62
|
+
"parameter_headings": False,
|
63
|
+
"show_root_heading": False,
|
64
|
+
"show_root_toc_entry": True,
|
65
|
+
"show_root_full_path": True,
|
66
|
+
"show_root_members_full_path": False,
|
67
|
+
"show_object_full_path": False,
|
68
|
+
"show_category_heading": False,
|
69
|
+
"show_symbol_type_heading": False,
|
70
|
+
"show_symbol_type_toc": False,
|
71
|
+
# Member options
|
72
|
+
"inherited_members": False,
|
73
|
+
"members": None,
|
74
|
+
"members_order": rendering.Order.alphabetical.value,
|
75
|
+
"filters": ["!^_[^_]"],
|
76
|
+
"group_by_category": True,
|
77
|
+
"show_submodules": False,
|
78
|
+
"summary": False,
|
79
|
+
"show_labels": True,
|
80
|
+
# Docstring options
|
81
|
+
"docstring_style": "google",
|
82
|
+
"docstring_options": {},
|
83
|
+
"docstring_section_style": "table",
|
84
|
+
"merge_init_into_class": False,
|
85
|
+
"show_if_no_docstring": False,
|
86
|
+
"show_docstring_attributes": True,
|
87
|
+
"show_docstring_functions": True,
|
88
|
+
"show_docstring_classes": True,
|
89
|
+
"show_docstring_modules": True,
|
90
|
+
"show_docstring_description": True,
|
91
|
+
"show_docstring_examples": True,
|
92
|
+
"show_docstring_other_parameters": True,
|
93
|
+
"show_docstring_parameters": True,
|
94
|
+
"show_docstring_raises": True,
|
95
|
+
"show_docstring_receives": True,
|
96
|
+
"show_docstring_returns": True,
|
97
|
+
"show_docstring_warns": True,
|
98
|
+
"show_docstring_yields": True,
|
99
|
+
# Signature options
|
100
|
+
"annotations_path": "brief",
|
101
|
+
"line_length": 60,
|
102
|
+
"show_signature": True,
|
103
|
+
"show_signature_annotations": False,
|
104
|
+
"signature_crossrefs": False,
|
105
|
+
"separate_signature": True,
|
106
|
+
"unwrap_annotated": False,
|
107
|
+
"modernize_annotations": False,
|
108
|
+
}
|
109
|
+
|
110
|
+
def __init__(
|
111
|
+
self,
|
112
|
+
*args: Any,
|
113
|
+
config_file_path: str | None = None,
|
114
|
+
paths: list[str] | None = None,
|
115
|
+
startup_expression: str = "",
|
116
|
+
locale: str = "en",
|
117
|
+
**kwargs: Any,
|
118
|
+
) -> None:
|
119
|
+
super().__init__(*args, **kwargs)
|
120
|
+
|
121
|
+
if paths is None:
|
122
|
+
paths = ""
|
123
|
+
|
124
|
+
self.engine = MatlabEngine()
|
125
|
+
self.engine.addpath(str(Path(__file__).parent / "matlab"))
|
126
|
+
self.engine.matlab_startup(paths, startup_expression)
|
127
|
+
self._locale = locale
|
128
|
+
|
129
|
+
def get_templates_dir(self, handler: str | None = None) -> Path:
|
130
|
+
# use the python handler templates
|
131
|
+
# (it assumes the python handler is installed)
|
132
|
+
return super().get_templates_dir("python")
|
133
|
+
|
134
|
+
def collect(self, identifier: str, config: Mapping[str, Any]) -> CollectorItem:
|
135
|
+
"""Collect data given an identifier and user configuration.
|
136
|
+
|
137
|
+
In the implementation, you typically call a subprocess that returns JSON, and load that JSON again into
|
138
|
+
a Python dictionary for example, though the implementation is completely free.
|
139
|
+
|
140
|
+
Arguments:
|
141
|
+
identifier: An identifier for which to collect data.
|
142
|
+
config: The handler's configuration options.
|
143
|
+
|
144
|
+
Returns:
|
145
|
+
CollectorItem
|
146
|
+
"""
|
147
|
+
final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
|
148
|
+
try:
|
149
|
+
ast_json = self.engine.docstring.resolve(identifier)
|
150
|
+
except MatlabExecutionError as error:
|
151
|
+
raise CollectionError(error.args[0].strip()) from error
|
152
|
+
ast_dict = json.loads(ast_json)
|
153
|
+
|
154
|
+
match ast_dict["type"]:
|
155
|
+
case "function":
|
156
|
+
return collect_function(ast_dict, final_config)
|
157
|
+
case "method":
|
158
|
+
return collect_function(ast_dict, final_config)
|
159
|
+
case "class":
|
160
|
+
return self.collect_class(ast_dict, final_config)
|
161
|
+
case _:
|
162
|
+
return None
|
163
|
+
|
164
|
+
def render(self, data: CollectorItem, config: Mapping[str, Any]) -> str:
|
165
|
+
"""Render a template using provided data and configuration options.
|
166
|
+
|
167
|
+
Arguments:
|
168
|
+
data: The collected data to render.
|
169
|
+
config: The handler's configuration options.
|
170
|
+
|
171
|
+
Returns:
|
172
|
+
The rendered template as HTML.
|
173
|
+
"""
|
174
|
+
final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
|
175
|
+
|
176
|
+
template_name = rendering.do_get_template(self.env, data)
|
177
|
+
template = self.env.get_template(template_name)
|
178
|
+
|
179
|
+
heading_level = final_config["heading_level"]
|
180
|
+
|
181
|
+
return template.render(
|
182
|
+
**{
|
183
|
+
"config": final_config,
|
184
|
+
data.kind.value: data,
|
185
|
+
"heading_level": heading_level,
|
186
|
+
"root": True,
|
187
|
+
"locale": self._locale,
|
188
|
+
},
|
189
|
+
)
|
190
|
+
|
191
|
+
def get_anchors(self, data: CollectorItem) -> tuple[str, ...]:
|
192
|
+
"""Return the possible identifiers (HTML anchors) for a collected item.
|
193
|
+
|
194
|
+
Arguments:
|
195
|
+
data: The collected data.
|
196
|
+
|
197
|
+
Returns:
|
198
|
+
The HTML anchors (without '#'), or an empty tuple if this item doesn't have an anchor.
|
199
|
+
"""
|
200
|
+
anchors = [data.path]
|
201
|
+
return tuple(anchors)
|
202
|
+
|
203
|
+
def update_env(self, md: Markdown, config: dict) -> None:
|
204
|
+
"""Update the Jinja environment with custom filters and tests.
|
205
|
+
|
206
|
+
Parameters:
|
207
|
+
md: The Markdown instance.
|
208
|
+
config: The configuration dictionary.
|
209
|
+
"""
|
210
|
+
super().update_env(md, config)
|
211
|
+
self.env.trim_blocks = True
|
212
|
+
self.env.lstrip_blocks = True
|
213
|
+
self.env.keep_trailing_newline = False
|
214
|
+
self.env.filters["split_path"] = rendering.do_split_path
|
215
|
+
self.env.filters["crossref"] = rendering.do_crossref
|
216
|
+
self.env.filters["multi_crossref"] = rendering.do_multi_crossref
|
217
|
+
self.env.filters["order_members"] = rendering.do_order_members
|
218
|
+
self.env.filters["format_code"] = rendering.do_format_code
|
219
|
+
self.env.filters["format_signature"] = rendering.do_format_signature
|
220
|
+
self.env.filters["format_attribute"] = rendering.do_format_attribute
|
221
|
+
self.env.filters["filter_objects"] = rendering.do_filter_objects
|
222
|
+
self.env.filters["stash_crossref"] = lambda ref, length: ref
|
223
|
+
self.env.filters["get_template"] = rendering.do_get_template
|
224
|
+
self.env.filters["as_attributes_section"] = rendering.do_as_attributes_section
|
225
|
+
self.env.filters["as_functions_section"] = rendering.do_as_functions_section
|
226
|
+
self.env.filters["as_classes_section"] = rendering.do_as_classes_section
|
227
|
+
self.env.filters["as_modules_section"] = rendering.do_as_modules_section
|
228
|
+
self.env.tests["existing_template"] = (
|
229
|
+
lambda template_name: template_name in self.env.list_templates()
|
230
|
+
)
|
231
|
+
|
232
|
+
|
233
|
+
def collect_class(self, ast_dict: dict, config: Mapping) -> Class:
|
234
|
+
docstring = (
|
235
|
+
Docstring(ast_dict["docstring"], parser=config["docstring_style"])
|
236
|
+
if ast_dict["docstring"]
|
237
|
+
else None
|
238
|
+
)
|
239
|
+
object = Class(
|
240
|
+
ast_dict["name"],
|
241
|
+
docstring=docstring,
|
242
|
+
parent=get_parent(Path(ast_dict["path"]).parent),
|
243
|
+
hidden=ast_dict["hidden"],
|
244
|
+
sealed=ast_dict["sealed"],
|
245
|
+
abstract=ast_dict["abstract"],
|
246
|
+
enumeration=ast_dict["enumeration"],
|
247
|
+
handle=ast_dict["handle"],
|
248
|
+
)
|
249
|
+
|
250
|
+
|
251
|
+
for property_dict in ast_dict["properties"]:
|
252
|
+
name = property_dict.pop("name")
|
253
|
+
defining_class = property_dict.pop("class")
|
254
|
+
property_doc = property_dict.pop("docstring")
|
255
|
+
docstring = (
|
256
|
+
Docstring(property_doc, parser=config["docstring_style"])
|
257
|
+
if property_doc
|
258
|
+
else None
|
259
|
+
)
|
260
|
+
if defining_class != object.canonical_path and not config["inherited_members"]:
|
261
|
+
continue
|
262
|
+
|
263
|
+
object.members[name] = Property(name, docstring=docstring, **property_dict)
|
264
|
+
|
265
|
+
for method_dict in ast_dict["methods"]:
|
266
|
+
name = method_dict.pop("name")
|
267
|
+
defining_class = method_dict.pop("class")
|
268
|
+
if defining_class != object.canonical_path and not config["inherited_members"]:
|
269
|
+
continue
|
270
|
+
|
271
|
+
method = self.collect(f"{defining_class}.{name}", config)
|
272
|
+
method._access = method_dict["access"]
|
273
|
+
method._static = method_dict["static"]
|
274
|
+
method._abstract = method_dict["abstract"]
|
275
|
+
method._sealed = method_dict["sealed"]
|
276
|
+
method._hidden = method_dict["hidden"]
|
277
|
+
|
278
|
+
object.members[name] = method
|
279
|
+
|
280
|
+
return object
|
281
|
+
|
282
|
+
def get_parent(path: Path) -> Namespace | Classfolder:
|
283
|
+
if path.stem[0] == "+":
|
284
|
+
if path in MODELS:
|
285
|
+
parent = MODELS[path]
|
286
|
+
else:
|
287
|
+
parent = Namespace(
|
288
|
+
path.stem[1:], filepath=str(path), parent=get_parent(path.parent)
|
289
|
+
)
|
290
|
+
MODELS[path] = parent
|
291
|
+
elif path.stem[0] == "@":
|
292
|
+
if path in MODELS:
|
293
|
+
parent = MODELS[path]
|
294
|
+
else:
|
295
|
+
parent = Classfolder(
|
296
|
+
path.stem[1:], filepath=str(path), parent=get_parent(path.parent)
|
297
|
+
)
|
298
|
+
MODELS[path] = parent
|
299
|
+
else:
|
300
|
+
parent = ROOT_NAMESPACE
|
301
|
+
return parent
|
302
|
+
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
def collect_function(ast_dict: dict, config: Mapping) -> Function:
|
308
|
+
parameters = []
|
309
|
+
|
310
|
+
inputs = (
|
311
|
+
ast_dict["inputs"]
|
312
|
+
if isinstance(ast_dict["inputs"], list)
|
313
|
+
else [ast_dict["inputs"]]
|
314
|
+
)
|
315
|
+
for input_dict in inputs:
|
316
|
+
if input_dict["name"] == "varargin":
|
317
|
+
parameter_kind = ParameterKind.var_positional
|
318
|
+
elif input_dict["kind"] == "positional":
|
319
|
+
parameter_kind = ParameterKind.positional_only
|
320
|
+
else:
|
321
|
+
parameter_kind = ParameterKind.keyword_only
|
322
|
+
|
323
|
+
parameters.append(
|
324
|
+
Parameter(
|
325
|
+
input_dict["name"],
|
326
|
+
kind=parameter_kind,
|
327
|
+
annotation=input_dict["class"],
|
328
|
+
default=input_dict["default"] if input_dict["default"] else None,
|
329
|
+
)
|
330
|
+
)
|
331
|
+
|
332
|
+
func = Function(
|
333
|
+
ast_dict["name"],
|
334
|
+
parameters=Parameters(*parameters),
|
335
|
+
docstring=Docstring(
|
336
|
+
ast_dict["docstring"],
|
337
|
+
parser=config["docstring_style"],
|
338
|
+
parser_options=config["docstring_options"],
|
339
|
+
)
|
340
|
+
if ast_dict["docstring"]
|
341
|
+
else None,
|
342
|
+
parent=get_parent(Path(ast_dict["path"]).parent),
|
343
|
+
)
|
344
|
+
|
345
|
+
return func
|
346
|
+
|
347
|
+
|
348
|
+
def get_handler(
|
349
|
+
*,
|
350
|
+
theme: str,
|
351
|
+
custom_templates: str | None = None,
|
352
|
+
config_file_path: str | None = None,
|
353
|
+
paths: list[str] | None = None,
|
354
|
+
startup_expression: str = "",
|
355
|
+
**config: Any,
|
356
|
+
) -> MatlabHandler:
|
357
|
+
"""
|
358
|
+
Returns a MatlabHandler object.
|
359
|
+
|
360
|
+
Parameters:
|
361
|
+
theme (str): The theme to use.
|
362
|
+
custom_templates (str | None, optional): Path to custom templates. Defaults to None.
|
363
|
+
config_file_path (str | None, optional): Path to configuration file. Defaults to None.
|
364
|
+
paths (list[str] | None, optional): List of paths to include. Defaults to None.
|
365
|
+
startup_expression (str, optional): Startup expression. Defaults to "".
|
366
|
+
**config (Any): Additional configuration options.
|
367
|
+
|
368
|
+
Returns:
|
369
|
+
MatlabHandler: The created MatlabHandler object.
|
370
|
+
"""
|
371
|
+
return MatlabHandler(
|
372
|
+
handler="matlab",
|
373
|
+
theme=theme,
|
374
|
+
custom_templates=custom_templates,
|
375
|
+
config_file_path=config_file_path,
|
376
|
+
paths=paths,
|
377
|
+
startup_expression=startup_expression,
|
378
|
+
)
|
379
|
+
|
380
|
+
|
381
|
+
if __name__ == "__main__":
|
382
|
+
handler = get_handler(theme="material")
|
383
|
+
pprint(handler.collect("matlab_startup", {}).docstring.parse("google"))
|
@@ -0,0 +1,12 @@
|
|
1
|
+
function data = class(identifier)
|
2
|
+
|
3
|
+
if isMATLABReleaseOlderThan('R2024a')
|
4
|
+
metaclass = @meta.class.fromName;
|
5
|
+
else
|
6
|
+
metaclass = @matlab.metadata.Class.fromName;
|
7
|
+
end
|
8
|
+
|
9
|
+
object = metaclass(identifier);
|
10
|
+
data = docstring.metadata.class(object);
|
11
|
+
|
12
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+case/namespace.m
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
function data = namespace(identifier)
|
2
|
+
|
3
|
+
currentpath = split(pwd, filesep);
|
4
|
+
|
5
|
+
name = identifier(2:end);
|
6
|
+
|
7
|
+
if isfolder(identifier)
|
8
|
+
for i = numel(currentpath):-1:1
|
9
|
+
directory = currentpath(i);
|
10
|
+
if isempty(directory)
|
11
|
+
break
|
12
|
+
elseif strcmp(directory(1), '+')
|
13
|
+
name = sprintf("%s.%s", directory(2:end), name);
|
14
|
+
else
|
15
|
+
break
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
object = matlab.metadata.Namespace.fromName(name);
|
21
|
+
|
22
|
+
if isempty(object)
|
23
|
+
docstring.exception(identifier)
|
24
|
+
end
|
25
|
+
|
26
|
+
data = docstring.metadata.namespace(object);
|
27
|
+
data.name = name;
|
28
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/argument.m
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
function data = argument(object)
|
2
|
+
arguments
|
3
|
+
object (1,:) matlab.internal.metadata.Argument
|
4
|
+
end
|
5
|
+
|
6
|
+
if isempty(object)
|
7
|
+
data = struct.empty();
|
8
|
+
return
|
9
|
+
elseif numel(object) > 1
|
10
|
+
for iArg = numel(object):-1:1
|
11
|
+
data(iArg) = docstring.metadata.argument(object(iArg));
|
12
|
+
end
|
13
|
+
return
|
14
|
+
end
|
15
|
+
|
16
|
+
data.name = object.Name;
|
17
|
+
data.kind = string(object.Kind);
|
18
|
+
data.presence = string(object.Presence);
|
19
|
+
|
20
|
+
if isempty(object.DefaultValue)
|
21
|
+
data.default = "";
|
22
|
+
elseif object.DefaultValue.IsConstant
|
23
|
+
data.default = string(object.DefaultValue.Value);
|
24
|
+
else
|
25
|
+
data.default = "*expression*";
|
26
|
+
end
|
27
|
+
|
28
|
+
if ~isempty(object.Validation)
|
29
|
+
if ~isempty(object.Validation.Class)
|
30
|
+
data.class = string(object.Validation.Class.Name);
|
31
|
+
else
|
32
|
+
data.class = "";
|
33
|
+
end
|
34
|
+
if ~isempty(object.Validation.Size)
|
35
|
+
for iSize = numel(object.Validation.Size):-1:1
|
36
|
+
|
37
|
+
if isprop(object.Validation.Size(iSize), 'Length')
|
38
|
+
data.size(iSize) = object.Validation.Size(iSize).Length;
|
39
|
+
else
|
40
|
+
data.size(iSize) = ":";
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
data.size = "";
|
45
|
+
end
|
46
|
+
|
47
|
+
if ~isempty(object.Validation.Functions)
|
48
|
+
data.validators = arrayfun(@(f) string(f.Name), object.Validation.Functions);
|
49
|
+
else
|
50
|
+
data.validators = "";
|
51
|
+
end
|
52
|
+
else
|
53
|
+
data.class = "";
|
54
|
+
data.size = "";
|
55
|
+
data.validators = "";
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
function data = class(object)
|
2
|
+
arguments
|
3
|
+
object (1,1) matlab.metadata.Class
|
4
|
+
end
|
5
|
+
data.type = 'class';
|
6
|
+
|
7
|
+
namespaces = split(object.Name, '.');
|
8
|
+
data.name = namespaces{end};
|
9
|
+
|
10
|
+
data.docstring = docstring.utils.parse_doc(object, true);
|
11
|
+
data.path = matlab.internal.metafunction(object.Name).Location;
|
12
|
+
data.hidden = object.Hidden;
|
13
|
+
data.sealed = object.Sealed;
|
14
|
+
data.abstract = object.Abstract;
|
15
|
+
data.enumeration = object.Enumeration;
|
16
|
+
data.superclasses = arrayfun(@(o) string(o.Name), object.SuperclassList);
|
17
|
+
data.handle = object.HandleCompatible;
|
18
|
+
data.aliases = object.Aliases;
|
19
|
+
|
20
|
+
data.methods = [];
|
21
|
+
for methodObject = object.MethodList'
|
22
|
+
if any(strcmp(methodObject.Name, {'empty', 'forInteractiveUse'}))
|
23
|
+
break
|
24
|
+
else
|
25
|
+
method.name = string(methodObject.Name);
|
26
|
+
method.class = string(methodObject.DefiningClass.Name);
|
27
|
+
method.access = methodObject.Access;
|
28
|
+
method.static = methodObject.Static;
|
29
|
+
method.abstract = methodObject.Abstract;
|
30
|
+
method.sealed = methodObject.Sealed;
|
31
|
+
method.hidden = methodObject.Hidden;
|
32
|
+
data.methods = [data.methods, method];
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
numProp = numel(object.PropertyList);
|
37
|
+
for iProp = numProp:-1:1
|
38
|
+
data.properties(iProp) = docstring.metadata.property(object.PropertyList(iProp));
|
39
|
+
end
|
40
|
+
|
41
|
+
nameparts = split(object.Name, '.');
|
42
|
+
data.constructor = any(strcmp(nameparts(end), [data.methods.name]));
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
function data = func(object)
|
2
|
+
|
3
|
+
arguments
|
4
|
+
object (1,1) matlab.metadata.MetaData
|
5
|
+
end
|
6
|
+
|
7
|
+
data.type = 'function';
|
8
|
+
data.name = object.Name;
|
9
|
+
data.docstring = docstring.utils.parse_doc(object);
|
10
|
+
data.path = object.Location;
|
11
|
+
|
12
|
+
data.inputs = docstring.metadata.argument(object.Signature.Inputs);
|
13
|
+
data.outputs = docstring.metadata.argument(object.Signature.Outputs);
|
14
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/namespace.m
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
function data = namespace(object)
|
2
|
+
|
3
|
+
arguments
|
4
|
+
object (1,1) matlab.metadata.Namespace
|
5
|
+
end
|
6
|
+
|
7
|
+
data.type = 'namespace';
|
8
|
+
data.docstring = docstring.utils.parse_doc(object);
|
9
|
+
|
10
|
+
data.classes = arrayfun(@(o) string(o.Name), object.ClassList);
|
11
|
+
data.functions = arrayfun(@(o) string(o.Name), object.FunctionList);
|
12
|
+
data.namespaces = arrayfun(@(o) string(o.Name), object.InnerNamespaces);
|
13
|
+
data.path = docstring.utils.get_namespace_path(object);
|
14
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/property.m
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
function data = argument(object)
|
2
|
+
arguments
|
3
|
+
object (1,:) meta.property
|
4
|
+
end
|
5
|
+
|
6
|
+
data.name = string(object.Name);
|
7
|
+
data.class = string(object.DefiningClass.Name);
|
8
|
+
data.docstring = docstring.utils.parse_doc(object);
|
9
|
+
data.get_access = object.GetAccess;
|
10
|
+
data.set_access = object.SetAccess;
|
11
|
+
data.dependent = object.Dependent;
|
12
|
+
data.constant = object.Constant;
|
13
|
+
data.abstract = object.Abstract;
|
14
|
+
data.transient = object.Transient;
|
15
|
+
data.hidden = object.Hidden;
|
16
|
+
|
17
|
+
if ~isempty(object.Validation) && ~isempty(object.Validation.Class)
|
18
|
+
data.annotation = string(object.Validation.Class.Name);
|
19
|
+
else
|
20
|
+
data.annotation = "";
|
21
|
+
end
|
22
|
+
|
23
|
+
if ~isempty(object.Validation) && ~isempty(object.Validation.Size)
|
24
|
+
for iSize = numel(object.Validation.Size):-1:1
|
25
|
+
if isprop(object.Validation.Size(iSize), 'Length')
|
26
|
+
sizeStr(iSize) = string(object.Validation.Size(iSize).Length);
|
27
|
+
else
|
28
|
+
sizeStr(iSize) = ":";
|
29
|
+
end
|
30
|
+
end
|
31
|
+
data.size = sprintf("[%s]", join(sizeStr, ","));
|
32
|
+
else
|
33
|
+
data.size = "";
|
34
|
+
end
|
35
|
+
|
36
|
+
if ~isempty(object.Validation) && ~isempty(object.Validation.ValidatorFunctions)
|
37
|
+
data.validation = join(cellfun(@(f) string(char(f)), object.Validation.ValidatorFunctions), ", ");
|
38
|
+
else
|
39
|
+
data.validation = "";
|
40
|
+
end
|
41
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/script.m
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
function data = script(object)
|
2
|
+
%SCRIPT Summary of this function goes here
|
3
|
+
% Detailed explanation goes here
|
4
|
+
|
5
|
+
arguments
|
6
|
+
object (1,1) matlab.metadata.MetaData
|
7
|
+
end
|
8
|
+
|
9
|
+
data.type = 'script';
|
10
|
+
data.Name = object.Name;
|
11
|
+
data.docstring = docstring.utils.parse_doc(object);
|
12
|
+
data.path = object.Location;
|
13
|
+
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
function parsedDoc = dedent(doc)
|
2
|
+
%DEDENT Summary of this function goes here
|
3
|
+
% Detailed explanation goes here
|
4
|
+
arguments
|
5
|
+
doc (1,1) string
|
6
|
+
end
|
7
|
+
|
8
|
+
lines = cellstr(splitlines(doc));
|
9
|
+
|
10
|
+
|
11
|
+
for iLine = numel(lines):-1:1
|
12
|
+
line = lines{iLine};
|
13
|
+
if ~isempty(line) && ~all(line == ' ')
|
14
|
+
indentations(iLine) = find(line~= ' ', 1);
|
15
|
+
else
|
16
|
+
indentations(iLine) = inf;
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
indentation = min(indentations);
|
21
|
+
|
22
|
+
for iLine = 1:numel(lines)
|
23
|
+
line = lines{iLine};
|
24
|
+
if isempty(line) || numel(line) <= indentation
|
25
|
+
lines{iLine} = '';
|
26
|
+
else
|
27
|
+
lines{iLine} = line(indentation:end);
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
parsedDoc = string(strjoin(lines, '\n'));
|
32
|
+
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
function path = get_namespace_path(object, parents)
|
2
|
+
|
3
|
+
arguments
|
4
|
+
object (1,1) matlab.metadata.Namespace
|
5
|
+
parents (1,1) double {mustBeInteger, mustBeNonnegative} = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
if ~isempty(object.ClassList)
|
9
|
+
|
10
|
+
function_path = which(sprintf("%s.%s", object.Name, object.ClassList(1).Name));
|
11
|
+
path = fileparts(function_path);
|
12
|
+
elseif ~isempty(object.FunctionList)
|
13
|
+
|
14
|
+
function_path = which(sprintf("%s.%s", object.Name, object.FunctionList(1).Name));
|
15
|
+
path = fileparts(function_path);
|
16
|
+
elseif ~isempty(object.InnerNamespaces)
|
17
|
+
path = docstring.utils.get_namespace_path(...
|
18
|
+
object.InnerNamespaces(1), parents + 1);
|
19
|
+
else
|
20
|
+
error("Cannot get path of namespace %s", object.Name);
|
21
|
+
end
|
22
|
+
|
23
|
+
for i = 1:parents
|
24
|
+
path = fileparts(path);
|
25
|
+
end
|
26
|
+
end
|
mkdocstrings_matlab-0.1.0/src/mkdocstrings_handlers/matlab/matlab/+docstring/+utils/parse_doc.m
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
function doc = parse_doc(object, combine)
|
2
|
+
|
3
|
+
arguments
|
4
|
+
object (1,1) matlab.metadata.MetaData
|
5
|
+
combine (1,1) logical = false
|
6
|
+
end
|
7
|
+
|
8
|
+
if isempty(object.DetailedDescription)
|
9
|
+
doc = object.Description;
|
10
|
+
else
|
11
|
+
if combine
|
12
|
+
doc = sprintf("%s\n%s", object.Description, ...
|
13
|
+
docstring.utils.dedent(object.DetailedDescription));
|
14
|
+
else
|
15
|
+
doc = docstring.utils.dedent(object.DetailedDescription);
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
function [jsonString, data] = resolve(identifier, cwd)
|
2
|
+
% Resolve the docstring for a given MATLAB entity
|
3
|
+
%
|
4
|
+
% ```matlab
|
5
|
+
% jsonString = resolve(name, cwd)
|
6
|
+
% ```
|
7
|
+
%
|
8
|
+
% Parameters:
|
9
|
+
% identifier (string): Name of the MATLAB entity
|
10
|
+
% cwd (string): Current working directory
|
11
|
+
%
|
12
|
+
% Returns:
|
13
|
+
% jsonString(string): JSON-encoded metadata object
|
14
|
+
% data(struct): metadata object
|
15
|
+
|
16
|
+
arguments
|
17
|
+
identifier (1, :) char
|
18
|
+
cwd (1,1) string {mustBeFolder} = pwd()
|
19
|
+
end
|
20
|
+
|
21
|
+
cd(cwd);
|
22
|
+
|
23
|
+
% Check if namespace
|
24
|
+
if strcmp(identifier(1), '+')
|
25
|
+
data = docstring.case.namespace(identifier);
|
26
|
+
jsonString = jsonencode(data);
|
27
|
+
return;
|
28
|
+
end
|
29
|
+
|
30
|
+
% Try namespace functions
|
31
|
+
if contains(identifier, '.')
|
32
|
+
object = matlab.internal.metafunction(identifier);
|
33
|
+
if ~isempty(object) && isa(object, 'matlab.internal.metadata.Function')
|
34
|
+
if isempty(object.Signature)
|
35
|
+
data = docstring.metadata.script(object);
|
36
|
+
else
|
37
|
+
data = docstring.metadata.func(object);
|
38
|
+
end
|
39
|
+
jsonString = jsonencode(data);
|
40
|
+
return;
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
% Try built-in aliases with which
|
45
|
+
if contains(which(identifier), ' built-in ')
|
46
|
+
data = docstring.case.builtin(identifier);
|
47
|
+
jsonString = jsonencode(data);
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
switch exist(identifier) %#ok<EXIST>
|
52
|
+
case 2
|
53
|
+
% if NAME is a file with extension .m, .mlx, .mlapp, or .sfx, or NAME
|
54
|
+
% is the name of a file with a non-registered file extension
|
55
|
+
% (.mat, .fig, .txt).
|
56
|
+
|
57
|
+
% Try with metafunction
|
58
|
+
object = matlab.internal.metafunction(identifier);
|
59
|
+
if ~isempty(object) && isa(object, 'matlab.internal.metadata.Function')
|
60
|
+
if isempty(object.Signature)
|
61
|
+
data = docstring.metadata.script(object);
|
62
|
+
else
|
63
|
+
data = docstring.metadata.func(object);
|
64
|
+
end
|
65
|
+
data.name = identifier;
|
66
|
+
else
|
67
|
+
docstring.exception(identifier);
|
68
|
+
end
|
69
|
+
case 5
|
70
|
+
% if NAME is a built-in MATLAB function. This does not include classes
|
71
|
+
data = docstring.case.builtin(identifier);
|
72
|
+
case 8
|
73
|
+
% if NAME is a class (exist returns 0 for Java classes if you
|
74
|
+
% start MATLAB with the -nojvm option.)
|
75
|
+
data = docstring.case.class(identifier);
|
76
|
+
case 0
|
77
|
+
if contains(identifier, '.')
|
78
|
+
nameparts = split(identifier, '.');
|
79
|
+
tryclassname = strjoin(nameparts(1:end-1), '.');
|
80
|
+
if exist(tryclassname, 'class')
|
81
|
+
data = docstring.case.method(identifier);
|
82
|
+
else
|
83
|
+
docstring.exception(identifier);
|
84
|
+
end
|
85
|
+
else
|
86
|
+
docstring.exception(identifier);
|
87
|
+
end
|
88
|
+
otherwise
|
89
|
+
docstring.exception(identifier);
|
90
|
+
end
|
91
|
+
|
92
|
+
jsonString = jsonencode(data);
|
93
|
+
|
94
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
function result = matlab_startup(paths, expression)
|
2
|
+
% Add paths and evaluate an expression
|
3
|
+
%
|
4
|
+
% Parameters:
|
5
|
+
% paths (string): Paths to add to the MATLAB path
|
6
|
+
% expression (string): MATLAB startup expression
|
7
|
+
|
8
|
+
arguments
|
9
|
+
paths (1, :) string
|
10
|
+
expression (1, 1) string = string.empty()
|
11
|
+
end
|
12
|
+
for path = paths
|
13
|
+
addpath(genpath(path));
|
14
|
+
end
|
15
|
+
|
16
|
+
if ~isempty(expression)
|
17
|
+
eval(expression);
|
18
|
+
end
|
19
|
+
|
20
|
+
result = nan;
|
21
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
from enum import Enum
|
2
|
+
from typing import Any
|
3
|
+
from griffe import Function as GriffeFunction, Class as GriffeClass, Module, Attribute
|
4
|
+
from _griffe.exceptions import BuiltinModuleError
|
5
|
+
|
6
|
+
|
7
|
+
class Access(Enum):
|
8
|
+
PUBLIC = "public"
|
9
|
+
PROTECTED = "protected"
|
10
|
+
PRIVATE = "private"
|
11
|
+
IMMUTABLE = "immutable"
|
12
|
+
|
13
|
+
|
14
|
+
class CanonicalPathMixin:
|
15
|
+
@property
|
16
|
+
def canonical_path(self) -> str:
|
17
|
+
"""The full dotted path of this object.
|
18
|
+
|
19
|
+
The canonical path is the path where the object was defined (not imported).
|
20
|
+
"""
|
21
|
+
if self.parent is None or self.parent.path == "":
|
22
|
+
return self.name
|
23
|
+
return f"{self.parent.path}.{self.name}"
|
24
|
+
|
25
|
+
|
26
|
+
class Class(CanonicalPathMixin, GriffeClass):
|
27
|
+
def __init__(
|
28
|
+
self,
|
29
|
+
*args: Any,
|
30
|
+
hidden: bool = False,
|
31
|
+
sealed: bool = False,
|
32
|
+
abstract: bool = False,
|
33
|
+
enumeration: bool = False,
|
34
|
+
handle: bool = False,
|
35
|
+
**kwargs: Any,
|
36
|
+
) -> None:
|
37
|
+
super().__init__(*args, **kwargs)
|
38
|
+
self._hidden: bool = hidden
|
39
|
+
self._sealed: bool = sealed
|
40
|
+
self._abstract: bool = abstract
|
41
|
+
self._enumeration: bool = enumeration
|
42
|
+
self._handle: bool = handle
|
43
|
+
|
44
|
+
@property
|
45
|
+
def is_private(self) -> bool:
|
46
|
+
return self._hidden
|
47
|
+
|
48
|
+
@property
|
49
|
+
def canonical_path(self) -> str:
|
50
|
+
if isinstance(self.parent, Classfolder):
|
51
|
+
return self.parent.canonical_path
|
52
|
+
else:
|
53
|
+
return super().canonical_path
|
54
|
+
|
55
|
+
|
56
|
+
class Property(CanonicalPathMixin, Attribute):
|
57
|
+
def __init__(
|
58
|
+
self,
|
59
|
+
*args: Any,
|
60
|
+
get_access: Access = Access.PUBLIC,
|
61
|
+
set_access: Access = Access.PUBLIC,
|
62
|
+
dependent: bool = False,
|
63
|
+
constant: bool = False,
|
64
|
+
abstract: bool = False,
|
65
|
+
transient: bool = False,
|
66
|
+
hidden: bool = False,
|
67
|
+
get_observable: bool = False,
|
68
|
+
set_observable: bool = False,
|
69
|
+
abort_set: bool = False,
|
70
|
+
non_copyable: bool = False,
|
71
|
+
has_default: bool = False,
|
72
|
+
size: str | None = None,
|
73
|
+
validation: str | None = None,
|
74
|
+
**kwargs: Any,
|
75
|
+
) -> None:
|
76
|
+
super().__init__(*args, **kwargs)
|
77
|
+
self._get_access: Access = get_access
|
78
|
+
self._set_access: Access = set_access
|
79
|
+
self._dependent: bool = dependent
|
80
|
+
self._constant: bool = constant
|
81
|
+
self._abstract: bool = abstract
|
82
|
+
self._transient: bool = transient
|
83
|
+
self._hidden: bool = hidden
|
84
|
+
self._get_observable: bool = get_observable
|
85
|
+
self._set_observable: bool = set_observable
|
86
|
+
self._abort_set: bool = abort_set
|
87
|
+
self._non_copyable: bool = non_copyable
|
88
|
+
self._has_default: bool = has_default
|
89
|
+
self._size: str | None = size
|
90
|
+
self._validation: str | None = validation
|
91
|
+
|
92
|
+
@property
|
93
|
+
def is_private(self) -> bool:
|
94
|
+
set_public = self._access == Access.PUBLIC | self._access == Access.IMMUTABLE
|
95
|
+
get_public = self._access == Access.PUBLIC
|
96
|
+
return (set_public or get_public) and not self._hidden
|
97
|
+
|
98
|
+
|
99
|
+
class Function(CanonicalPathMixin, GriffeFunction):
|
100
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
101
|
+
super().__init__(*args, **kwargs)
|
102
|
+
self._access: Access = Access.PUBLIC
|
103
|
+
self._static: bool = False
|
104
|
+
self._abstract: bool = False
|
105
|
+
self._sealed: bool = False
|
106
|
+
self._hidden: bool = False
|
107
|
+
|
108
|
+
@property
|
109
|
+
def is_private(self) -> bool:
|
110
|
+
public = self._access == Access.PUBLIC | self._access == Access.IMMUTABLE
|
111
|
+
return public and not self._hidden
|
112
|
+
|
113
|
+
|
114
|
+
class Namespace(CanonicalPathMixin, Module):
|
115
|
+
def __repr__(self) -> str:
|
116
|
+
try:
|
117
|
+
return f"Namespace({self.filepath!r})"
|
118
|
+
except BuiltinModuleError:
|
119
|
+
return f"Namespace({self.name!r})"
|
120
|
+
|
121
|
+
|
122
|
+
class Classfolder(CanonicalPathMixin, Module):
|
123
|
+
def __repr__(self) -> str:
|
124
|
+
try:
|
125
|
+
return f"Classfolder({self.filepath!r})"
|
126
|
+
except BuiltinModuleError:
|
127
|
+
return f"Classfolder({self.name!r})"
|
File without changes
|