mdforge 0.2.2__tar.gz → 0.2.3__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 (45) hide show
  1. {mdforge-0.2.2 → mdforge-0.2.3}/PKG-INFO +14 -14
  2. {mdforge-0.2.2 → mdforge-0.2.3}/README.md +1 -1
  3. mdforge-0.2.3/pyproject.toml +107 -0
  4. mdforge-0.2.3/src/mdforge/__init__.py +105 -0
  5. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/_norm.py +13 -18
  6. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/_utils.py +3 -5
  7. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/container.py +8 -24
  8. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/document.py +3 -1
  9. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/element.py +22 -25
  10. mdforge-0.2.3/src/mdforge/elements/__init__.py +71 -0
  11. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/_image.py +1 -1
  12. mdforge-0.2.3/src/mdforge/elements/block/__init__.py +60 -0
  13. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/basic.py +8 -12
  14. mdforge-0.2.3/src/mdforge/elements/block/lists/__init__.py +33 -0
  15. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/lists/definition.py +5 -11
  16. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/lists/item.py +10 -11
  17. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/section.py +6 -8
  18. mdforge-0.2.3/src/mdforge/elements/block/table/__init__.py +22 -0
  19. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_context.py +2 -5
  20. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_flavors/flavors.py +7 -12
  21. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_flavors/frame/__init__.py +1 -2
  22. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_flavors/frame/context.py +52 -82
  23. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_flavors/frame/variant.py +2 -4
  24. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_flavors/frame/variants.py +1 -1
  25. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_params.py +33 -47
  26. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_variant.py +6 -13
  27. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_vcell.py +16 -14
  28. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/cell.py +6 -12
  29. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/table.py +10 -19
  30. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/text.py +1 -1
  31. mdforge-0.2.3/src/mdforge/elements/inline/__init__.py +39 -0
  32. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/inline/basic.py +2 -3
  33. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/inline/text.py +14 -17
  34. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/exceptions.py +2 -2
  35. mdforge-0.2.3/src/mdforge/py.typed +0 -0
  36. mdforge-0.2.2/mdforge/__init__.py +0 -15
  37. mdforge-0.2.2/mdforge/elements/__init__.py +0 -11
  38. mdforge-0.2.2/mdforge/elements/block/__init__.py +0 -14
  39. mdforge-0.2.2/mdforge/elements/block/lists/__init__.py +0 -11
  40. mdforge-0.2.2/mdforge/elements/block/table/__init__.py +0 -11
  41. mdforge-0.2.2/mdforge/elements/inline/__init__.py +0 -11
  42. mdforge-0.2.2/pyproject.toml +0 -71
  43. {mdforge-0.2.2 → mdforge-0.2.3}/LICENSE +0 -0
  44. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/elements/block/table/_flavors/list/__init__.py +0 -0
  45. {mdforge-0.2.2 → mdforge-0.2.3/src}/mdforge/types.py +0 -0
@@ -1,23 +1,24 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: mdforge
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: Pythonic multi-flavor Markdown generator
5
5
  Author: mm21
6
- Author-email: mm21.dev@gmail.com
7
- Requires-Python: >=3.12,<4.0
8
- Classifier: Programming Language :: Python :: Implementation :: CPython
9
- Classifier: Operating System :: OS Independent
10
- Classifier: Typing :: Typed
11
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
6
+ Author-email: mm21 <mm21.dev@gmail.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
12
9
  Classifier: Development Status :: 3 - Alpha
13
10
  Classifier: Natural Language :: English
14
- Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
15
12
  Classifier: Programming Language :: Python :: 3
16
13
  Classifier: Programming Language :: Python :: 3.12
17
14
  Classifier: Programming Language :: Python :: 3.13
18
- Requires-Dist: pyrollup (>=0.1.0,<0.2.0)
19
- Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
20
- Project-URL: Homepage, https://github.com/mm21/mdforge
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: Python :: Implementation :: CPython
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: pyyaml>=6.0.2,<7
20
+ Requires-Python: >=3.12, <4.0
21
+ Project-URL: homepage, https://github.com/mm21/mdforge
21
22
  Description-Content-Type: text/markdown
22
23
 
23
24
  # MDForge
@@ -378,7 +379,7 @@ doc += Table(
378
379
  ],
379
380
  header=[
380
381
  [Cell("Column 1", rspan=2), Cell("Columns 2 & 3", cspan=2)],
381
- ["Column 2", "Column 3"],
382
+ [Cell("Column 2"), Cell("Column 3")],
382
383
  ],
