mkdocstrings-matlab 0.1.0__py2.py3-none-any.whl
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.
- mkdocstrings_handlers/matlab/__init__.py +5 -0
- mkdocstrings_handlers/matlab/handler.py +383 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+case/builtin.m +8 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+case/class.m +12 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+case/func.m +5 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+case/method.m +6 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+case/namespace.m +28 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/argument.m +58 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m +44 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/func.m +14 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/namespace.m +14 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/property.m +41 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/script.m +15 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+utils/dedent.m +34 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+utils/get_namespace_path.m +26 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/+utils/parse_doc.m +21 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/exception.m +7 -0
- mkdocstrings_handlers/matlab/matlab/+docstring/resolve.m +94 -0
- mkdocstrings_handlers/matlab/matlab/matlab_startup.m +21 -0
- mkdocstrings_handlers/matlab/models.py +127 -0
- mkdocstrings_handlers/matlab/py.typed +0 -0
- mkdocstrings_matlab-0.1.0.dist-info/METADATA +17 -0
- mkdocstrings_matlab-0.1.0.dist-info/RECORD +25 -0
- mkdocstrings_matlab-0.1.0.dist-info/WHEEL +5 -0
- mkdocstrings_matlab-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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
|
@@ -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,25 @@
|
|
1
|
+
mkdocstrings_handlers/matlab/__init__.py,sha256=laA2bEP5rxdIWBLmfLiKKu7ChZ_HzCe-VeRvxmUTqww,128
|
2
|
+
mkdocstrings_handlers/matlab/handler.py,sha256=GuFjY7Jrv9QnHZELWghzAXEBf6Z67xvYr7aLPxMGvAg,14294
|
3
|
+
mkdocstrings_handlers/matlab/models.py,sha256=-k5V6Usho9D8KAynvEnMz7B6Fyrf1TrkJ1P8NhRdyzQ,3997
|
4
|
+
mkdocstrings_handlers/matlab/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
mkdocstrings_handlers/matlab/matlab/matlab_startup.m,sha256=rGXiR8fI2GW7yWmHxgzE5Un66n5ws3ogYnMvS2oWO8U,464
|
6
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/exception.m,sha256=sj2ycqMpknn_OG5A5X_b5e4WcAoR2oPoqNnDEHJsi7c,222
|
7
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/resolve.m,sha256=ZHHz6ujW1godzDcGtC3p0SsVARv-roseUh85e2eTBrE,2736
|
8
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+case/builtin.m,sha256=IioiokiaLnsi_6VXraaGdU2AgjCNApYhgVEmp2Lg1eA,245
|
9
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+case/class.m,sha256=MXeRhQibRQSOYwbrmc9tHLS723baStzSf9yXfzSEri0,275
|
10
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+case/func.m,sha256=QneDYSICtXqdPNq8sYNieirXUisuDKRM9rxPx-0osDU,137
|
11
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+case/method.m,sha256=Bw8Mb96OP7-AnbGnvRMySOIbYSTtEC1BGBnqHMEIhsM,165
|
12
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+case/namespace.m,sha256=ZpYrgZHLIdGvgg3F6210gDTska9YyASn63ZVYkBq41A,667
|
13
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/argument.m,sha256=l6UIQ4uolz533vo5DDWxl0R5PRkbb6hpRxpMPu5SNm8,1583
|
14
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/class.m,sha256=KurAMy-D_-47CYCdrqvzlSDXIl_dB2gwIQPLzjai35s,1542
|
15
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/func.m,sha256=urjYQauSRZ9bXg4co4gurOmiKzj5Sc4IS8FRKU8eEHM,408
|
16
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/namespace.m,sha256=kMzfAoWIpMXH76rrkyUqauJSRIaylsfnu0Cds4pYnJc,481
|
17
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/property.m,sha256=Ro5jciF60k8YRjJ_GWSm0kJNVZPfh4kyyLvYOwhrL2o,1379
|
18
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+metadata/script.m,sha256=pmuazWBqlugNEEojfQFkAg1ioErizoiEZ9RcFXecCP4,329
|
19
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+utils/dedent.m,sha256=r02mWQkRP9uuoEl-f-02h1-ja17a_29LTeyJvK-kazI,669
|
20
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+utils/get_namespace_path.m,sha256=4NlQ7-RjqIFZAn6P-9JzCrm2FvfGRKiM2M_leINj9i4,835
|
21
|
+
mkdocstrings_handlers/matlab/matlab/+docstring/+utils/parse_doc.m,sha256=z1voyYnASblb2i98n4dySOmBIbCa3n9moQKtbR5WE-k,442
|
22
|
+
mkdocstrings_matlab-0.1.0.dist-info/METADATA,sha256=R5KTt_IHagwweU_hC78Od6DXPiTfNOkE6S0IiDqqNeU,457
|
23
|
+
mkdocstrings_matlab-0.1.0.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
|
24
|
+
mkdocstrings_matlab-0.1.0.dist-info/licenses/LICENSE,sha256=14xA0OIYNpfmdeuq8-Yyqg7-3IJ4qhu3BJhknent-cY,1069
|
25
|
+
mkdocstrings_matlab-0.1.0.dist-info/RECORD,,
|
@@ -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.
|