mkdocstrings-matlab 0.6.0__py3-none-any.whl → 0.8.0__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/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 %}
|