383
384
  block=True,
384
385
  )
@@ -616,4 +617,3 @@ doc += Strikethrough("This text is struck through")
616
617
  extensions = doc.get_pandoc_extensions()
617
618
  assert extensions == ["header_attributes", "strikeout"]
618
619
  ```
619
-
@@ -356,7 +356,7 @@ doc += Table(
356
356
  ],
357
357
  header=[
358
358
  [Cell("Column 1", rspan=2), Cell("Columns 2 & 3", cspan=2)],
359
- ["Column 2", "Column 3"],
359
+ [Cell("Column 2"), Cell("Column 3")],
360
360
  ],
361
361
  block=True,
362
362
  )
@@ -0,0 +1,107 @@
1
+ # managed (in part) by pyprojkit: https://github.com/mm21/pyprojkit
2
+
3
+ [project]
4
+ authors = [{name = "mm21", email = "mm21.dev@gmail.com"}]
5
+ classifiers = [
6
+ "Development Status :: 3 - Alpha",
7
+ "Natural Language :: English",
8
+ "Operating System :: OS Independent",
9
+ "Programming Language :: Python :: 3", # pyprojkit-managed
10
+ "Programming Language :: Python :: 3.12", # pyprojkit-managed
11
+ "Programming Language :: Python :: 3.13", # pyprojkit-managed
12
+ "Programming Language :: Python :: 3.14", # pyprojkit-managed
13
+ "Programming Language :: Python :: Implementation :: CPython",
14
+ "Topic :: Software Development :: Libraries :: Python Modules",
15
+ "Typing :: Typed" # pyprojkit-managed
16
+ ]
17
+ dependencies = [
18
+ "pyyaml>=6.0.2,<7"
19
+ ]
20
+ description = "Pythonic multi-flavor Markdown generator"
21
+ license = "MIT"
22
+ license-files = ["LICENSE"]
23
+ name = "mdforge"
24
+ readme = "README.md"
25
+ requires-python = ">=3.12,<4.0" # pyprojkit-managed
26
+ version = "0.2.3"
27
+
28
+ [project.urls]
29
+ homepage = "https://github.com/mm21/mdforge"
30
+
31
+ [dependency-groups]
32
+ dev = [
33
+ "pyprojkit[all]>=0.8.1,<0.9.0",
34
+ "pytest-powerpack>=0.1.5,<0.2",
35
+ "types-pyyaml>=6.0.12,<7"
36
+ ]
37
+
38
+ [build-system]
39
+ build-backend = "uv_build"
40
+ requires = ["uv_build>=0.11.6,<0.12.0"]
41
+
42
+ [tool.autoflake]
43
+ in_place = true # pyprojkit-managed
44
+ recursive = true # pyprojkit-managed
45
+ remove-all-unused-imports = true # pyprojkit-managed
46
+ remove-unused-variables = true # pyprojkit-managed
47
+
48
+ [tool.black]
49
+ quiet = true # pyprojkit-managed
50
+ target-version = [
51
+ "py312",
52
+ "py313",
53
+ "py314"
54
+ ] # pyprojkit-managed
55
+
56
+ [tool.coverage.report]
57
+ exclude_lines = [
58
+ "if TYPE_CHECKING:",
59
+ "\\.\\.\\.$"
60
+ ] # pyprojkit-managed
61
+
62
+ [tool.coverage.run]
63
+ data_file = "__cache__/.coverage" # pyprojkit-managed
64
+
65
+ [tool.docfmt]
66
+ force-reflow = true # pyprojkit-managed
67
+ in-place = true # pyprojkit-managed
68
+ recursive = true # pyprojkit-managed
69
+ summary-on-own-line = true # pyprojkit-managed
70
+
71
+ [tool.doit]
72
+ dep_file = "__cache__/.doit.db" # pyprojkit-managed
73
+ verbosity = 2 # pyprojkit-managed
74
+
75
+ [tool.isort]
76
+ profile = "black" # pyprojkit-managed
77
+ quiet = true # pyprojkit-managed
78
+
79
+ [tool.mypy]
80
+ check_untyped_defs = true # pyprojkit-managed
81
+ python_version = "3.12" # pyprojkit-managed
82
+
83
+ [[tool.mypy.overrides]]
84
+ ignore_missing_imports = true
85
+ module = ["pytest_powerpack", "pytest_powerpack.*"]
86
+
87
+ [tool.nox]
88
+ default_venv_backend = "uv" # pyprojkit-managed
89
+ envdir = "__cache__/nox" # pyprojkit-managed
90
+
91
+ [tool.pyright]
92
+ pythonVersion = "3.12" # pyprojkit-managed
93
+
94
+ [tool.pytest.ini_options]
95
+ addopts = "--import-mode=importlib -s -v -rA" # pyprojkit-managed
96
+ cache_dir = "__cache__/pytest" # pyprojkit-managed
97
+ powerpack_underline = true
98
+ testpaths = ["test"] # pyprojkit-managed
99
+
100
+ [tool.tomlsort]
101
+ sort_first = [
102
+ "project",
103
+ "dependency-groups",
104
+ "build-system"
105
+ ] # pyprojkit-managed
106
+ sort_table_keys = true # pyprojkit-managed
107
+ spaces_before_inline_comment = 2 # pyprojkit-managed
@@ -0,0 +1,105 @@
1
+ """
2
+ MDForge: Forge Markdown files in a Python way.
3
+ """
4
+
5
+ __submodules__ = [
6
+ "types",
7
+ "document",
8
+ "element",
9
+ "container",
10
+ "elements",
11
+ "exceptions",
12
+ ]
13
+
14
+ # isort: off
15
+ # <AUTOGEN_INIT>
16
+ from .types import (
17
+ FlavorType,
18
+ AlignType,
19
+ )
20
+ from .document import (
21
+ Document,
22
+ )
23
+ from .element import (
24
+ BaseElement,
25
+ BaseInlineElement,
26
+ BaseBlockElement,
27
+ Attributes,
28
+ )
29
+ from .container import (
30
+ InlineContainer,
31
+ BlockContainer,
32
+ )
33
+ from .elements import (
34
+ Section,
35
+ Heading,
36
+ BlockImage,
37
+ Paragraph,
38
+ BlockText,
39
+ ListItemType,
40
+ ListItem,
41
+ BulletList,
42
+ NumberedList,
43
+ BaseItemList,
44
+ DefinitionItem,
45
+ DefinitionList,
46
+ Table,
47
+ Cell,
48
+ CellType,
49
+ RowType,
50
+ Text,
51
+ Emph,
52
+ Strong,
53
+ Underline,
54
+ Strikethrough,
55
+ Link,
56
+ Ref,
57
+ Newline,
58
+ Span,
59
+ InlineImage,
60
+ )
61
+ from .exceptions import (
62
+ ValidationError,
63
+ RenderError,
64
+ )
65
+
66
+ __all__ = [
67
+ "FlavorType",
68
+ "AlignType",
69
+ "Document",
70
+ "BaseElement",
71
+ "BaseInlineElement",
72
+ "BaseBlockElement",
73
+ "Attributes",
74
+ "InlineContainer",
75
+ "BlockContainer",
76
+ "Section",
77
+ "Heading",
78
+ "BlockImage",
79
+ "Paragraph",
80
+ "BlockText",
81
+ "ListItemType",
82
+ "ListItem",
83
+ "BulletList",
84
+ "NumberedList",
85
+ "BaseItemList",
86
+ "DefinitionItem",
87
+ "DefinitionList",
88
+ "Table",
89
+ "Cell",
90
+ "CellType",
91
+ "RowType",
92
+ "Text",
93
+ "Emph",
94
+ "Strong",
95
+ "Underline",
96
+ "Strikethrough",
97
+ "Link",
98
+ "Ref",
99
+ "Newline",
100
+ "Span",
101
+ "InlineImage",
102
+ "ValidationError",
103
+ "RenderError",
104
+ ]
105
+ # </AUTOGEN_INIT>
@@ -5,7 +5,7 @@ Utilities to normalize objects.
5
5
  """
6
6
 
7
7
  from dataclasses import dataclass
8
- from typing import Any, Callable, Iterable, TypeVar
8
+ from typing import Any, Callable, Iterable
9
9
 
10
10
  __all__ = [
11
11
  "CoerceSpec",
@@ -14,10 +14,6 @@ __all__ = [
14
14
  ]
15
15
 
16
16
 
17
- ExpectT = TypeVar("ExpectT")
18
- CoerceT = TypeVar("CoerceT", bound=ExpectT)
19
-
20
-
21
17
  @dataclass
22
18
  class CoerceSpec[CoerceT]:
23
19
  """
@@ -26,8 +22,9 @@ class CoerceSpec[CoerceT]:
26
22
 
27
23
  to_type: Callable[[Any], CoerceT]
28
24
  """
29
- Type to which to coerce, or a callable returning that type. Must take a
30
- single argument of one of the type(s) given in `from_types`.
25
+ Type to which to coerce, or a callable returning that type.
26
+
27
+ Must take a single argument of one of the type(s) given in `from_types`.
31
28
  """
32
29
 
33
30
  from_types: type[Any] | tuple[Any, ...]
@@ -36,17 +33,17 @@ class CoerceSpec[CoerceT]:
36
33
  """
37
34
 
38
35
 
39
- def norm_obj[
40
- ExpectT, CoerceT
41
- ](
36
+ def norm_obj[ExpectT](
42
37
  obj: Any,
43
- expect_type: type[ExpectT],
44
- *coerce_specs: CoerceSpec[CoerceT],
38
+ expect_type: type[ExpectT] | tuple[type[ExpectT], ...],
39
+ *coerce_specs: CoerceSpec[ExpectT],
45
40
  ) -> ExpectT:
46
41
  """
47
42
  Normalize object to the expected type, coercing if applicable.
48
43
  """
49
44
 
45
+ note: str | None
46
+
50
47
  if isinstance(obj, expect_type):
51
48
  # already have expected type
52
49
  return obj
@@ -74,12 +71,10 @@ def norm_obj[
74
71
  raise ValueError(_err_str(obj, expect_type, note))
75
72
 
76
73
 
77
- def norm_list[
78
- ExpectT, CoerceT
79
- ](
74
+ def norm_list[ExpectT](
80
75
  objs: Any | Iterable[Any],
81
- expect_type: type[ExpectT],
82
- *coerce_specs: CoerceSpec[CoerceT],
76
+ expect_type: type[ExpectT] | tuple[type[ExpectT], ...],
77
+ *coerce_specs: CoerceSpec[ExpectT],
83
78
  ) -> list[ExpectT]:
84
79
  """
85
80
  Normalize object(s) to a list of the expected type, coercing if applicable.
@@ -101,7 +96,7 @@ def norm_list[
101
96
 
102
97
 
103
98
  def _err_str(
104
- obj: Any, expect_type: type[ExpectT], note: str | None = None
99
+ obj: Any, expect_type: type[Any] | tuple[type[Any], ...], note: str | None = None
105
100
  ) -> str:
106
101
  note_norm = f" {note}" if note else ""
107
102
  return f"Object {obj} of type {type(obj)} is not of expected type {expect_type}{note_norm}"
@@ -18,12 +18,10 @@ def coerce_text(obj: str) -> BaseElement:
18
18
  return BlockText(obj) if "\n" in obj else Text(obj)
19
19
 
20
20
 
21
- def coerce_inline_text(
22
- obj: str, allow_multiline: bool = False
23
- ) -> BaseInlineElement:
21
+ def coerce_inline_text(obj: str, allow_multiline: bool = False) -> BaseInlineElement:
24
22
  """
25
- Wrap text with inline element, validating based on whether newlines
26
- (non-consecutive only) are allowed.
23
+ Wrap text with inline element, validating based on whether newlines (non-consecutive
24
+ only) are allowed.
27
25
  """
28
26
  from .container import InlineContainer
29
27
  from .elements.inline.text import Newline, Text
@@ -30,13 +30,9 @@ class InlineContainerMixin(BaseElement):
30
30
  __elements: list[BaseInlineElement]
31
31
  __auto_space: bool
32
32
 
33
- def __init__(
34
- self, *elements: BaseInlineElement | str, auto_space: bool = False
35
- ):
33
+ def __init__(self, *elements: BaseInlineElement | str, auto_space: bool = False):
36
34
  def coerce(obj: str) -> BaseInlineElement:
37
- return coerce_inline_text(
38
- obj, allow_multiline=self._allow_multiline
39
- )
35
+ return coerce_inline_text(obj, allow_multiline=self._allow_multiline)
40
36
 
41
37
  self.__elements = norm_list(
42
38
  elements, BaseInlineElement, CoerceSpec(coerce, str)
@@ -52,21 +48,15 @@ class InlineContainerMixin(BaseElement):
52
48
 
53
49
  def _render_elements(self, flavor: FlavorType) -> str:
54
50
  sep = " " if self.__auto_space else ""
55
- return sep.join(
56
- element._render_inline(flavor) for element in self.__elements
57
- )
51
+ return sep.join(element._render_inline(flavor) for element in self.__elements)
58
52
 
59
53
  def _get_pandoc_extensions(self) -> set[str]:
60
- return (
61
- _aggregate_extensions(self.__elements)
62
- | super()._get_pandoc_extensions()
63
- )
54
+ return _aggregate_extensions(self.__elements) | super()._get_pandoc_extensions()
64
55
 
65
56
 
66
57
  class InlineContainer(InlineContainerMixin, BaseInlineElement):
67
58
  """
68
- Container for inline elements; wraps multiple inline elements in a single
69
- one.
59
+ Container for inline elements; wraps multiple inline elements in a single one.
70
60
  """
71
61
 
72
62
  def _render_inline(self, flavor: FlavorType) -> str:
@@ -95,17 +85,11 @@ class BaseBlockContainer(BaseBlockElement):
95
85
 
96
86
  def _render_block(self, flavor: FlavorType) -> Generator[str, None, None]:
97
87
  yield "\n\n".join(
98
- [
99
- "\n".join(element._render_block(flavor))
100
- for element in self.__elements
101
- ]
88
+ ["\n".join(element._render_block(flavor)) for element in self.__elements]
102
89
  )
103
90
 
104
91
  def _get_pandoc_extensions(self) -> set[str]:
105
- return (
106
- _aggregate_extensions(self.__elements)
107
- | super()._get_pandoc_extensions()
108
- )
92
+ return _aggregate_extensions(self.__elements) | super()._get_pandoc_extensions()
109
93
 
110
94
  def _add_elements(self, elements: list[BaseBlockElement]):
111
95
  for element in elements:
@@ -207,7 +191,7 @@ class BaseLevelBlockContainer(BaseBlockContainer):
207
191
  container._level = self.__level + self._level_inc
208
192
 
209
193
 
210
- def _aggregate_extensions(elements: list[BaseElement]) -> set[str]:
194
+ def _aggregate_extensions(elements: Iterable[BaseElement]) -> set[str]:
211
195
  """
212
196
  Aggregate extensions from elements.
213
197
  """
@@ -21,7 +21,9 @@ ROOT_LEVEL: int = 1
21
21
 
22
22
  class Document(BaseLevelBlockContainer):
23
23
  """
24
- Encapsulates a Markdown document. Add elements using the `+=` operator.
24
+ Encapsulates a Markdown document.
25
+
26
+ Add elements using the `+=` operator.
25
27
  """
26
28
 
27
29
  _level_inc: int = 0
@@ -25,15 +25,15 @@ __all__ = [
25
25
 
26
26
  class BaseElement(ABC):
27
27
  """
28
- Base renderable markdown element, which may be a container of other
29
- elements.
28
+ Base renderable markdown element, which may be a container of other elements.
30
29
  """
31
30
 
32
31
  __container: BaseLevelBlockContainer | None = None
33
32
  """
34
- Container to which this element belongs. Must be added to a container in
35
- order to be rendered in a document, but otherwise can still be rendered
36
- standalone.
33
+ Container to which this element belongs.
34
+
35
+ Must be added to a container in order to be rendered in a document, but otherwise
36
+ can still be rendered standalone.
37
37
  """
38
38
 
39
39
  def render(self, *, flavor: FlavorType) -> str:
@@ -52,9 +52,8 @@ class BaseElement(ABC):
52
52
 
53
53
  def get_pandoc_extensions(self) -> list[str]:
54
54
  """
55
- Get a list of extensions required to convert the resulting
56
- markdown document in pandoc, assuming pandoc flavor is used for
57
- rendering.
55
+ Get a list of extensions required to convert the resulting markdown document in
56
+ pandoc, assuming pandoc flavor is used for rendering.
58
57
  """
59
58
  return sorted(self._get_pandoc_extensions())
60
59
 
@@ -71,20 +70,16 @@ class BaseElement(ABC):
71
70
  """
72
71
  return set()
73
72
 
74
- def _render_element_norm(
75
- self, flavor: FlavorType
76
- ) -> Generator[str, None, None]:
73
+ def _render_element_norm(self, flavor: FlavorType) -> Generator[str, None, None]:
77
74
  """
78
- Render this element, splitting any newlines embedded in content and
79
- stripping whitespace.
75
+ Render this element, splitting any newlines embedded in content and stripping
76
+ whitespace.
80
77
  """
81
78
  yield from "\n".join(self._render_element(flavor)).strip().split("\n")
82
79
 
83
80
  @property
84
81
  def _container(self) -> BaseLevelBlockContainer:
85
- assert (
86
- self.__container
87
- ), f"Element has not been placed in a container: {self}"
82
+ assert self.__container, f"Element has not been placed in a container: {self}"
88
83
  return self.__container
89
84
 
90
85
  @_container.setter
@@ -105,9 +100,7 @@ class BaseInlineElement(BaseElement):
105
100
  """
106
101
  ...
107
102
 
108
- def _render_element(
109
- self, flavor: BaseElement
110
- ) -> Generator[str, None, None]:
103
+ def _render_element(self, flavor: FlavorType) -> Generator[str, None, None]:
111
104
  yield self._render_inline(flavor)
112
105
 
113
106
 
@@ -130,8 +123,9 @@ class BaseBlockElement(BaseElement):
130
123
  @dataclass(kw_only=True)
131
124
  class Attributes:
132
125
  """
133
- HTML attributes which can be associated with some elements. Only applicable
134
- to pandoc flavor.
126
+ HTML attributes which can be associated with some elements.
127
+
128
+ Only applicable to pandoc flavor.
135
129
  """
136
130
 
137
131
  html_id: str | None = None
@@ -189,8 +183,9 @@ class Attributes:
189
183
 
190
184
  class AttributesMixin:
191
185
  """
192
- Mixin to facilitate adding HTML attributes. Only supported for pandoc
193
- flavor.
186
+ Mixin to facilitate adding HTML attributes.
187
+
188
+ Only supported for pandoc flavor.
194
189
  """
195
190
 
196
191
  __attributes: Attributes | None = None
@@ -223,16 +218,18 @@ class AttributesMixin:
223
218
  ) -> str:
224
219
  """
225
220
  Get string representing attributes, optionally prefixed with a space.
221
+
226
222
  For pandoc flavor only.
227
223
  """
228
224
 
225
+ attributes = self.__attributes
226
+
229
227
  # return if not applicable or no attributes set
230
- if flavor != "pandoc" or not self._has_attrs:
228
+ if flavor != "pandoc" or not attributes:
231
229
  return ""
232
230
 
233
231
  parts: list[str] = []
234
232
 
235
- attributes = self.__attributes
236
233
  if attributes.html_id:
237
234
  parts.append(f"#{attributes.html_id}")
238
235
  if css_classes := attributes._css_classes_norm:
@@ -0,0 +1,71 @@
1
+ """
2
+ Primitive Markdown elements which can be inserted into a document or section.
3
+ """
4
+
5
+ __submodules__ = [
6
+ "block",
7
+ "inline",
8
+ ]
9
+
10
+ # isort: off
11
+ # <AUTOGEN_INIT>
12
+ from .block import (
13
+ Section,
14
+ Heading,
15
+ BlockImage,
16
+ Paragraph,
17
+ BlockText,
18
+ ListItemType,
19
+ ListItem,
20
+ BulletList,
21
+ NumberedList,
22
+ BaseItemList,
23
+ DefinitionItem,
24
+ DefinitionList,
25
+ Table,
26
+ Cell,
27
+ CellType,
28
+ RowType,
29
+ )
30
+ from .inline import (
31
+ Text,
32
+ Emph,
33
+ Strong,
34
+ Underline,
35
+ Strikethrough,
36
+ Link,
37
+ Ref,
38
+ Newline,
39
+ Span,
40
+ InlineImage,
41
+ )
42
+
43
+ __all__ = [
44
+ "Section",
45
+ "Heading",
46
+ "BlockImage",
47
+ "Paragraph",
48
+ "BlockText",
49
+ "ListItemType",
50
+ "ListItem",
51
+ "BulletList",
52
+ "NumberedList",
53
+ "BaseItemList",
54
+ "DefinitionItem",
55
+ "DefinitionList",
56
+ "Table",
57
+ "Cell",
58
+ "CellType",
59
+ "RowType",
60
+ "Text",
61
+ "Emph",
62
+ "Strong",
63
+ "Underline",
64
+ "Strikethrough",
65
+ "Link",
66
+ "Ref",
67
+ "Newline",
68
+ "Span",
69
+ "InlineImage",
70
+ ]
71
+ # </AUTOGEN_INIT>
@@ -31,7 +31,7 @@ class ImageMixin(AttributesMixin, ABC):
31
31
  self._set_attrs(attributes)
32
32
 
33
33
  @abstractmethod
34
- def _render_alt_text(self, _: FlavorType) -> str:
34
+ def _render_alt_text(self, flavor: FlavorType) -> str:
35
35
  """
36
36
  Implemented by concrete class to get alt text.
37
37
  """