MDit 0.0.0.dev0__tar.gz → 0.0.0.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. mdit-0.0.0.dev1/PKG-INFO +24 -0
  2. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/pyproject.toml +17 -3
  3. mdit-0.0.0.dev1/src/MDit.egg-info/PKG-INFO +24 -0
  4. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/MDit.egg-info/SOURCES.txt +9 -1
  5. mdit-0.0.0.dev1/src/MDit.egg-info/requires.txt +20 -0
  6. mdit-0.0.0.dev1/src/mdit/__init__.py +133 -0
  7. mdit-0.0.0.dev1/src/mdit/container.py +195 -0
  8. mdit-0.0.0.dev1/src/mdit/data/__init__.py +3 -0
  9. mdit-0.0.0.dev1/src/mdit/data/file.py +75 -0
  10. mdit-0.0.0.dev1/src/mdit/data/schema.py +45 -0
  11. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/mdit/display.py +6 -12
  12. mdit-0.0.0.dev1/src/mdit/document.py +309 -0
  13. mdit-0.0.0.dev1/src/mdit/element.py +2790 -0
  14. mdit-0.0.0.dev1/src/mdit/generate.py +149 -0
  15. mdit-0.0.0.dev1/src/mdit/protocol.py +90 -0
  16. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/mdit/render.py +59 -8
  17. mdit-0.0.0.dev1/src/mdit/target.py +202 -0
  18. mdit-0.0.0.dev1/src/mdit/template.py +8 -0
  19. mdit-0.0.0.dev0/PKG-INFO +0 -11
  20. mdit-0.0.0.dev0/src/MDit.egg-info/PKG-INFO +0 -11
  21. mdit-0.0.0.dev0/src/MDit.egg-info/requires.txt +0 -7
  22. mdit-0.0.0.dev0/src/mdit/__init__.py +0 -6
  23. mdit-0.0.0.dev0/src/mdit/container.py +0 -71
  24. mdit-0.0.0.dev0/src/mdit/element.py +0 -558
  25. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/README.md +0 -0
  26. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/setup.cfg +0 -0
  27. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/MDit.egg-info/dependency_links.txt +0 -0
  28. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/MDit.egg-info/not-zip-safe +0 -0
  29. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/MDit.egg-info/top_level.txt +0 -0
  30. {mdit-0.0.0.dev0 → mdit-0.0.0.dev1}/src/mdit/parse.py +0 -0
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.1
2
+ Name: MDit
3
+ Version: 0.0.0.dev1
4
+ Requires-Python: >=3.10
5
+ Requires-Dist: sphinx<8
6
+ Requires-Dist: myst-parser<4,>3
7
+ Requires-Dist: pydata-sphinx-theme
8
+ Requires-Dist: sphinx-togglebutton
9
+ Requires-Dist: sphinx-design
10
+ Requires-Dist: markdown-it-py
11
+ Requires-Dist: mdit-py-plugins
12
+ Requires-Dist: linkify-it-py
13
+ Requires-Dist: readme-renderer
14
+ Requires-Dist: cmarkgfm
15
+ Requires-Dist: zundler
16
+ Requires-Dist: PkgData
17
+ Requires-Dist: PySerials
18
+ Requires-Dist: PyLinks
19
+ Requires-Dist: PyBadger
20
+ Requires-Dist: PyColorIt
21
+ Requires-Dist: IPython
22
+ Requires-Dist: PyProtocol
23
+ Requires-Dist: HTMP
24
+ Requires-Dist: ansi-sgr
@@ -17,15 +17,29 @@ namespaces = true
17
17
  # ----------------------------------------- Project Metadata -------------------------------------
18
18
  #
19
19
  [project]
20
- version = "0.0.0.dev0"
20
+ version = "0.0.0.dev1"
21
21
  name = "MDit"
22
22
  requires-python = ">=3.10"
