mdforge 0.2.2__tar.gz → 0.3.0__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 (52) hide show
  1. mdforge-0.2.2/README.md → mdforge-0.3.0/PKG-INFO +70 -22
  2. mdforge-0.2.2/PKG-INFO → mdforge-0.3.0/README.md +47 -45
  3. mdforge-0.3.0/pyproject.toml +109 -0
  4. mdforge-0.3.0/pyproject.toml.orig +107 -0
  5. mdforge-0.3.0/src/mdforge/__init__.py +111 -0
  6. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/_norm.py +13 -18
  7. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/_utils.py +39 -8
  8. mdforge-0.3.0/src/mdforge/container.py +231 -0
  9. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/document.py +10 -12
  10. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/element.py +126 -49
  11. mdforge-0.3.0/src/mdforge/elements/__init__.py +75 -0
  12. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/_image.py +5 -6
  13. mdforge-0.3.0/src/mdforge/elements/block/__init__.py +67 -0
  14. mdforge-0.3.0/src/mdforge/elements/block/basic.py +74 -0
  15. mdforge-0.3.0/src/mdforge/elements/block/container.py +68 -0
  16. mdforge-0.3.0/src/mdforge/elements/block/lists/__init__.py +33 -0
  17. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/lists/definition.py +24 -17
  18. mdforge-0.3.0/src/mdforge/elements/block/lists/item.py +211 -0
  19. mdforge-0.3.0/src/mdforge/elements/block/section.py +122 -0
  20. mdforge-0.3.0/src/mdforge/elements/block/table/__init__.py +22 -0
  21. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_context.py +9 -8
  22. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/flavors.py +12 -15
  23. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/__init__.py +1 -2
  24. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/context.py +55 -83
  25. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/variant.py +2 -4
  26. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/variants.py +1 -1
  27. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_params.py +33 -47
  28. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_variant.py +6 -13
  29. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_vcell.py +16 -14
  30. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/cell.py +15 -19
  31. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/table.py +21 -24
  32. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/text.py +4 -5
  33. mdforge-0.3.0/src/mdforge/elements/inline/__init__.py +39 -0
  34. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/inline/basic.py +9 -11
  35. mdforge-0.3.0/src/mdforge/elements/inline/text.py +198 -0
  36. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/exceptions.py +10 -2
  37. mdforge-0.3.0/src/mdforge/py.typed +0 -0
  38. mdforge-0.2.2/mdforge/__init__.py +0 -15
  39. mdforge-0.2.2/mdforge/container.py +0 -217
  40. mdforge-0.2.2/mdforge/elements/__init__.py +0 -11
  41. mdforge-0.2.2/mdforge/elements/block/__init__.py +0 -14
  42. mdforge-0.2.2/mdforge/elements/block/basic.py +0 -109
  43. mdforge-0.2.2/mdforge/elements/block/lists/__init__.py +0 -11
  44. mdforge-0.2.2/mdforge/elements/block/lists/item.py +0 -209
  45. mdforge-0.2.2/mdforge/elements/block/section.py +0 -49
  46. mdforge-0.2.2/mdforge/elements/block/table/__init__.py +0 -11
  47. mdforge-0.2.2/mdforge/elements/inline/__init__.py +0 -11
  48. mdforge-0.2.2/mdforge/elements/inline/text.py +0 -152
  49. mdforge-0.2.2/pyproject.toml +0 -71
  50. {mdforge-0.2.2 → mdforge-0.3.0}/LICENSE +0 -0
  51. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/list/__init__.py +0 -0
  52. {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/types.py +0 -0
@@ -1,3 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: mdforge
3
+ Version: 0.3.0
4
+ Summary: Pythonic multi-flavor Markdown generator
5
+ Author: mm21
6
+ Author-email: mm21 <mm21.dev@gmail.com>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Natural Language :: English
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
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
22
+ Description-Content-Type: text/markdown
23
+
1
24
  # MDForge
2
25
  Pythonic multi-flavor Markdown generator
3
26
 
@@ -41,17 +64,17 @@ pip install mdforge
41
64
  Create your first Markdown document:
42
65
 
43
66
  ```python
44
- from mdforge import Document, Heading, Paragraph, Strong
67
+ from mdforge import Document, Paragraph, Section, Strong
45
68
  from pathlib import Path
46
69
 
47
70
  # create a document
48
71
  doc = Document()
49
72
 
50
73
  # add elements
51
- doc += [
52
- Heading("My first MDForge document"),
53
- Paragraph("Hello, ", Strong("world"), "!"),
54
- ]
74
+ doc += Section(
75
+ "My first MDForge document",
76
+ elements=Paragraph("Hello, ", Strong("world"), "!"),
77
+ )
55
78
 
56
79
  # render pandoc-flavored Markdown document to a file
57
80
  doc.render_file("doc.md", flavor="pandoc")
@@ -141,11 +164,33 @@ Elaboration on point 3.
141
164
 
142
165
  Note the following observations:
143
166
 
144
- - Sections can be nested in other sections, with optional headings
145
- - Heading levels for sections are automatically set by their placement in the hierarchy
167
+ - Headings are created from section titles; content belonging to a heading is placed in its section
168
+ - Sections can be nested in other sections, with optional titles
169
+ - Heading levels for sections are automatically set by their placement in the hierarchy; see [Heading levels](#heading-levels)
146
170
  - Strings added to a document or section via `+=` are treated as raw text
147
171
  - A comment is placed at the end of each list; this disambiguates the end of one list and the start of the next, in case there are no other elements in between
148
172
 
173
+ ### Heading levels
174
+
175
+ By default (`level=None`), the level of a section is relative to the render root: the element on which `render()` is called. The render root is level 1 and each nested section is one level deeper.
176
+
177
+ As a result, a section rendered by itself is a self-contained tree starting at level 1, even if it's also placed in a document.
178
+
179
+ To generate a fragment to be placed in a larger document, pass an explicit `level`. Explicit levels are invariant of placement, and nested sections are relative to it:
180
+
181
+ ```python
182
+ from mdforge import Section
183
+
184
+ fragment = Section("Fragment", level=3, elements=Section("Subsection"))
185
+
186
+ assert fragment.render(flavor="pandoc") == "### Fragment\n\n#### Subsection"
187
+ ```
188
+
189
+ When an element with an explicit level is rendered as part of a larger tree, its level is checked against its placement:
190
+
191
+ - A level not nested in the containing level, e.g. `level=1` in a level-1 section, raises `RenderError`
192
+ - A level which skips levels, e.g. `level=3` in a level-1 section, issues `RenderWarning`
193
+
149
194
  ## Pythonic Markdown elements
150
195
 
151
196
  MDForge provides a set of Markdown elements that can be composed to create rich documents. Not all common elements are implemented yet, e.g. code blocks. Nonetheless, you can insert raw text (which may be pre-formatted as Markdown) using `+=`.
@@ -356,7 +401,7 @@ doc += Table(
356
401
  ],
357
402
  header=[
358
403
  [Cell("Column 1", rspan=2), Cell("Columns 2 & 3", cspan=2)],
359
- ["Column 2", "Column 3"],
404
+ [Cell("Column 2"), Cell("Column 3")],
360
405
  ],
361
406
  block=True,
362
407
  )
@@ -534,32 +579,33 @@ assert element.render(flavor="pandoc") == "This is a **test element**"
534
579
 
535
580
  ### HTML attributes
536
581
 
537
- For pandoc flavor, HTML attributes can be added to various elements:
582
+ For pandoc flavor, HTML attributes can be added to various elements, including section headings:
538
583
 
539
584
  ```python
540
- from mdforge import Attributes, Document, Heading, Ref, Span
585
+ from mdforge import Attributes, Document, Ref, Section, Span
541
586
 
542
587
  doc = Document()
543
588
 
544
- # heading with ID, classes, and custom attributes
545
- my_heading = Heading(
546
- "Heading with attributes",
589
+ # section with heading ID, classes, and custom attributes
590
+ my_section = Section(
591
+ "Section with attributes",
547
592
  attributes=Attributes(
548
- html_id="my-heading",
593
+ html_id="my-section",
549
594
  css_classes=["class1", "class2"],
550
595
  attrs={"style": "color: blue;"},
551
596
  ),
552
597
  )
553
- doc += my_heading
598
+ doc += my_section
554
599
 
555
600
  # span with attributes
556
- doc += Span(
601
+ my_section += Span(
557
602
  "Text with attributes",
558
603
  attributes=Attributes(html_id="my-span", css_classes="class1"),
559
604
  )
560
605
 
561
- # reference to heading by id
562
- doc += Ref(my_heading, "See previous heading")
606
+ # references to section, by object and by id
607
+ my_section += Ref(my_section, "See this section")
608
+ my_section += Ref("my-section")
563
609
 
564
610
  doc.render_file("doc.md", flavor="pandoc")
565
611
  ```
@@ -567,11 +613,13 @@ doc.render_file("doc.md", flavor="pandoc")
567
613
  This is rendered as:
568
614
 
569
615
  ```markdown
570
- # Heading with attributes {#my-heading .class1 .class2 style="color: blue;"}
616
+ # Section with attributes {#my-section .class1 .class2 style="color: blue;"}
571
617
 
572
618
  [Text with attributes]{#my-span .class1}
573
619
 
574
- [See previous heading](#my-heading)
620
+ [See this section](#my-section)
621
+
622
+ [Section with attributes](#my-section)
575
623
 
576
624
  ```
577
625
 
@@ -580,12 +628,12 @@ This is rendered as:
580
628
  As MDForge is designed with pandoc compatibility in mind, it automatically tracks required pandoc extensions:
581
629
 
582
630
  ```python
583
- from mdforge import Attributes, Document, Heading, Strikethrough
631
+ from mdforge import Attributes, Document, Section, Strikethrough
584
632
 
585
633
  doc = Document()
586
634
 
587
635
  # requires "header_attributes"
588
- doc += Heading("Heading 1", attributes=Attributes(html_id="heading-1"))
636
+ doc += Section("Section 1", attributes=Attributes(html_id="section-1"))
589
637
 
590
638
  # requires "strikeout"
591
639
  doc += Strikethrough("This text is struck through")
@@ -1,25 +1,3 @@
1
- Metadata-Version: 2.3
2
- Name: mdforge
3
- Version: 0.2.2
4
- Summary: Pythonic multi-flavor Markdown generator
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
12
- Classifier: Development Status :: 3 - Alpha
13
- Classifier: Natural Language :: English
14
- Classifier: License :: OSI Approved :: MIT License
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.12
17
- 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
21
- Description-Content-Type: text/markdown
22
-
23
1
  # MDForge
24
2
  Pythonic multi-flavor Markdown generator
25
3
 
@@ -63,17 +41,17 @@ pip install mdforge
63
41
  Create your first Markdown document:
64
42
 
65
43
  ```python
66
- from mdforge import Document, Heading, Paragraph, Strong
44
+ from mdforge import Document, Paragraph, Section, Strong
67
45
  from pathlib import Path
68
46
 
69
47
  # create a document
70
48
  doc = Document()
71
49
 
72
50
  # add elements
73
- doc += [
74
- Heading("My first MDForge document"),
75
- Paragraph("Hello, ", Strong("world"), "!"),
76
- ]
51
+ doc += Section(
52
+ "My first MDForge document",
53
+ elements=Paragraph("Hello, ", Strong("world"), "!"),
54
+ )
77
55
 
78
56
  # render pandoc-flavored Markdown document to a file
79
57
  doc.render_file("doc.md", flavor="pandoc")
@@ -163,11 +141,33 @@ Elaboration on point 3.
163
141
 
164
142
  Note the following observations:
165
143
 
166
- - Sections can be nested in other sections, with optional headings
167
- - Heading levels for sections are automatically set by their placement in the hierarchy
144
+ - Headings are created from section titles; content belonging to a heading is placed in its section
145
+ - Sections can be nested in other sections, with optional titles
146
+ - Heading levels for sections are automatically set by their placement in the hierarchy; see [Heading levels](#heading-levels)
168
147
  - Strings added to a document or section via `+=` are treated as raw text
169
148
  - A comment is placed at the end of each list; this disambiguates the end of one list and the start of the next, in case there are no other elements in between
170
149
 
150
+ ### Heading levels
151
+
152
+ By default (`level=None`), the level of a section is relative to the render root: the element on which `render()` is called. The render root is level 1 and each nested section is one level deeper.
153
+
154
+ As a result, a section rendered by itself is a self-contained tree starting at level 1, even if it's also placed in a document.
155
+
156
+ To generate a fragment to be placed in a larger document, pass an explicit `level`. Explicit levels are invariant of placement, and nested sections are relative to it:
157
+
158
+ ```python
159
+ from mdforge import Section
160
+
161
+ fragment = Section("Fragment", level=3, elements=Section("Subsection"))
162
+
163
+ assert fragment.render(flavor="pandoc") == "### Fragment\n\n#### Subsection"
164
+ ```
165
+
166
+ When an element with an explicit level is rendered as part of a larger tree, its level is checked against its placement:
167
+
168
+ - A level not nested in the containing level, e.g. `level=1` in a level-1 section, raises `RenderError`
169
+ - A level which skips levels, e.g. `level=3` in a level-1 section, issues `RenderWarning`
170
+
171
171
  ## Pythonic Markdown elements
172
172
 
173
173
  MDForge provides a set of Markdown elements that can be composed to create rich documents. Not all common elements are implemented yet, e.g. code blocks. Nonetheless, you can insert raw text (which may be pre-formatted as Markdown) using `+=`.
@@ -378,7 +378,7 @@ doc += Table(
378
378
  ],
379
379
  header=[
380
380
  [Cell("Column 1", rspan=2), Cell("Columns 2 & 3", cspan=2)],
381
- ["Column 2", "Column 3"],
381
+ [Cell("Column 2"), Cell("Column 3")],
382
382
  ],
383
383
  block=True,
384
384
  )
@@ -556,32 +556,33 @@ assert element.render(flavor="pandoc") == "This is a **test element**"
556
556
 
557
557
  ### HTML attributes
558
558
 
559
- For pandoc flavor, HTML attributes can be added to various elements:
559
+ For pandoc flavor, HTML attributes can be added to various elements, including section headings:
560
560
 
561
561
  ```python
562
- from mdforge import Attributes, Document, Heading, Ref, Span
562
+ from mdforge import Attributes, Document, Ref, Section, Span
563
563
 
564
564
  doc = Document()
565
565
 
566
- # heading with ID, classes, and custom attributes
567
- my_heading = Heading(
568
- "Heading with attributes",
566
+ # section with heading ID, classes, and custom attributes
567
+ my_section = Section(
568
+ "Section with attributes",
569
569
  attributes=Attributes(
570
- html_id="my-heading",
570
+ html_id="my-section",
571
571
  css_classes=["class1", "class2"],
572
572
  attrs={"style": "color: blue;"},
573
573
  ),
574
574
  )
575
- doc += my_heading
575
+ doc += my_section
576
576
 
577
577
  # span with attributes
578
- doc += Span(
578
+ my_section += Span(
579
579
  "Text with attributes",
580
580
  attributes=Attributes(html_id="my-span", css_classes="class1"),
581
581
  )
582
582
 
583
- # reference to heading by id
584
- doc += Ref(my_heading, "See previous heading")
583
+ # references to section, by object and by id
584
+ my_section += Ref(my_section, "See this section")
585
+ my_section += Ref("my-section")
585
586
 
586
587
  doc.render_file("doc.md", flavor="pandoc")
587
588
  ```
@@ -589,11 +590,13 @@ doc.render_file("doc.md", flavor="pandoc")
589
590
  This is rendered as:
590
591
 
591
592
  ```markdown
592
- # Heading with attributes {#my-heading .class1 .class2 style="color: blue;"}
593
+ # Section with attributes {#my-section .class1 .class2 style="color: blue;"}
593
594
 
594
595
  [Text with attributes]{#my-span .class1}
595
596
 
596
- [See previous heading](#my-heading)
597
+ [See this section](#my-section)
598
+
599
+ [Section with attributes](#my-section)
597
600
 
598
601
  ```
599
602
 
@@ -602,12 +605,12 @@ This is rendered as:
602
605
  As MDForge is designed with pandoc compatibility in mind, it automatically tracks required pandoc extensions:
603
606
 
604
607
  ```python
605
- from mdforge import Attributes, Document, Heading, Strikethrough
608
+ from mdforge import Attributes, Document, Section, Strikethrough
606
609
 
607
610
  doc = Document()
608
611
 
609
612
  # requires "header_attributes"
610
- doc += Heading("Heading 1", attributes=Attributes(html_id="heading-1"))
613
+ doc += Section("Section 1", attributes=Attributes(html_id="section-1"))
611
614
 
612
615
  # requires "strikeout"
613
616
  doc += Strikethrough("This text is struck through")
@@ -616,4 +619,3 @@ doc += Strikethrough("This text is struck through")
616
619
  extensions = doc.get_pandoc_extensions()
617
620
  assert extensions == ["header_attributes", "strikeout"]
618
621
  ```
619
-
@@ -0,0 +1,109 @@
1
+ [project]
2
+ classifiers = [
3
+ "Development Status :: 3 - Alpha",
4
+ "Natural Language :: English",
5
+ "Operating System :: OS Independent",
6
+ "Programming Language :: Python :: 3",
7
+ "Programming Language :: Python :: 3.12",
8
+ "Programming Language :: Python :: 3.13",
9
+ "Programming Language :: Python :: 3.14",
10
+ "Programming Language :: Python :: Implementation :: CPython",
11
+ "Topic :: Software Development :: Libraries :: Python Modules",
12
+ "Typing :: Typed",
13
+ ]
14
+ dependencies = ["pyyaml>=6.0.2,<7"]
15
+ description = "Pythonic multi-flavor Markdown generator"
16
+ license = "MIT"
17
+ license-files = ["LICENSE"]
18
+ name = "mdforge"
19
+ readme = "README.md"
20
+ requires-python = ">=3.12,<4.0"
21
+ version = "0.3.0"
22
+
23
+ [[project.authors]]
24
+ name = "mm21"
25
+ email = "mm21.dev@gmail.com"
26
+
27
+ [project.urls]
28
+ homepage = "https://github.com/mm21/mdforge"
29
+
30
+ [dependency-groups]
31
+ dev = [
32
+ "pyprojkit[all]>=0.9.0,<0.10.0",
33
+ "pytest-powerpack>=0.1.5,<0.2",
34
+ "types-pyyaml>=6.0.12,<7",
35
+ ]
36
+
37
+ [build-system]
38
+ build-backend = "uv_build"
39
+ requires = ["uv_build>=0.13.5,<0.14.0"]
40
+
41
+ [tool.autoflake]
42
+ in_place = true
43
+ recursive = true
44
+ remove-all-unused-imports = true
45
+ remove-unused-variables = true
46
+
47
+ [tool.black]
48
+ quiet = true
49
+ target-version = [
50
+ "py312",
51
+ "py313",
52
+ "py314",
53
+ ]
54
+
55
+ [tool.coverage.report]
56
+ exclude_lines = [
57
+ "if TYPE_CHECKING:",
58
+ '\.\.\.$',
59
+ ]
60
+
61
+ [tool.coverage.run]
62
+ data_file = "__cache__/.coverage"
63
+
64
+ [tool.docfmt]
65
+ force-reflow = true
66
+ in-place = true
67
+ recursive = true
68
+ summary-on-own-line = true
69
+
70
+ [tool.doit]
71
+ dep_file = "__cache__/.doit.db"
72
+ verbosity = 2
73
+
74
+ [tool.isort]
75
+ profile = "black"
76
+ quiet = true
77
+
78
+ [tool.mypy]
79
+ check_untyped_defs = true
80
+ python_version = "3.12"
81
+
82
+ [[tool.mypy.overrides]]
83
+ ignore_missing_imports = true
84
+ module = [
85
+ "pytest_powerpack",
86
+ "pytest_powerpack.*",
87
+ ]
88
+
89
+ [tool.nox]
90
+ default_venv_backend = "uv"
91
+ envdir = "__cache__/nox"
92
+
93
+ [tool.pyright]
94
+ pythonVersion = "3.12"
95
+
96
+ [tool.pytest.ini_options]
97
+ addopts = "--import-mode=importlib -s -v -rA"
98
+ cache_dir = "__cache__/pytest"
99
+ powerpack_underline = true
100
+ testpaths = ["test"]
101
+
102
+ [tool.tomlsort]
103
+ sort_first = [
104
+ "project",
105
+ "dependency-groups",
106
+ "build-system",
107
+ ]
108
+ sort_table_keys = true
109
+ spaces_before_inline_comment = 2
@@ -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.3.0"
27
+
28
+ [project.urls]
29
+ homepage = "https://github.com/mm21/mdforge"
30
+
31
+ [dependency-groups]
32
+ dev = [
33
+ "pyprojkit[all]>=0.9.0,<0.10.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" # pyprojkit-tracked
40
+ requires = ["uv_build>=0.13.5,<0.14.0"] # pyprojkit-tracked
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,111 @@
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
+ BlockImage,
36
+ HorizontalRule,
37
+ Quote,
38
+ AlignedBlock,
39
+ Paragraph,
40
+ BlockText,
41
+ ListItemType,
42
+ ListItem,
43
+ BulletList,
44
+ NumberedList,
45
+ BaseItemList,
46
+ DefinitionItem,
47
+ DefinitionList,
48
+ Table,
49
+ Cell,
50
+ CellType,
51
+ RowType,
52
+ Text,
53
+ Emph,
54
+ Strong,
55
+ Underline,
56
+ Strikethrough,
57
+ Link,
58
+ Ref,
59
+ Newline,
60
+ Span,
61
+ InlineImage,
62
+ )
63
+ from .exceptions import (
64
+ ValidationError,
65
+ RenderError,
66
+ RenderWarning,
67
+ )
68
+
69
+ __all__ = [
70
+ "FlavorType",
71
+ "AlignType",
72
+ "Document",
73
+ "BaseElement",
74
+ "BaseInlineElement",
75
+ "BaseBlockElement",
76
+ "Attributes",
77
+ "InlineContainer",
78
+ "BlockContainer",
79
+ "Section",
80
+ "BlockImage",
81
+ "HorizontalRule",
82
+ "Quote",
83
+ "AlignedBlock",
84
+ "Paragraph",
85
+ "BlockText",
86
+ "ListItemType",
87
+ "ListItem",
88
+ "BulletList",
89
+ "NumberedList",
90
+ "BaseItemList",
91
+ "DefinitionItem",
92
+ "DefinitionList",
93
+ "Table",
94
+ "Cell",
95
+ "CellType",
96
+ "RowType",
97
+ "Text",
98
+ "Emph",
99
+ "Strong",
100
+ "Underline",
101
+ "Strikethrough",
102
+ "Link",
103
+ "Ref",
104
+ "Newline",
105
+ "Span",
106
+ "InlineImage",
107
+ "ValidationError",
108
+ "RenderError",
109
+ "RenderWarning",
110
+ ]
111
+ # </AUTOGEN_INIT>