mkdocstrings-matlab 0.6.0__py3-none-any.whl → 0.8.0__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- mkdocstrings_handlers/matlab/collect.py +84 -32
- mkdocstrings_handlers/matlab/handler.py +31 -10
- mkdocstrings_handlers/matlab/models.py +60 -28
- mkdocstrings_handlers/matlab/templates/material/children.html.jinja +172 -0
- mkdocstrings_handlers/matlab/templates/material/docstring/namespaces.html.jinja +86 -0
- mkdocstrings_handlers/matlab/templates/material/docstring/properties.html.jinja +109 -0
- mkdocstrings_handlers/matlab/templates/material/folder.html.jinja +121 -0
- mkdocstrings_handlers/matlab/templates/material/namespace.html.jinja +121 -0
- mkdocstrings_handlers/matlab/templates/material/property.html.jinja +120 -0
- mkdocstrings_handlers/matlab/templates/material/style.css +26 -0
- mkdocstrings_handlers/matlab/templates/material/summary/namespaces.html.jinja +21 -0
- mkdocstrings_handlers/matlab/templates/material/summary/properties.html.jinja +21 -0
- mkdocstrings_handlers/matlab/templates/material/summary.html.jinja +26 -0
- {mkdocstrings_matlab-0.6.0.dist-info → mkdocstrings_matlab-0.8.0.dist-info}/METADATA +9 -9
- mkdocstrings_matlab-0.8.0.dist-info/RECORD +21 -0
- mkdocs_material_matlab/__init__.py +0 -4
- mkdocs_material_matlab/css/style.css +0 -7
- mkdocs_material_matlab/mkdocs_material_matlab.py +0 -20
- mkdocstrings_matlab-0.6.0.dist-info/RECORD +0 -15
- mkdocstrings_matlab-0.6.0.dist-info/entry_points.txt +0 -2
- {mkdocstrings_matlab-0.6.0.dist-info → mkdocstrings_matlab-0.8.0.dist-info}/WHEEL +0 -0
- {mkdocstrings_matlab-0.6.0.dist-info → mkdocstrings_matlab-0.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,7 @@
|
|
3
3
|
from collections import defaultdict, deque
|
4
4
|
from copy import copy, deepcopy
|
5
5
|
from pathlib import Path
|
6
|
-
from typing import Mapping, Sequence
|
6
|
+
from typing import Mapping, Sequence, Callable, TypeVar
|
7
7
|
|
8
8
|
from _griffe.collections import LinesCollection as GLC, ModulesCollection
|
9
9
|
from _griffe.docstrings.models import (
|
@@ -24,14 +24,16 @@ from mkdocstrings_handlers.matlab.models import (
|
|
24
24
|
Docstring,
|
25
25
|
DocstringSectionText,
|
26
26
|
Function,
|
27
|
+
Folder,
|
27
28
|
MatlabMixin,
|
28
|
-
Object,
|
29
29
|
Namespace,
|
30
|
-
|
30
|
+
PathMixin,
|
31
31
|
)
|
32
32
|
from mkdocstrings_handlers.matlab.treesitter import FileParser
|
33
33
|
|
34
34
|
|
35
|
+
PathType = TypeVar("PathType", bound=PathMixin)
|
36
|
+
|
35
37
|
__all__ = ["LinesCollection", "PathCollection"]
|
36
38
|
|
37
39
|
|
@@ -104,6 +106,7 @@ class PathCollection(ModulesCollection):
|
|
104
106
|
matlab_path (Sequence[str | Path]): A list of strings or Path objects representing the MATLAB paths.
|
105
107
|
recursive (bool, optional): If True, recursively adds all subdirectories of the given paths to the search path. Defaults to False.
|
106
108
|
config (Mapping, optional): Configuration settings for the PathCollection. Defaults to {}.
|
109
|
+
config_path (Path | None, optional): The path to the configuration file. Defaults to None.
|
107
110
|
|
108
111
|
Methods:
|
109
112
|
members() -> dict:
|
@@ -130,6 +133,7 @@ class PathCollection(ModulesCollection):
|
|
130
133
|
matlab_path: Sequence[str | Path],
|
131
134
|
recursive: bool = False,
|
132
135
|
config: Mapping = {},
|
136
|
+
config_path: Path | None = None,
|
133
137
|
) -> None:
|
134
138
|
"""
|
135
139
|
Initialize an instance of PathCollection.
|
@@ -148,6 +152,8 @@ class PathCollection(ModulesCollection):
|
|
148
152
|
self._mapping: dict[str, deque[Path]] = defaultdict(deque)
|
149
153
|
self._models: dict[Path, LazyModel] = {}
|
150
154
|
self._members: dict[Path, list[tuple[str, Path]]] = defaultdict(list)
|
155
|
+
self._folders: dict[str, LazyModel] = {}
|
156
|
+
self._config_path = config_path
|
151
157
|
|
152
158
|
self.config = config
|
153
159
|
self.lines_collection = LinesCollection()
|
@@ -188,6 +194,26 @@ class PathCollection(ModulesCollection):
|
|
188
194
|
model = self._models[self._mapping[identifier][0]].model()
|
189
195
|
if model is not None:
|
190
196
|
model = self.update_model(model, config)
|
197
|
+
|
198
|
+
elif self._config_path is not None and "/" in identifier:
|
199
|
+
absolute_path = (self._config_path / Path(identifier)).resolve()
|
200
|
+
if absolute_path.exists():
|
201
|
+
path = absolute_path.relative_to(self._config_path)
|
202
|
+
if path.suffix:
|
203
|
+
path, member = path.parent, path.stem
|
204
|
+
else:
|
205
|
+
member = None
|
206
|
+
lazymodel = self._folders.get(str(path), None)
|
207
|
+
|
208
|
+
if lazymodel is not None:
|
209
|
+
model = lazymodel.model()
|
210
|
+
if model is not None and member is not None:
|
211
|
+
model = model.members.get(member, None)
|
212
|
+
else:
|
213
|
+
model = None
|
214
|
+
else:
|
215
|
+
model = None
|
216
|
+
|
191
217
|
else:
|
192
218
|
model = None
|
193
219
|
name_parts = identifier.split(".")
|
@@ -511,13 +537,25 @@ class PathCollection(ModulesCollection):
|
|
511
537
|
else:
|
512
538
|
self._path.appendleft(path)
|
513
539
|
|
514
|
-
|
515
|
-
for member in members:
|
540
|
+
for member in PathGlobber(path, recursive=recursive):
|
516
541
|
model = LazyModel(member, self)
|
517
542
|
self._models[member] = model
|
518
543
|
self._mapping[model.name].append(member)
|
519
544
|
self._members[path].append((model.name, member))
|
520
545
|
|
546
|
+
if self._config_path is not None and member.parent.stem[0] not in [
|
547
|
+
"+",
|
548
|
+
"@",
|
549
|
+
]:
|
550
|
+
if member.parent.is_relative_to(self._config_path):
|
551
|
+
relative_path = member.parent.relative_to(self._config_path)
|
552
|
+
if member.parent not in self._folders:
|
553
|
+
self._folders[str(relative_path)] = LazyModel(
|
554
|
+
member.parent, self
|
555
|
+
)
|
556
|
+
else:
|
557
|
+
pass # TODO: Issue warning?
|
558
|
+
|
521
559
|
def rm_path(self, path: str | Path, recursive: bool = False):
|
522
560
|
"""
|
523
561
|
Removes a path from the search path and updates the namespace and database accordingly.
|
@@ -610,6 +648,10 @@ class LazyModel:
|
|
610
648
|
self._path_collection: PathCollection = path_collection
|
611
649
|
self._lines_collection: LinesCollection = path_collection.lines_collection
|
612
650
|
|
651
|
+
@property
|
652
|
+
def is_folder(self) -> bool:
|
653
|
+
return self._path.is_dir() and self._path.name[0] not in ["+", "@"]
|
654
|
+
|
613
655
|
@property
|
614
656
|
def is_class_folder(self) -> bool:
|
615
657
|
return self._path.is_dir() and self._path.name[0] == "@"
|
@@ -648,7 +690,7 @@ class LazyModel:
|
|
648
690
|
else:
|
649
691
|
return name
|
650
692
|
|
651
|
-
def model(self):
|
693
|
+
def model(self) -> MatlabMixin | None:
|
652
694
|
if not self._path.exists():
|
653
695
|
return None
|
654
696
|
|
@@ -657,19 +699,22 @@ class LazyModel:
|
|
657
699
|
self._model = self._collect_classfolder(self._path)
|
658
700
|
elif self.is_namespace:
|
659
701
|
self._model = self._collect_namespace(self._path)
|
702
|
+
elif self.is_folder:
|
703
|
+
self._model = self._collect_folder(self._path)
|
660
704
|
else:
|
661
705
|
self._model = self._collect_path(self._path)
|
662
706
|
if self._model is not None:
|
663
707
|
self._model.parent = self._collect_parent(self._path.parent)
|
664
708
|
return self._model
|
665
709
|
|
666
|
-
def _collect_parent(self, path: Path) ->
|
710
|
+
def _collect_parent(self, path: Path) -> _ParentGrabber | None:
|
667
711
|
if self.is_in_namespace:
|
668
|
-
|
669
|
-
|
670
|
-
|
712
|
+
grabber: Callable[[], MatlabMixin | None] = self._path_collection._models[
|
713
|
+
path
|
714
|
+
].model
|
715
|
+
parent = _ParentGrabber(grabber)
|
671
716
|
else:
|
672
|
-
parent =
|
717
|
+
parent = None
|
673
718
|
return parent
|
674
719
|
|
675
720
|
def _collect_path(self, path: Path) -> MatlabMixin:
|
@@ -678,6 +723,27 @@ class LazyModel:
|
|
678
723
|
self._lines_collection[path] = file.content.split("\n")
|
679
724
|
return model
|
680
725
|
|
726
|
+
def _collect_directory(self, path: Path, model: PathType) -> PathType:
|
727
|
+
for member in path.iterdir():
|
728
|
+
if member.is_dir() and member.name[0] in ["+", "@"]:
|
729
|
+
submodel = self._path_collection._models[member].model()
|
730
|
+
if submodel is not None:
|
731
|
+
model.members[submodel.name] = submodel
|
732
|
+
|
733
|
+
elif member.is_file() and member.suffix == ".m":
|
734
|
+
if member.name == "Contents.m":
|
735
|
+
contentsfile = self._collect_path(member)
|
736
|
+
model.docstring = contentsfile.docstring
|
737
|
+
else:
|
738
|
+
submodel = self._path_collection._models[member].model()
|
739
|
+
if submodel is not None:
|
740
|
+
model.members[submodel.name] = submodel
|
741
|
+
|
742
|
+
if model.docstring is None:
|
743
|
+
model.docstring = self._collect_readme_md(path, model)
|
744
|
+
|
745
|
+
return model
|
746
|
+
|
681
747
|
def _collect_classfolder(self, path: Path) -> Classfolder | None:
|
682
748
|
classfile = path / (path.name[1:] + ".m")
|
683
749
|
if not classfile.exists():
|
@@ -698,31 +764,17 @@ class LazyModel:
|
|
698
764
|
model.docstring = self._collect_readme_md(path, model)
|
699
765
|
return model
|
700
766
|
|
701
|
-
def _collect_namespace(self, path: Path) -> Namespace
|
767
|
+
def _collect_namespace(self, path: Path) -> Namespace:
|
702
768
|
name = self.name[1:].split(".")[-1]
|
703
769
|
model = Namespace(name, filepath=path, path_collection=self._path_collection)
|
770
|
+
return self._collect_directory(path, model)
|
704
771
|
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
model.members[submodel.name] = submodel
|
710
|
-
|
711
|
-
elif member.is_file() and member.suffix == ".m":
|
712
|
-
if member.name == "Contents.m":
|
713
|
-
contentsfile = self._collect_path(member)
|
714
|
-
model.docstring = contentsfile.docstring
|
715
|
-
else:
|
716
|
-
submodel = self._path_collection._models[member].model()
|
717
|
-
if submodel is not None:
|
718
|
-
model.members[submodel.name] = submodel
|
719
|
-
|
720
|
-
if model.docstring is None:
|
721
|
-
model.docstring = self._collect_readme_md(path, model)
|
722
|
-
|
723
|
-
return model
|
772
|
+
def _collect_folder(self, path: Path) -> Folder:
|
773
|
+
name = path.stem
|
774
|
+
model = Folder(name, filepath=path, path_collection=self._path_collection)
|
775
|
+
return self._collect_directory(path, model)
|
724
776
|
|
725
|
-
def _collect_readme_md(self, path, parent:
|
777
|
+
def _collect_readme_md(self, path, parent: PathMixin) -> Docstring | None:
|
726
778
|
if (path / "README.md").exists():
|
727
779
|
readme = path / "README.md"
|
728
780
|
elif (path / "readme.md").exists():
|
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
from pathlib import Path
|
4
4
|
from collections import ChainMap
|
5
|
+
from jinja2.loaders import FileSystemLoader
|
5
6
|
from markdown import Markdown
|
6
|
-
from
|
7
|
+
from mkdocs.exceptions import PluginError
|
7
8
|
from mkdocstrings.handlers.base import BaseHandler, CollectorItem, CollectionError
|
8
9
|
from mkdocstrings_handlers.python import rendering
|
9
10
|
from typing import Any, ClassVar, Mapping
|
@@ -152,7 +153,9 @@ class MatlabHandler(BaseHandler):
|
|
152
153
|
|
153
154
|
def __init__(
|
154
155
|
self,
|
155
|
-
|
156
|
+
handler: str,
|
157
|
+
theme: str,
|
158
|
+
custom_templates: str | None = None,
|
156
159
|
config_file_path: str | None = None,
|
157
160
|
paths: list[str] | None = None,
|
158
161
|
paths_recursive: bool = False,
|
@@ -163,7 +166,9 @@ class MatlabHandler(BaseHandler):
|
|
163
166
|
Initialize the handler with the given configuration.
|
164
167
|
|
165
168
|
Args:
|
166
|
-
|
169
|
+
handler: The name of the handler.
|
170
|
+
theme: The name of theme to use.
|
171
|
+
custom_templates: Directory containing custom templates.
|
167
172
|
config_file_path (str | None, optional): Path to the configuration file. Defaults to None.
|
168
173
|
paths (list[str] | None, optional): List of paths to include. Defaults to None.
|
169
174
|
paths_recursive (bool, optional): Whether to include paths recursively. Defaults to False.
|
@@ -173,21 +178,37 @@ class MatlabHandler(BaseHandler):
|
|
173
178
|
Returns:
|
174
179
|
None
|
175
180
|
"""
|
176
|
-
|
181
|
+
|
182
|
+
super().__init__(handler, theme, custom_templates=custom_templates)
|
183
|
+
|
184
|
+
theme_path = Path(__file__).resolve().parent / "templates" / theme
|
185
|
+
if theme_path.exists() and isinstance(self.env.loader, FileSystemLoader):
|
186
|
+
# Insert our templates directory at the beginning of the search path to overload the Python templates
|
187
|
+
self.env.loader.searchpath.insert(0, str(theme_path))
|
188
|
+
css_path = theme_path / "style.css"
|
189
|
+
if css_path.exists():
|
190
|
+
self.extra_css += "\n" + css_path.read_text(encoding="utf-8")
|
177
191
|
|
178
192
|
if paths is None or config_file_path is None:
|
193
|
+
config_path = None
|
179
194
|
full_paths = []
|
180
195
|
else:
|
181
196
|
config_path = Path(config_file_path).parent
|
182
197
|
full_paths = [(config_path / path).resolve() for path in paths]
|
183
198
|
|
199
|
+
if pathIds := [str(path) for path in full_paths if not path.is_dir()]:
|
200
|
+
raise PluginError(
|
201
|
+
"The following paths do not exist or are not directories: "
|
202
|
+
+ ", ".join(pathIds)
|
203
|
+
)
|
204
|
+
|
184
205
|
self.paths: PathCollection = PathCollection(
|
185
|
-
full_paths, recursive=paths_recursive
|
206
|
+
full_paths, recursive=paths_recursive, config_path=config_path
|
186
207
|
)
|
187
208
|
self.lines: LinesCollection = self.paths.lines_collection
|
188
209
|
self._locale: str = locale
|
189
210
|
|
190
|
-
def get_templates_dir(self,
|
211
|
+
def get_templates_dir(self, *args, **kwargs) -> Path:
|
191
212
|
# use the python handler templates
|
192
213
|
# (it assumes the python handler is installed)
|
193
214
|
return super().get_templates_dir("python")
|
@@ -253,9 +274,6 @@ class MatlabHandler(BaseHandler):
|
|
253
274
|
}
|
254
275
|
|
255
276
|
# Map docstring options
|
256
|
-
final_config["show_submodules"] = config.get(
|
257
|
-
"show_subnamespaces", False
|
258
|
-
)
|
259
277
|
final_config["show_docstring_attributes"] = config.get(
|
260
278
|
"show_docstring_properties", True
|
261
279
|
)
|
@@ -340,7 +358,10 @@ class MatlabHandler(BaseHandler):
|
|
340
358
|
raise CollectionError("Empty identifier")
|
341
359
|
|
342
360
|
final_config = ChainMap(config, self.default_config) # type: ignore[arg-type]
|
343
|
-
|
361
|
+
model = self.paths.resolve(identifier, config=final_config)
|
362
|
+
if model is None:
|
363
|
+
raise CollectionError(f"Identifier '{identifier}' not found")
|
364
|
+
return model
|
344
365
|
|
345
366
|
|
346
367
|
def get_handler(
|
@@ -99,7 +99,7 @@ class _ParentGrabber:
|
|
99
99
|
__call__(): Calls the grabber function and returns a MatlabObject.
|
100
100
|
"""
|
101
101
|
|
102
|
-
def __init__(self, grabber: "Callable[[],
|
102
|
+
def __init__(self, grabber: "Callable[[], MatlabMixin | None]") -> None:
|
103
103
|
"""
|
104
104
|
Initializes the _ParentGrabber with a grabber function.
|
105
105
|
|
@@ -109,7 +109,7 @@ class _ParentGrabber:
|
|
109
109
|
self._grabber = grabber
|
110
110
|
|
111
111
|
@property
|
112
|
-
def parent(self) -> "
|
112
|
+
def parent(self) -> "MatlabMixin | None":
|
113
113
|
"""
|
114
114
|
Calls the grabber function and returns a MatlabObject.
|
115
115
|
|
@@ -141,13 +141,24 @@ class MatlabObject(Object):
|
|
141
141
|
path_collection (PathCollection | None): The collection of paths related to the object.
|
142
142
|
**kwargs: Arbitrary keyword arguments.
|
143
143
|
"""
|
144
|
-
|
145
144
|
self.path_collection: "PathCollection | None" = path_collection
|
146
145
|
lines_collection = (
|
147
146
|
path_collection.lines_collection if path_collection is not None else None
|
148
147
|
)
|
149
148
|
super().__init__(*args, lines_collection=lines_collection, **kwargs)
|
150
149
|
|
150
|
+
@property
|
151
|
+
def namespaces(self) -> dict[str, "Namespace"]:
|
152
|
+
return {}
|
153
|
+
|
154
|
+
@property
|
155
|
+
def is_namespace(self) -> bool:
|
156
|
+
return False
|
157
|
+
|
158
|
+
@property
|
159
|
+
def is_folder(self) -> bool:
|
160
|
+
return False
|
161
|
+
|
151
162
|
@property
|
152
163
|
def canonical_path(self) -> str:
|
153
164
|
"""
|
@@ -156,7 +167,7 @@ class MatlabObject(Object):
|
|
156
167
|
Returns:
|
157
168
|
str: The canonical path of the object.
|
158
169
|
"""
|
159
|
-
if
|
170
|
+
if self.parent is None:
|
160
171
|
return self.name
|
161
172
|
|
162
173
|
if isinstance(self.parent, MatlabObject):
|
@@ -165,7 +176,7 @@ class MatlabObject(Object):
|
|
165
176
|
parent = getattr(self.parent, "model", self.parent)
|
166
177
|
|
167
178
|
if isinstance(parent, Classfolder) and self.name == parent.name:
|
168
|
-
if
|
179
|
+
if parent.parent is None:
|
169
180
|
return self.name
|
170
181
|
else:
|
171
182
|
return f"{parent.parent.canonical_path}.{self.name}"
|
@@ -173,23 +184,6 @@ class MatlabObject(Object):
|
|
173
184
|
return f"{parent.canonical_path}.{self.name}" if parent else self.name
|
174
185
|
|
175
186
|
|
176
|
-
class _Root(MatlabObject):
|
177
|
-
"""
|
178
|
-
A class representing the root object in a MATLAB structure.
|
179
|
-
All the objects that have the root object as parent are at the top level,
|
180
|
-
and can be called directly.
|
181
|
-
"""
|
182
|
-
|
183
|
-
def __init__(self) -> None:
|
184
|
-
super().__init__("ROOT", parent=None)
|
185
|
-
|
186
|
-
def __repr__(self) -> str:
|
187
|
-
return "MATLABROOT"
|
188
|
-
|
189
|
-
|
190
|
-
ROOT = _Root()
|
191
|
-
|
192
|
-
|
193
187
|
class PathMixin(Object):
|
194
188
|
"""
|
195
189
|
A mixin class that provides a filepath attribute and related functionality.
|
@@ -200,7 +194,6 @@ class PathMixin(Object):
|
|
200
194
|
|
201
195
|
def __init__(self, *args: Any, filepath: Path | None = None, **kwargs: Any) -> None:
|
202
196
|
self._filepath: Path | None = filepath
|
203
|
-
|
204
197
|
super().__init__(*args, **kwargs)
|
205
198
|
|
206
199
|
@property
|
@@ -215,22 +208,22 @@ class MatlabMixin(Object):
|
|
215
208
|
def __init__(
|
216
209
|
self,
|
217
210
|
*args: Any,
|
218
|
-
parent: "Class | Classfolder | Namespace |
|
211
|
+
parent: "Class | Classfolder | Namespace | None" = None,
|
219
212
|
docstring: Docstring | None = None,
|
220
213
|
**kwargs: Any,
|
221
214
|
):
|
222
|
-
self._parent: "Class | Classfolder | Namespace |
|
215
|
+
self._parent: "Class | Classfolder | Namespace | _ParentGrabber | None" = parent
|
223
216
|
self._docstring: Docstring | None = docstring
|
224
217
|
super().__init__(*args, **kwargs)
|
225
218
|
|
226
219
|
@property
|
227
|
-
def parent(self) -> Object:
|
220
|
+
def parent(self) -> Object | None:
|
228
221
|
if isinstance(self._parent, MatlabMixin):
|
229
222
|
return self._parent
|
230
223
|
elif isinstance(self._parent, _ParentGrabber):
|
231
224
|
return self._parent.parent
|
232
225
|
else:
|
233
|
-
return
|
226
|
+
return None
|
234
227
|
|
235
228
|
@parent.setter
|
236
229
|
def parent(self, value):
|
@@ -444,6 +437,8 @@ class Property(MatlabMixin, Attribute, MatlabObject):
|
|
444
437
|
self.SetAccess: AccessEnum = SetAccess
|
445
438
|
self.getter: Function | None = None
|
446
439
|
|
440
|
+
self.extra["mkdocstrings"] = {"template": "property.html.jinja"}
|
441
|
+
|
447
442
|
@property
|
448
443
|
def Private(self) -> bool:
|
449
444
|
private = self.Access != AccessEnum.public
|
@@ -559,19 +554,52 @@ class Function(MatlabMixin, PathMixin, GriffeFunction, MatlabObject):
|
|
559
554
|
pass
|
560
555
|
|
561
556
|
|
557
|
+
class Folder(MatlabMixin, PathMixin, Module, MatlabObject):
|
558
|
+
"""
|
559
|
+
A class representing a Folder in a MATLAB project.
|
560
|
+
|
561
|
+
Inherits from:
|
562
|
+
- MatlabMixin: A mixin class providing MATLAB-specific functionality.
|
563
|
+
- PathMixin: A mixin class providing path-related functionality.
|
564
|
+
- Module: A class representing a module.
|
565
|
+
- MatlabObject: A base class for MATLAB objects.
|
566
|
+
"""
|
567
|
+
|
568
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
569
|
+
super().__init__(*args, **kwargs)
|
570
|
+
self.extra["mkdocstrings"] = {"template": "folder.html.jinja"}
|
571
|
+
|
572
|
+
def __repr__(self) -> str:
|
573
|
+
return f"Folder({self.filepath!r})"
|
574
|
+
|
575
|
+
@property
|
576
|
+
def namespaces(self) -> dict[str, "Namespace"]:
|
577
|
+
return {
|
578
|
+
name: member
|
579
|
+
for name, member in self.members.items()
|
580
|
+
if isinstance(member, Namespace)
|
581
|
+
}
|
582
|
+
|
583
|
+
@property
|
584
|
+
def is_folder(self) -> bool:
|
585
|
+
return True
|
586
|
+
|
587
|
+
|
562
588
|
class Namespace(MatlabMixin, PathMixin, Module, MatlabObject):
|
563
589
|
"""
|
564
590
|
A class representing a namespace in a MATLAB project.
|
565
591
|
|
566
592
|
Inherits from:
|
593
|
+
- MatlabMixin: A mixin class providing MATLAB-specific functionality.
|
567
594
|
- PathMixin: A mixin class providing path-related functionality.
|
568
|
-
- MatlabObject: A base class for MATLAB objects.
|
569
595
|
- Module: A class representing a module.
|
596
|
+
- MatlabObject: A base class for MATLAB objects.
|
570
597
|
"""
|
571
598
|
|
572
599
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
573
600
|
super().__init__(*args, **kwargs)
|
574
601
|
self._access: AccessEnum = AccessEnum.public
|
602
|
+
self.extra["mkdocstrings"] = {"template": "namespace.html.jinja"}
|
575
603
|
|
576
604
|
def __repr__(self) -> str:
|
577
605
|
return f"Namespace({self.path!r})"
|
@@ -583,3 +611,7 @@ class Namespace(MatlabMixin, PathMixin, Module, MatlabObject):
|
|
583
611
|
if self.filepath
|
584
612
|
else False
|
585
613
|
)
|
614
|
+
|
615
|
+
@property
|
616
|
+
def is_namespace(self) -> bool:
|
617
|
+
return True
|
@@ -0,0 +1,172 @@
|
|
1
|
+
{#- Template for members (children) of an object.
|
2
|
+
|
3
|
+
This template iterates on members of a given object and renders them.
|
4
|
+
It can group members by category (attributes, classes, functions, modules) or render them in a flat list.
|
5
|
+
|
6
|
+
Context:
|
7
|
+
obj (griffe.Object): The object to render.
|
8
|
+
config (dict): The configuration options.
|
9
|
+
root_members (bool): Whether the object is the root object.
|
10
|
+
heading_level (int): The HTML heading level to use.
|
11
|
+
-#}
|
12
|
+
|
13
|
+
{% if obj.all_members %}
|
14
|
+
{% block logs scoped %}
|
15
|
+
{#- Logging block.
|
16
|
+
|
17
|
+
This block can be used to log debug messages, deprecation messages, warnings, etc.
|
18
|
+
-#}
|
19
|
+
{{ log.debug("Rendering children of " + obj.path) }}
|
20
|
+
{% endblock logs %}
|
21
|
+
|
22
|
+
<div class="doc doc-children">
|
23
|
+
|
24
|
+
{% if root_members %}
|
25
|
+
{% set members_list = config.members %}
|
26
|
+
{% else %}
|
27
|
+
{% set members_list = none %}
|
28
|
+
{% endif %}
|
29
|
+
|
30
|
+
{% if config.group_by_category %}
|
31
|
+
|
32
|
+
{% with %}
|
33
|
+
|
34
|
+
{% if config.show_category_heading %}
|
35
|
+
{% set extra_level = 1 %}
|
36
|
+
{% else %}
|
37
|
+
{% set extra_level = 0 %}
|
38
|
+
{% endif %}
|
39
|
+
|
40
|
+
{% with attributes = obj.attributes|filter_objects(
|
41
|
+
filters=config.filters,
|
42
|
+
members_list=members_list,
|
43
|
+
inherited_members=config.inherited_members,
|
44
|
+
keep_no_docstrings=config.show_if_no_docstring,
|
45
|
+
) %}
|
46
|
+
{% if attributes %}
|
47
|
+
{% if config.show_category_heading %}
|
48
|
+
{% filter heading(heading_level, id=html_id ~ "-properties") %}Properties{% endfilter %}
|
49
|
+
{% endif %}
|
50
|
+
{% with heading_level = heading_level + extra_level %}
|
51
|
+
{% for attribute in attributes|order_members(config.members_order, members_list) %}
|
52
|
+
{% if members_list is not none or (not attribute.is_imported or attribute.is_public) %}
|
53
|
+
{% include attribute|get_template with context %}
|
54
|
+
{% endif %}
|
55
|
+
{% endfor %}
|
56
|
+
{% endwith %}
|
57
|
+
{% endif %}
|
58
|
+
{% endwith %}
|
59
|
+
|
60
|
+
{% with classes = obj.classes|filter_objects(
|
61
|
+
filters=config.filters,
|
62
|
+
members_list=members_list,
|
63
|
+
inherited_members=config.inherited_members,
|
64
|
+
keep_no_docstrings=config.show_if_no_docstring,
|
65
|
+
) %}
|
66
|
+
{% if classes %}
|
67
|
+
{% if config.show_category_heading %}
|
68
|
+
{% filter heading(heading_level, id=html_id ~ "-classes") %}Classes{% endfilter %}
|
69
|
+
{% endif %}
|
70
|
+
{% with heading_level = heading_level + extra_level %}
|
71
|
+
{% for class in classes|order_members(config.members_order, members_list) %}
|
72
|
+
{% if members_list is not none or (not class.is_imported or class.is_public) %}
|
73
|
+
{% include class|get_template with context %}
|
74
|
+
{% endif %}
|
75
|
+
{% endfor %}
|
76
|
+
{% endwith %}
|
77
|
+
{% endif %}
|
78
|
+
{% endwith %}
|
79
|
+
|
80
|
+
{% with functions = obj.functions|filter_objects(
|
81
|
+
filters=config.filters,
|
82
|
+
members_list=members_list,
|
83
|
+
inherited_members=config.inherited_members,
|
84
|
+
keep_no_docstrings=config.show_if_no_docstring,
|
85
|
+
) %}
|
86
|
+
{% if functions %}
|
87
|
+
{% if config.show_category_heading %}
|
88
|
+
{% filter heading(heading_level, id=html_id ~ "-functions") %}Functions{% endfilter %}
|
89
|
+
{% endif %}
|
90
|
+
{% with heading_level = heading_level + extra_level %}
|
91
|
+
{% for function in functions|order_members(config.members_order, members_list) %}
|
92
|
+
{% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
|
93
|
+
{% if members_list is not none or (not function.is_imported or function.is_public) %}
|
94
|
+
{% include function|get_template with context %}
|
95
|
+
{% endif %}
|
96
|
+
{% endif %}
|
97
|
+
{% endfor %}
|
98
|
+
{% endwith %}
|
99
|
+
{% endif %}
|
100
|
+
{% endwith %}
|
101
|
+
|
102
|
+
{% if config.show_submodules or obj.is_folder %}
|
103
|
+
{% with modules = obj.modules|filter_objects(
|
104
|
+
filters=config.filters,
|
105
|
+
members_list=members_list,
|
106
|
+
inherited_members=config.inherited_members,
|
107
|
+
keep_no_docstrings=config.show_if_no_docstring,
|
108
|
+
) %}
|
109
|
+
{% if modules %}
|
110
|
+
{% if config.show_category_heading %}
|
111
|
+
{% filter heading(heading_level, id=html_id ~ "-namespaces") %}Modules{% endfilter %}
|
112
|
+
{% endif %}
|
113
|
+
{% with heading_level = heading_level + extra_level %}
|
114
|
+
{% for module in modules|order_members(config.members_order.alphabetical, members_list) %}
|
115
|
+
{% if members_list is not none or (not module.is_alias or module.is_public) %}
|
116
|
+
{% include module|get_template with context %}
|
117
|
+
{% endif %}
|
118
|
+
{% endfor %}
|
119
|
+
{% endwith %}
|
120
|
+
{% endif %}
|
121
|
+
{% endwith %}
|
122
|
+
{% endif %}
|
123
|
+
|
124
|
+
{% endwith %}
|
125
|
+
|
126
|
+
{% else %}
|
127
|
+
|
128
|
+
{% for child in obj.all_members
|
129
|
+
|filter_objects(
|
130
|
+
filters=config.filters,
|
131
|
+
members_list=members_list,
|
132
|
+
inherited_members=config.inherited_members,
|
133
|
+
keep_no_docstrings=config.show_if_no_docstring,
|
134
|
+
)
|
135
|
+
|order_members(config.members_order, members_list)
|
136
|
+
%}
|
137
|
+
|
138
|
+
{% if not (obj.is_class and child.name == "__init__" and config.merge_init_into_class) %}
|
139
|
+
|
140
|
+
{% if members_list is not none or child.is_public %}
|
141
|
+
{% if child.is_attribute %}
|
142
|
+
{% with attribute = child %}
|
143
|
+
{% include attribute|get_template with context %}
|
144
|
+
{% endwith %}
|
145
|
+
|
146
|
+
{% elif child.is_class %}
|
147
|
+
{% with class = child %}
|
148
|
+
{% include class|get_template with context %}
|
149
|
+
{% endwith %}
|
150
|
+
|
151
|
+
{% elif child.is_function %}
|
152
|
+
{% with function = child %}
|
153
|
+
{% include function|get_template with context %}
|
154
|
+
{% endwith %}
|
155
|
+
|
156
|
+
{% elif (child.is_namespace and config.show_submodules) or obj.is_folder %}
|
157
|
+
{% with module = child %}
|
158
|
+
{% include module|get_template with context %}
|
159
|
+
{% endwith %}
|
160
|
+
|
161
|
+
{% endif %}
|
162
|
+
{% endif %}
|
163
|
+
|
164
|
+
{% endif %}
|
165
|
+
|
166
|
+
{% endfor %}
|
167
|
+
|
168
|
+
{% endif %}
|
169
|
+
|
170
|
+
</div>
|
171
|
+
|
172
|
+
{% endif %}
|