23
23
  dependencies = [
24
- "IPython",
25
- "PyProtocol",
24
+ "sphinx < 8",
25
+ "myst-parser > 3, < 4",
26
+ "pydata-sphinx-theme",
27
+ "sphinx-togglebutton",
28
+ "sphinx-design",
26
29
  "markdown-it-py",
27
30
  "mdit-py-plugins",
28
31
  "linkify-it-py",
29
32
  "readme-renderer",
30
33
  "cmarkgfm",
34
+ "zundler",
35
+ "PkgData",
36
+ "PySerials",
37
+ "PyLinks",
38
+ "PyBadger",
39
+ "PyColorIt",
40
+ "IPython",
41
+ "PyProtocol",
42
+ "HTMP",
43
+ "ansi-sgr",
44
+
31
45
  ]
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.1
2
+ Name: MDit
3
+ Version: 0.0.0.dev1
4
+ Requires-Python: >=3.10
5
+ Requires-Dist: sphinx<8
6
+ Requires-Dist: myst-parser<4,>3
7
+ Requires-Dist: pydata-sphinx-theme
8
+ Requires-Dist: sphinx-togglebutton
9
+ Requires-Dist: sphinx-design
10
+ Requires-Dist: markdown-it-py
11
+ Requires-Dist: mdit-py-plugins
12
+ Requires-Dist: linkify-it-py
13
+ Requires-Dist: readme-renderer
14
+ Requires-Dist: cmarkgfm
15
+ Requires-Dist: zundler
16
+ Requires-Dist: PkgData
17
+ Requires-Dist: PySerials
18
+ Requires-Dist: PyLinks
19
+ Requires-Dist: PyBadger
20
+ Requires-Dist: PyColorIt
21
+ Requires-Dist: IPython
22
+ Requires-Dist: PyProtocol
23
+ Requires-Dist: HTMP
24
+ Requires-Dist: ansi-sgr
@@ -9,6 +9,14 @@ src/MDit.egg-info/top_level.txt
9
9
  src/mdit/__init__.py
10
10
  src/mdit/container.py
11
11
  src/mdit/display.py
12
+ src/mdit/document.py
12
13
  src/mdit/element.py
14
+ src/mdit/generate.py
13
15
  src/mdit/parse.py
