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.
- mdforge-0.2.2/README.md → mdforge-0.3.0/PKG-INFO +70 -22
- mdforge-0.2.2/PKG-INFO → mdforge-0.3.0/README.md +47 -45
- mdforge-0.3.0/pyproject.toml +109 -0
- mdforge-0.3.0/pyproject.toml.orig +107 -0
- mdforge-0.3.0/src/mdforge/__init__.py +111 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/_norm.py +13 -18
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/_utils.py +39 -8
- mdforge-0.3.0/src/mdforge/container.py +231 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/document.py +10 -12
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/element.py +126 -49
- mdforge-0.3.0/src/mdforge/elements/__init__.py +75 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/_image.py +5 -6
- mdforge-0.3.0/src/mdforge/elements/block/__init__.py +67 -0
- mdforge-0.3.0/src/mdforge/elements/block/basic.py +74 -0
- mdforge-0.3.0/src/mdforge/elements/block/container.py +68 -0
- mdforge-0.3.0/src/mdforge/elements/block/lists/__init__.py +33 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/lists/definition.py +24 -17
- mdforge-0.3.0/src/mdforge/elements/block/lists/item.py +211 -0
- mdforge-0.3.0/src/mdforge/elements/block/section.py +122 -0
- mdforge-0.3.0/src/mdforge/elements/block/table/__init__.py +22 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_context.py +9 -8
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/flavors.py +12 -15
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/__init__.py +1 -2
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/context.py +55 -83
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/variant.py +2 -4
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/frame/variants.py +1 -1
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_params.py +33 -47
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_variant.py +6 -13
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_vcell.py +16 -14
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/cell.py +15 -19
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/table.py +21 -24
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/text.py +4 -5
- mdforge-0.3.0/src/mdforge/elements/inline/__init__.py +39 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/inline/basic.py +9 -11
- mdforge-0.3.0/src/mdforge/elements/inline/text.py +198 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/exceptions.py +10 -2
- mdforge-0.3.0/src/mdforge/py.typed +0 -0
- mdforge-0.2.2/mdforge/__init__.py +0 -15
- mdforge-0.2.2/mdforge/container.py +0 -217
- mdforge-0.2.2/mdforge/elements/__init__.py +0 -11
- mdforge-0.2.2/mdforge/elements/block/__init__.py +0 -14
- mdforge-0.2.2/mdforge/elements/block/basic.py +0 -109
- mdforge-0.2.2/mdforge/elements/block/lists/__init__.py +0 -11
- mdforge-0.2.2/mdforge/elements/block/lists/item.py +0 -209
- mdforge-0.2.2/mdforge/elements/block/section.py +0 -49
- mdforge-0.2.2/mdforge/elements/block/table/__init__.py +0 -11
- mdforge-0.2.2/mdforge/elements/inline/__init__.py +0 -11
- mdforge-0.2.2/mdforge/elements/inline/text.py +0 -152
- mdforge-0.2.2/pyproject.toml +0 -71
- {mdforge-0.2.2 → mdforge-0.3.0}/LICENSE +0 -0
- {mdforge-0.2.2 → mdforge-0.3.0/src}/mdforge/elements/block/table/_flavors/list/__init__.py +0 -0
- {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,
|
|
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
|
-
|
|
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
|
-
-
|
|
145
|
-
-
|
|
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,
|
|
585
|
+
from mdforge import Attributes, Document, Ref, Section, Span
|
|
541
586
|
|
|
542
587
|
doc = Document()
|
|
543
588
|
|
|
544
|
-
#
|
|
545
|
-
|
|
546
|
-
"
|
|
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-
|
|
593
|
+
html_id="my-section",
|
|
549
594
|
css_classes=["class1", "class2"],
|
|
550
595
|
attrs={"style": "color: blue;"},
|
|
551
596
|
),
|
|
552
597
|
)
|
|
553
|
-
doc +=
|
|
598
|
+
doc += my_section
|
|
554
599
|
|
|
555
600
|
# span with attributes
|
|
556
|
-
|
|
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
|
-
#
|
|
562
|
-
|
|
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
|
-
#
|
|
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
|
|
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,
|
|
631
|
+
from mdforge import Attributes, Document, Section, Strikethrough
|
|
584
632
|
|
|
585
633
|
doc = Document()
|
|
586
634
|
|
|
587
635
|
# requires "header_attributes"
|
|
588
|
-
doc +=
|
|
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,
|
|
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
|
-
|
|
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
|
-
-
|
|
167
|
-
-
|
|
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,
|
|
562
|
+
from mdforge import Attributes, Document, Ref, Section, Span
|
|
563
563
|
|
|
564
564
|
doc = Document()
|
|
565
565
|
|
|
566
|
-
#
|
|
567
|
-
|
|
568
|
-
"
|
|
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-
|
|
570
|
+
html_id="my-section",
|
|
571
571
|
css_classes=["class1", "class2"],
|
|
572
572
|
attrs={"style": "color: blue;"},
|
|
573
573
|
),
|
|
574
574
|
)
|
|
575
|
-
doc +=
|
|
575
|
+
doc += my_section
|
|
576
576
|
|
|
577
577
|
# span with attributes
|
|
578
|
-
|
|
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
|
-
#
|
|
584
|
-
|
|
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
|
-
#
|
|
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
|
|
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,
|
|
608
|
+
from mdforge import Attributes, Document, Section, Strikethrough
|
|
606
609
|
|
|
607
610
|
doc = Document()
|
|
608
611
|
|
|
609
612
|
# requires "header_attributes"
|
|
610
|
-
doc +=
|
|
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>
|