markdown_convert 1.2.38__tar.gz → 1.2.40__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.
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/PKG-INFO +1 -1
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/default.css +41 -38
- markdown_convert-1.2.40/markdown_convert/modules/constants.py +56 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/modules/convert.py +9 -41
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/modules/transform.py +3 -3
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/pyproject.toml +1 -1
- markdown_convert-1.2.38/markdown_convert/modules/constants.py +0 -25
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/.gitignore +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/LICENSE +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/README.md +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/__init__.py +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/__main__.py +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/code.css +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/modules/__init__.py +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/modules/resources.py +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/modules/utils.py +0 -0
- {markdown_convert-1.2.38 → markdown_convert-1.2.40}/markdown_convert/modules/validate.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: markdown_convert
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.40
|
|
4
4
|
Summary: Convert Markdown files to PDF from your command line.
|
|
5
5
|
Project-URL: homepage, https://github.com/Julynx/markdown_convert
|
|
6
6
|
Author-email: Julio Cabria <juliocabria@tutanota.com>
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
:root {
|
|
2
|
-
/* --
|
|
3
|
-
--top-margin:
|
|
4
|
-
--bottom-margin: 0.
|
|
5
|
-
--left-margin: 1.5em;
|
|
2
|
+
/* -- Header margins -- */
|
|
3
|
+
--top-margin: 1em;
|
|
4
|
+
--bottom-margin-small: 0.25em;
|
|
6
5
|
|
|
7
|
-
/* --
|
|
8
|
-
--
|
|
9
|
-
--top-margin-small: 0.25em;
|
|
10
|
-
--bottom-margin-small: 0.15em;
|
|
6
|
+
/* -- Element margins -- */
|
|
7
|
+
--bottom-margin: 0.75em;
|
|
11
8
|
|
|
12
|
-
/* --
|
|
9
|
+
/* -- Nested element margins -- */
|
|
10
|
+
--left-margin: 1.5em;
|
|
11
|
+
--left-margin-small: 1em;
|
|
13
12
|
--left-margin-big: 2em;
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -28,39 +27,41 @@ body {
|
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
/* Headers and paragraphs */
|
|
31
|
-
h1
|
|
30
|
+
h1 {
|
|
31
|
+
margin-top: 0;
|
|
32
|
+
margin-bottom: var(--bottom-margin-small);
|
|
33
|
+
}
|
|
34
|
+
|
|
32
35
|
h2,
|
|
33
36
|
h3,
|
|
34
37
|
h4,
|
|
35
38
|
h5 {
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
margin-top: var(--top-margin);
|
|
40
|
+
margin-bottom: var(--bottom-margin-small);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
|
|
43
|
+
p {
|
|
41
44
|
margin-top: 0;
|
|
42
45
|
margin-bottom: var(--bottom-margin);
|
|
43
46
|
}
|
|
44
47
|
|
|
48
|
+
h1,
|
|
45
49
|
h2,
|
|
46
50
|
h3,
|
|
47
51
|
h4,
|
|
48
|
-
h5
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
margin-bottom: 0;
|
|
52
|
+
h5 {
|
|
53
|
+
color: #333;
|
|
54
|
+
font-weight: 600;
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
h1 {
|
|
55
58
|
font-size: 2.2rem;
|
|
56
59
|
border-bottom: 0.5px solid #999;
|
|
57
|
-
padding-bottom: var(--bottom-margin-small);
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
h2 {
|
|
61
63
|
font-size: 1.8rem;
|
|
62
64
|
border-bottom: 0.5px solid #999;
|
|
63
|
-
padding-bottom: var(--bottom-margin-small);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
h3 {
|
|
@@ -90,22 +91,20 @@ a {
|
|
|
90
91
|
ul,
|
|
91
92
|
ol {
|
|
92
93
|
font-size: 1rem;
|
|
93
|
-
|
|
94
|
-
margin-top: var(--top-margin);
|
|
95
|
-
margin-right: 0;
|
|
94
|
+
margin-top: 0;
|
|
96
95
|
margin-bottom: var(--bottom-margin);
|
|
97
|
-
margin-
|
|
96
|
+
margin-right: 0;
|
|
97
|
+
margin-left: var(--left-margin-small);
|
|
98
|
+
padding-left: var(--left-margin);
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
ul ol,
|
|
101
102
|
ol ul,
|
|
102
103
|
ol ol,
|
|
103
104
|
ul ul {
|
|
104
|
-
margin-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
li {
|
|
108
|
-
margin-top: var(--top-margin-small);
|
|
105
|
+
margin-bottom: 0;
|
|
106
|
+
margin-left: 0;
|
|
107
|
+
padding-left: var(--left-margin);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
110
|
/* Code blocks */
|
|
@@ -114,10 +113,10 @@ pre {
|
|
|
114
113
|
white-space: pre-wrap;
|
|
115
114
|
}
|
|
116
115
|
|
|
117
|
-
pre
|
|
116
|
+
pre>code {
|
|
118
117
|
display: block;
|
|
119
118
|
padding: 1em;
|
|
120
|
-
margin-top:
|
|
119
|
+
margin-top: 0;
|
|
121
120
|
margin-bottom: var(--bottom-margin);
|
|
122
121
|
}
|
|
123
122
|
|
|
@@ -143,26 +142,29 @@ h5 code {
|
|
|
143
142
|
|
|
144
143
|
/* Quotes */
|
|
145
144
|
blockquote {
|
|
146
|
-
margin-top:
|
|
145
|
+
margin-top: 0;
|
|
146
|
+
margin-bottom: var(--bottom-margin);
|
|
147
147
|
margin-left: var(--left-margin);
|
|
148
148
|
border-left: 4px solid #ccc;
|
|
149
149
|
padding-left: 0.5em;
|
|
150
150
|
color: #666;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
blockquote
|
|
154
|
-
|
|
153
|
+
blockquote>blockquote {
|
|
154
|
+
padding-left: var(--left-margin-small);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
/* Figures */
|
|
158
157
|
img {
|
|
158
|
+
max-width: 80vw;
|
|
159
|
+
max-height: 80vh;
|
|
160
|
+
width: auto;
|
|
161
|
+
height: auto;
|
|
159
162
|
display: block;
|
|
160
163
|
margin: 2em auto 1em auto;
|
|
161
|
-
max-width: 80%;
|
|
162
164
|
}
|
|
163
165
|
|
|
164
166
|
/* -- Figure footer */
|
|
165
|
-
p
|
|
167
|
+
p>img+em {
|
|
166
168
|
text-align: center;
|
|
167
169
|
font-size: 1rem;
|
|
168
170
|
font-style: italic;
|
|
@@ -176,7 +178,8 @@ table {
|
|
|
176
178
|
font-size: 1rem;
|
|
177
179
|
font-family: inherit;
|
|
178
180
|
border-collapse: collapse;
|
|
179
|
-
margin-top:
|
|
181
|
+
margin-top: 0;
|
|
182
|
+
margin-bottom: var(--bottom-margin);
|
|
180
183
|
text-align: left;
|
|
181
184
|
width: 100%;
|
|
182
185
|
table-layout: auto;
|
|
@@ -215,7 +218,7 @@ td {
|
|
|
215
218
|
page-break-after: always;
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
.pagebreak
|
|
221
|
+
.pagebreak+* {
|
|
219
222
|
margin-top: 0;
|
|
220
223
|
}
|
|
221
224
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the constants used in the markdown_convert package.
|
|
3
|
+
Author: @julynx
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
RED = "31"
|
|
7
|
+
GREEN = "32"
|
|
8
|
+
YELLOW = "33"
|
|
9
|
+
BLUE = "34"
|
|
10
|
+
MAGENTA = "35"
|
|
11
|
+
CYAN = "36"
|
|
12
|
+
|
|
13
|
+
OPTIONS = ("markdown_file_path", "--mode", "--css", "--out", "-h", "--help")
|
|
14
|
+
|
|
15
|
+
OPTIONS_MODES = ("once", "live", "debug")
|
|
16
|
+
|
|
17
|
+
MARKDOWN_EXTENSIONS = {
|
|
18
|
+
"fenced-code-blocks": None,
|
|
19
|
+
"header-ids": True,
|
|
20
|
+
"breaks": {"on_newline": True},
|
|
21
|
+
"tables": True,
|
|
22
|
+
"latex": True,
|
|
23
|
+
"mermaid": None,
|
|
24
|
+
"strike": None,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
BROWSER_ARGS = [
|
|
28
|
+
"--disable-dev-shm-usage",
|
|
29
|
+
"--disable-extensions",
|
|
30
|
+
"--disable-plugins",
|
|
31
|
+
"--disable-gpu",
|
|
32
|
+
"--no-first-run",
|
|
33
|
+
"--no-default-browser-check",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
CSP_TEMPLATE = (
|
|
37
|
+
"default-src 'none'; "
|
|
38
|
+
"script-src 'nonce-{nonce}' https://cdn.jsdelivr.net; " # <- Script for Mermaid diagrams
|
|
39
|
+
"script-src-elem 'nonce-{nonce}' https://cdn.jsdelivr.net; "
|
|
40
|
+
"style-src 'unsafe-inline'; "
|
|
41
|
+
"img-src data: https: file:; "
|
|
42
|
+
"font-src data: https:; "
|
|
43
|
+
"connect-src https://cdn.jsdelivr.net;"
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
PDF_PARAMS = {
|
|
47
|
+
"format": "A4",
|
|
48
|
+
"print_background": True,
|
|
49
|
+
"margin": {
|
|
50
|
+
"top": "20mm",
|
|
51
|
+
"bottom": "20mm",
|
|
52
|
+
"left": "20mm",
|
|
53
|
+
"right": "20mm",
|
|
54
|
+
},
|
|
55
|
+
"path": None, # <- Replace with actual output path when used
|
|
56
|
+
}
|
|
@@ -12,7 +12,7 @@ from pathlib import Path
|
|
|
12
12
|
import markdown2
|
|
13
13
|
from playwright.sync_api import sync_playwright
|
|
14
14
|
|
|
15
|
-
from .constants import MARKDOWN_EXTENSIONS
|
|
15
|
+
from .constants import MARKDOWN_EXTENSIONS, BROWSER_ARGS, CSP_TEMPLATE, PDF_PARAMS
|
|
16
16
|
from .resources import get_code_css_path, get_css_path, get_output_path
|
|
17
17
|
from .transform import (
|
|
18
18
|
create_sections,
|
|
@@ -41,39 +41,17 @@ def _generate_pdf_with_playwright(
|
|
|
41
41
|
css_content (str, optional): CSS content to inject.
|
|
42
42
|
base_dir (Path, optional): Base directory for resolving relative paths in HTML.
|
|
43
43
|
dump_html (bool, optional): Whether to dump the HTML content to a file.
|
|
44
|
+
nonce (str, optional): Nonce for Content Security Policy.
|
|
44
45
|
"""
|
|
45
|
-
|
|
46
|
+
if nonce is None:
|
|
47
|
+
raise ValueError("A nonce must be provided for CSP generation.")
|
|
46
48
|
|
|
47
|
-
# Content Security Policy using nonce to whitelist only the Mermaid initialization script
|
|
48
49
|
# This prevents arbitrary JavaScript injection while allowing Mermaid to work
|
|
49
|
-
csp = (
|
|
50
|
-
|
|
51
|
-
f"script-src 'nonce-{nonce}' https://cdn.jsdelivr.net; "
|
|
52
|
-
f"script-src-elem 'nonce-{nonce}' https://cdn.jsdelivr.net; "
|
|
53
|
-
"style-src 'unsafe-inline'; "
|
|
54
|
-
"img-src data: https: file:; "
|
|
55
|
-
"font-src data: https:; "
|
|
56
|
-
"connect-src https://cdn.jsdelivr.net;"
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
# Wrap HTML content with CSP and CSS
|
|
60
|
-
if css_content:
|
|
61
|
-
full_html = create_html_document(html_content, css_content, csp)
|
|
62
|
-
else:
|
|
63
|
-
full_html = html_content
|
|
50
|
+
csp = CSP_TEMPLATE.format(nonce=nonce)
|
|
51
|
+
full_html = create_html_document(html_content, css_content, csp)
|
|
64
52
|
|
|
65
53
|
with sync_playwright() as playwright:
|
|
66
|
-
browser = playwright.chromium.launch(
|
|
67
|
-
headless=True,
|
|
68
|
-
args=[
|
|
69
|
-
"--disable-dev-shm-usage",
|
|
70
|
-
"--disable-extensions",
|
|
71
|
-
"--disable-plugins",
|
|
72
|
-
"--disable-gpu",
|
|
73
|
-
"--no-first-run",
|
|
74
|
-
"--no-default-browser-check",
|
|
75
|
-
],
|
|
76
|
-
)
|
|
54
|
+
browser = playwright.chromium.launch(headless=True, args=BROWSER_ARGS)
|
|
77
55
|
context = browser.new_context(
|
|
78
56
|
java_script_enabled=True,
|
|
79
57
|
permissions=[],
|
|
@@ -82,7 +60,6 @@ def _generate_pdf_with_playwright(
|
|
|
82
60
|
)
|
|
83
61
|
page = context.new_page()
|
|
84
62
|
|
|
85
|
-
# Handle loading based on presence of base_dir
|
|
86
63
|
temp_html = None
|
|
87
64
|
try:
|
|
88
65
|
if base_dir:
|
|
@@ -93,16 +70,9 @@ def _generate_pdf_with_playwright(
|
|
|
93
70
|
page.set_content(full_html, wait_until="networkidle", timeout=30000)
|
|
94
71
|
|
|
95
72
|
pdf_params = {
|
|
96
|
-
|
|
97
|
-
"print_background": True,
|
|
98
|
-
"margin": {
|
|
99
|
-
"top": "20mm",
|
|
100
|
-
"bottom": "20mm",
|
|
101
|
-
"left": "20mm",
|
|
102
|
-
"right": "20mm",
|
|
103
|
-
},
|
|
73
|
+
**PDF_PARAMS,
|
|
104
74
|
"path": output_path,
|
|
105
|
-
}
|
|
75
|
+
}
|
|
106
76
|
|
|
107
77
|
pdf_bytes = page.pdf(**pdf_params)
|
|
108
78
|
return None if output_path else pdf_bytes
|
|
@@ -317,7 +287,6 @@ class LiveConverter:
|
|
|
317
287
|
|
|
318
288
|
try:
|
|
319
289
|
while True:
|
|
320
|
-
|
|
321
290
|
markdown_modified = self.get_last_modified_date(self.md_path)
|
|
322
291
|
css_modified = self.get_last_modified_date(self.css_path)
|
|
323
292
|
|
|
@@ -325,7 +294,6 @@ class LiveConverter:
|
|
|
325
294
|
markdown_modified != self.md_last_modified
|
|
326
295
|
or css_modified != self.css_last_modified
|
|
327
296
|
):
|
|
328
|
-
|
|
329
297
|
self.write_pdf()
|
|
330
298
|
|
|
331
299
|
self.md_last_modified = markdown_modified
|
|
@@ -21,13 +21,13 @@ def create_html_document(html_content, css_content, csp):
|
|
|
21
21
|
<html>
|
|
22
22
|
<head>
|
|
23
23
|
<meta charset="UTF-8">
|
|
24
|
-
<meta http-equiv="Content-Security-Policy" content="{csp}">
|
|
24
|
+
<meta http-equiv="Content-Security-Policy" content="{csp or ''}">
|
|
25
25
|
<style>
|
|
26
|
-
{css_content}
|
|
26
|
+
{css_content or ''}
|
|
27
27
|
</style>
|
|
28
28
|
</head>
|
|
29
29
|
<body>
|
|
30
|
-
{html_content}
|
|
30
|
+
{html_content or ''}
|
|
31
31
|
</body>
|
|
32
32
|
</html>"""
|
|
33
33
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "markdown_convert"
|
|
7
|
-
version = "1.2.
|
|
7
|
+
version = "1.2.40"
|
|
8
8
|
description = "Convert Markdown files to PDF from your command line."
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "Julio Cabria", email = "juliocabria@tutanota.com" },
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module contains the constants used in the markdown_convert package.
|
|
3
|
-
Author: @julynx
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
RED = "31"
|
|
7
|
-
GREEN = "32"
|
|
8
|
-
YELLOW = "33"
|
|
9
|
-
BLUE = "34"
|
|
10
|
-
MAGENTA = "35"
|
|
11
|
-
CYAN = "36"
|
|
12
|
-
|
|
13
|
-
OPTIONS = ("markdown_file_path", "--mode", "--css", "--out", "-h", "--help")
|
|
14
|
-
|
|
15
|
-
OPTIONS_MODES = ("once", "live", "debug")
|
|
16
|
-
|
|
17
|
-
MARKDOWN_EXTENSIONS = {
|
|
18
|
-
"fenced-code-blocks": None,
|
|
19
|
-
"header-ids": True,
|
|
20
|
-
"breaks": {"on_newline": True},
|
|
21
|
-
"tables": True,
|
|
22
|
-
"latex": True,
|
|
23
|
-
"mermaid": None,
|
|
24
|
-
"strike": None,
|
|
25
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|