14
- src/mdit/render.py
16
+ src/mdit/protocol.py
17
+ src/mdit/render.py
18
+ src/mdit/target.py
19
+ src/mdit/template.py
20
+ src/mdit/data/__init__.py
21
+ src/mdit/data/file.py
22
+ src/mdit/data/schema.py
@@ -0,0 +1,20 @@
1
+ sphinx<8
2
+ myst-parser<4,>3
3
+ pydata-sphinx-theme
4
+ sphinx-togglebutton
5
+ sphinx-design
6
+ markdown-it-py
7
+ mdit-py-plugins
8
+ linkify-it-py
9
+ readme-renderer
10
+ cmarkgfm
11
+ zundler
12
+ PkgData
13
+ PySerials
14
+ PyLinks
15
+ PyBadger
16
+ PyColorIt
17
+ IPython
18
+ PyProtocol
19
+ HTMP
20
+ ansi-sgr
@@ -0,0 +1,133 @@
1
+ """Generate and process Markdown content.
2
+
3
+ References
4
+ ----------
5
+ - [GitHub Flavored Markdown Spec](https://github.github.com/gfm/)
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING as _TYPE_CHECKING
11
+
12
+ from mdit.container import Container, MDContainer, BlockMDContainer, InlineMDContainer
13
+ from mdit.document import Document
14
+ from mdit.generate import DocumentGenerator
15
+ from mdit import render, target, element, display, parse, protocol, template
16
+ __version__ = "XXX"
17
+
18
+ if _TYPE_CHECKING:
19
+ from typing import Callable
20
+ from mdit.protocol import ContainerContentType, ContainerInputType, Stringable, TargetConfig, ANSITargetConfig
21
+
22
+
23
+ def generate(config: dict):
24
+ return DocumentGenerator().generate(config)
25
+
26
+
27
+ def document(
28
+ heading: element.Heading | ContainerInputType | None = None,
29
+ body: ContainerInputType = None,
30
+ section: Container | None = None,
31
+ footer: ContainerInputType = None,
32
+ frontmatter: dict | element.FrontMatter | None = None,
33
+ frontmatter_conditions: list[str] | None = None,
34
+ separate_sections: bool = False,
35
+ toctree_args: dict[str, str] | None = None,
36
+ toctree_dirhtml: bool = True,
37
+ target_config_md: dict[str, TargetConfig | dict] | None = None,
38
+ target_config_ansi: dict[str, ANSITargetConfig | dict] | None = None,
39
+ default_output_target: str = "sphinx",
40
+ deep_section_generator: Callable[[Document], str] | None = None,
41
+ ):
42
+ if heading and not isinstance(heading, element.Heading):
43
+ heading = element.heading(content=heading, level=1)
44
+ body = container(body, "\n\n")
45
+ if isinstance(section, Container):
46
+ pass
47
+ elif not section:
48
+ section = section_container()
49
+ elif isinstance(section, dict):
50
+ section = section_container(**section)
51
+ elif isinstance(section, (list, tuple)):
52
+ section = section_container(*section)
53
+ else:
54
+ section = section_container(section)
55
+ footer = container(footer, "\n\n")
56
+ if isinstance(frontmatter, dict):
57
+ frontmatter = element.frontmatter(frontmatter)
58
+ target_config = {}
59
+ for key, config in (target_config_md or {}).items():
60
+ config_obj = config if isinstance(config, protocol.TargetConfig) else target.custom(**config)
61
+ target_config[key] = config_obj
62
+ for key, config in (target_config_ansi or {}).items():
63
+ config_obj = config if isinstance(config, protocol.ANSITargetConfig) else target.ansi(**config)
64
+ if key in target_config:
65
+ raise ValueError(f"Target config key '{key}' already exists.")
66
+ target_config[key] = config_obj
67
+ return Document(
68
+ heading=heading,
69
+ body=body,
70
+ section=section,
71
+ footer=footer,
72
+ frontmatter=frontmatter,
73
+ frontmatter_conditions=frontmatter_conditions,
74
+ separate_sections=separate_sections,
75
+ toctree_args=toctree_args,
76
+ toctree_dirhtml=toctree_dirhtml,
77
+ target_config=target_config,
78
+ default_output_target=default_output_target,
79
+ deep_section_generator=deep_section_generator,
80
+ )
81
+
82
+
83
+ def container(
84
+ content,
85
+ content_seperator: str,
86
+ html_container: Stringable | None = None,
87
+ html_container_attrs: dict | None = None,
88
+ html_container_conditions: list[str] | None = None,
89
+ ) -> MDContainer:
90
+ if isinstance(content, MDContainer):
91
+ return content
92
+ cont = MDContainer(
93
+ content_separator=content_seperator,
94
+ html_container=html_container,
95
+ html_container_attrs=html_container_attrs,
96
+ html_container_conditions=html_container_conditions,
97
+ )
98
+ if not content:
99
+ return cont
100
+ if isinstance(content, dict):
101
+ cont.extend(**content)
102
+ elif isinstance(content, (list, tuple)):
103
+ cont.extend(*content)
104
+ else:
105
+ cont.append(content)
106
+ return cont
107
+
108
+
109
+ def block_container(
110
+ *unlabeled_contents: ContainerContentType,
111
+ **labeled_contents: ContainerContentType,
112
+ ) -> BlockMDContainer:
113
+ container_ = BlockMDContainer()
114
+ container_.extend(*unlabeled_contents, **labeled_contents)
115
+ return container_
116
+
117
+
118
+ def inline_container(
119
+ *unlabeled_contents: ContainerContentType,
120
+ **labeled_contents: ContainerContentType,
121
+ ) -> InlineMDContainer:
122
+ container_ = InlineMDContainer()
123
+ container_.extend(*unlabeled_contents, **labeled_contents)
124
+ return container_
125
+
126
+
127
+ def section_container(
128
+ *unlabeled_contents: ContainerContentType,
129
+ **labeled_contents: ContainerContentType,
130
+ ) -> Container:
131
+ container_ = Container()
132
+ container_.extend(*unlabeled_contents, **labeled_contents)
133
+ return container_
@@ -0,0 +1,195 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING as _TYPE_CHECKING, NamedTuple as _NamedTuple
4
+ import re as _re
5
+
6
+ import htmp as _htmp
7
+
8
+ from mdit.protocol import MDCode as _MDCode
9
+ from mdit import display as _display
10
+
11
+
12
+ if _TYPE_CHECKING:
13
+ from typing import Literal
14
+ from mdit.protocol import ContainerInputType, ContainerContentType, ContainerContentType, TargetConfigType, Stringable
15
+
16
+
17
+ class ContainerContent(_NamedTuple):
18
+ content: ContainerContentType
19
+ conditions: list[str]
20
+
21
+
22
+ class Container:
23
+
24
+ def __init__(self, data: dict[str | int, ContainerContent] | None = None):
25
+ self._data = data or {}
26
+ return
27
+
28
+ def append(
29
+ self,
30
+ content,
31
+ conditions: str | list[str] | None = None,
32
+ key: str | int | None = None
33
+ ) -> str | int:
34
+ if not key:
35
+ key = max((key for key in self._data.keys() if isinstance(key, int)), default=-1) + 1
36
+ if key in self._data:
37
+ raise ValueError("Key already exists in content.")
38
+ if not conditions:
39
+ conditions = []
40
+ elif isinstance(conditions, str):
41
+ conditions = [conditions]
42
+ else:
43
+ conditions = list(conditions)
44
+ self._data[key] = ContainerContent(content=content, conditions=conditions)
45
+ return key
46
+
47
+ def extend(self, *unlabeled_contents, **labeled_contents) -> list[str | int]:
48
+
49
+ def resolve_value(v):
50
+ if isinstance(v, (list, tuple)):
51
+ val = v[0]
52
+ cond = v[1] if len(v) > 1 else None
53
+ return val, cond
54
+ return v, None
55
+
56
+ added_keys = []
57
+ if unlabeled_contents:
58
+ first_available_key = max(
59
+ (key for key in self._data.keys() if isinstance(key, int)), default=-1
60
+ ) + 1
61
+ for idx, value in enumerate(unlabeled_contents):
62
+ content, conditions = resolve_value(value)
63
+ added_keys.append(self.append(content, conditions, first_available_key + idx))
64
+ if labeled_contents:
65
+ for key, value in labeled_contents.items():
66
+ content, conditions = resolve_value(value)
67
+ added_keys.append(self.append(content, conditions, key))
68
+ return added_keys
69
+
70
+ def elements(
71
+ self,
72
+ target: TargetConfigType | None = None,
73
+ filters: str | list[str] | None = None,
74
+ string: bool = False,
75
+ ) -> list:
76
+ elements = []
77
+ if isinstance(filters, str):
78
+ filters = [filters]
79
+ for content, conditions in self.values():
80
+ if not filters or not conditions or any(filter in conditions for filter in filters):
81
+ if not string:
82
+ elements.append(content)
83
+ elif isinstance(content, _MDCode):
84
+ elements.append(content.source(target=target, filters=filters))
85
+ else:
86
+ elements.append(str(content))
87
+ return elements
88
+
89
+ def get(self, key: str | int, default=None):
90
+ return self._data.get(key, default)
91
+
92
+ def keys(self):
93
+ return self._data.keys()
94
+
95
+ def values(self):
96
+ return self._data.values()
97
+
98
+ def items(self):
99
+ return self._data.items()
100
+
101
+ def __getitem__(self, item):
102
+ return self._data[item]
103
+
104
+ def __setitem__(self, key, value):
105
+ self._data[key] = value
106
+ return
107
+
108
+ def __contains__(self, item):
109
+ return item in self._data
110
+
111
+ def __bool__(self):
112
+ return bool(self._data)
113
+
114
+
115
+ class MDContainer(Container):
116
+
117
+ _IS_MD_CODE = True
118
+
119
+ def __init__(
120
+ self,
121
+ content: dict[str | int, ContainerContent] | None = None,
122
+ content_separator: str = "\n\n",
123
+ html_container: Stringable | None = None,
124
+ html_container_attrs: dict | None = None,
125
+ html_container_conditions: list[str] | None = None,
126
+ ):
127
+ super().__init__(content)
128
+ self.content_separator = content_separator
129
+ self.html_container = html_container
130
+ self.html_container_attrs = html_container_attrs or {}
131
+ self.html_container_conditions = html_container_conditions or []
132
+ return
133
+
134
+ def source(self, target: TargetConfigType | None = None, filters: str | list[str] | None = None) -> str:
135
+ elements = self.elements(target=target, filters=filters, string=True)
136
+ elements_str = self.content_separator.join(elements)
137
+ if self.html_container and self.html_container_attrs and (
138
+ not filters
139
+ or not self.html_container_conditions
140
+ or any(filter in self.html_container_conditions for filter in filters)
141
+ ):
142
+ container_func = getattr(_htmp.element, str(self.html_container))
143
+ return container_func(_htmp.elementor.markdown(elements_str), self.html_container_attrs).source(indent=-1)
144
+ return elements_str
145
+
146
+ def display(self, target: TargetConfigType | None = None, filters: str | list[str] | None = None) -> None:
147
+ """Display the element in an IPython notebook."""
148
+ _display.ipython(self.source(target=target, filters=filters))
149
+ return
150
+
151
+ @property
152
+ def code_fence_count(self) -> int:
153
+ pattern = _re.compile(r'^\s{0, 3}(`{3,}|~{3,}|:{3,})', _re.MULTILINE)
154
+ counts = []
155
+ for content, _ in self._data.values():
156
+ if isinstance(content, _MDCode):
157
+ counts.append(content.code_fence_count)
158
+ else:
159
+ matches = pattern.findall(str(content))
160
+ if matches:
161
+ counts.append(max(len(match) for match in matches))
162
+ return max(counts, default=0)
163
+
164
+
165
+ # def __str__(self):
166
+ # if not self._block:
167
+ # if any(not isinstance(elem, str) for elem in self._content.values()):
168
+ # raise ValueError("Inline elements must have string content.")
169
+ # elif self._leaf:
170
+ # if any(isinstance(elem, Element) and elem.is_block for elem in self._content.values()):
171
+ # raise ValueError("Leaf block elements cannot contain block content.")
172
+ # content = "".join(str(elem) for elem in self._content.values())
173
+ # md = self._md.replace("${{content}}", content)
174
+ # newlines_before, newlines_after = [
175
+ # newlines_count if isinstance(newlines_count, int) else (1 if self._block else 0)
176
+ # for newlines_count in (self.newlines_before, self.newlines_after)
177
+ # ]
178
+ # return f"{newlines_before * '\n'}{md}{newlines_after * '\n'}"
179
+
180
+ def __str__(self) -> str:
181
+ return self.source()
182
+
183
+
184
+ class BlockMDContainer(MDContainer):
185
+
186
+ def __init__(self, content: dict[str | int, ContainerContent] | None = None):
187
+ super().__init__(content, content_separator="\n\n")
188
+ return
189
+
190
+
191
+ class InlineMDContainer(MDContainer):
192
+
193
+ def __init__(self, content: dict[str | int, ContainerContent] | None = None):
194
+ super().__init__(content, content_separator="")
195
+ return
@@ -0,0 +1,3 @@
1
+ """Work with the package's data files and JSON schemas."""
2
+
3
+ from mdit.data import file, schema
@@ -0,0 +1,75 @@
1
+ """Get package data files."""
2
+
3
+ from pathlib import Path as _Path
4
+
5
+ import pkgdata as _pkgdata
6
+ import pyserials as _ps
7
+
8
+
9
+ path = _pkgdata.get_package_path_from_caller(top_level=True) / "data"
10
+
11
+
12
+ def template(group: str, name: str) -> str:
13
+ """Get the string content of a template."""
14
+ dir_path = path / "template" / group
15
+ for filepath in dir_path.iterdir():
16
+ if filepath.stem == name:
17
+ return filepath.read_text()
18
+
19
+
20
+ def schema(schema_id: str | None = None, relative_uri: bool = True) -> dict:
21
+ """Get all JSON schemas as a dictionary of schema IDs to schema objects.
22
+
23
+ Parameters
24
+ ----------
25
+ schema_id : str, optional
26
+ If provided, return only the schema with the given ID, otherwise all schemas.
27
+ The schema ID can be either an absolute or relative URI, i.e., with or without
28
+ the "https://docsman.repodynamics.com/schema/" prefix.
29
+ relative_uri : bool, default: True
30
+ Only applies when `schema_id` is not provided:
31
+ If True, the schema IDs (i.e., the keys of the returned dictionary)
32
+ will be relative URIs instead of absolute URIs,
33
+ i.e., without the "https://docsman.repodynamics.com/schema/" prefix.
34
+
35
+ Returns
36
+ -------
37
+ dict
38
+ If `schema_id` is provided, the schema object is returned,
39
+ otherwise a dictionary of JSON schemas with their IDs as keys.
40
+ The schema IDs are relative URIs if `relative_uri` is True.
41
+ """
42
+ dir_path = path / "schema"
43
+ if schema_id:
44
+ filepath = dir_path / schema_id.removeprefix("https://docsman.repodynamics.com/schema/")
45
+ filepath_full = filepath.with_suffix(".yaml")
46
+ return _ps.read.yaml_from_file(path=filepath_full)
47
+ schemas = {}
48
+ for filepath in dir_path.glob("**/*.yaml"):
49
+ schema = _ps.read.yaml_from_file(path=filepath)
50
+ schema_id = schema["$id"].removeprefix(
51
+ "https://docsman.repodynamics.com/schema/" if relative_uri else ""
52
+ )
53
+ schemas[schema_id] = schema
54
+ return schemas
55
+
56
+
57
+ def from_filepath(filepath: str | _Path) -> str | dict | list:
58
+ """Get a package data file from its relative path.
59
+
60
+ Parameters
61
+ ----------
62
+ filepath : str
63
+ Path of the data file relative to the package's `data` directory.
64
+
65
+ Returns
66
+ -------
67
+ file_content : str | dict | list
68
+ The content of the file.
69
+ If the file is a serialized data structure (e.g., JSON or YAML),
70
+ the content will be deserialized, otherwise a string is returned.
71
+ """
72
+ absolute_filepath = path / filepath
73
+ if absolute_filepath.suffix in (".json", ".yaml", ".yml", "toml"):
74
+ return _ps.read.from_file(path=absolute_filepath)
75
+ return absolute_filepath.read_text()
@@ -0,0 +1,45 @@
1
+ """Work with JSON schemas defined by the package."""
2
+
3
+ from typing import Callable as _Callable
4
+
5
+ import referencing as _referencing
6
+ from referencing import jsonschema as _ref_jsonschema
7
+ import jsonschemata as _jsonschemata
8
+ import pyserials as _ps
9
+
10
+ from mdit.data import file as _file
11
+
12
+
13
+ def make_registry(
14
+ dynamic: bool = False,
15
+ crawl: bool = True,
16
+ add_resources: list[dict | _referencing.Resource | tuple[str, dict | _referencing.Resource]] | None = None,
17
+ add_resources_default_spec: _referencing.Specification = _ref_jsonschema.DRAFT202012,
18
+ retrieval_func: _Callable[[str], str | _referencing.Resource] = None,
19
+ ) -> tuple[_referencing.Registry, dict[str, dict]]:
20
+ schemata = _file.schema(relative_uri=False)
21
+ resources = add_resources or []
22
+ for schema in schemata.values():
23
+ _jsonschemata.edit.required_last(schema)
24
+ resources.append(schema)
25
+ registry = _jsonschemata.registry.make(
26
+ dynamic=dynamic,
27
+ crawl=crawl,
28
+ add_resources=resources,
29
+ add_resources_default_spec=add_resources_default_spec,
30
+ retrieval_func=retrieval_func,
31
+ )
32
+ return registry, schemata
33
+
34
+
35
+ def validate(data: dict, schema_id: str):
36
+ _ps.validate.jsonschema(
37
+ data=data,
38
+ schema=_SCHEMATA[schema_id],
39
+ registry=_REGISTRY,
40
+ fill_defaults=True,
41
+ )
42
+ return
43
+
44
+
45
+ # _REGISTRY, _SCHEMATA = make_registry()
@@ -3,7 +3,6 @@
3
3
  import webbrowser as _webbrowser
4
4
  import tempfile as _tempfile
5
5
  import time as _time
6
- from pathlib import Path as _Path
7
6
 
8
7
  from IPython import display as _display
9
8
 
@@ -20,17 +19,15 @@ def browser(content: str) -> None:
20
19
  content : str
21
20
  HTML content to display.
22
21
  """
23
- with _tempfile.NamedTemporaryFile('w', delete=False, suffix='.html') as temp_file:
22
+ with _tempfile.NamedTemporaryFile('w', suffix='.html') as temp_file:
24
23
  temp_file.write(content)
25
24
  temp_file.flush()
26
- temp_filepath = temp_file.name
27
- _webbrowser.open(f'file://{temp_filepath}')
28
- _time.sleep(10)
29
- _Path(temp_filepath).unlink()
25
+ _webbrowser.open(f'file://{temp_file.name}')
26
+ _time.sleep(11)
30
27
  return
31
28
 
32
29
 
33
- def ipython(content: str, as_md: bool = False) -> None:
30
+ def ipython(content: str, as_md: bool = True) -> None:
34
31
  """Display HTML or Markdown content in an IPython notebook.
35
32
 
36
33
  This function uses the `IPython.display` module to render the content
@@ -44,9 +41,6 @@ def ipython(content: str, as_md: bool = False) -> None:
44
41
  If True, the function uses the `IPython.display.Markdown` renderer,
45
42
  otherwise (by default) it uses the `IPython.display.HTML` renderer
46
43
  """
47
- if ipython:
48
- renderer = _display.Markdown if as_md else _display.HTML
49
- _display.display(renderer(content))
50
- return
51
-
44
+ renderer = _display.Markdown if as_md else _display.HTML
45
+ _display.display(renderer(content))
52
46
  return