markdown_convert 1.2.38__py3-none-any.whl → 1.2.40__py3-none-any.whl

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.
@@ -1,15 +1,14 @@
1
1
  :root {
2
- /* -- Standard margins */
3
- --top-margin: 0.75em;
4
- --bottom-margin: 0.5em;
5
- --left-margin: 1.5em;
2
+ /* -- Header margins -- */
3
+ --top-margin: 1em;
4
+ --bottom-margin-small: 0.25em;
6
5
 
7
- /* -- Small margins */
8
- --left-margin-small: 1em;
9
- --top-margin-small: 0.25em;
10
- --bottom-margin-small: 0.15em;
6
+ /* -- Element margins -- */
7
+ --bottom-margin: 0.75em;
11
8
 
12
- /* -- Big margins */
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
- color: #333;
37
- font-weight: 600;
39
+ margin-top: var(--top-margin);
40
+ margin-bottom: var(--bottom-margin-small);
38
41
  }
39
42
 
40
- h1 {
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
- p {
50
- margin-top: var(--top-margin);
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
- padding: 0;
94
- margin-top: var(--top-margin);
95
- margin-right: 0;
94
+ margin-top: 0;
96
95
  margin-bottom: var(--bottom-margin);
97
- margin-left: var(--left-margin-big);
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-top: 0;
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 > code {
116
+ pre>code {
118
117
  display: block;
119
118
  padding: 1em;
120
- margin-top: var(--top-margin);
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: var(--top-margin);
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 > blockquote {
154
- margin-left: var(--left-margin-small);
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 > img + em {
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: var(--top-margin);
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
 
@@ -23,3 +23,34 @@ MARKDOWN_EXTENSIONS = {
23
23
  "mermaid": None,
24
24
  "strike": None,
25
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
- # Generate a cryptographic nonce for the Mermaid script
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
- "default-src 'none'; "
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
- "format": "A4",
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
- } # Playwright ignores None paths
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown_convert
3
- Version: 1.2.38
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,16 +1,16 @@
1
1
  markdown_convert/__init__.py,sha256=ysW3pXsDGGK4PzZHcIBTpfVW58IkDUwHffDkf_GM6UU,303
2
2
  markdown_convert/__main__.py,sha256=hO7AO0GnzPMPNqls8r5aF2C-7l9aFHDf1m8mXSy1GBE,2809
3
3
  markdown_convert/code.css,sha256=Wt4FqFqJcpT-jwY3GN-o4ZRCCXU8DQj-9lqKdGiuoyw,4935
4
- markdown_convert/default.css,sha256=QFJ2F3Rc7Cn-o5-9CuEXeq8NYLSB_FDWrv3MNY418A0,3465
4
+ markdown_convert/default.css,sha256=rIwRao7l7Rq6rkOaxVMfZ4yGQc2D68eJ7URLQ597GcY,3530
5
5
  markdown_convert/modules/__init__.py,sha256=PFPgiQhMXgyfjD8BkfLC_X8AR1jz-dCxfif2qmNofJs,65
6
- markdown_convert/modules/constants.py,sha256=_h6N0fhG9K1hQPmp3eYu53TfQnAPe7RtmMj-2FCD7VU,495
7
- markdown_convert/modules/convert.py,sha256=R1xIKW6UVGP7a6VK5C6qLK278wBlHZV9X6Y9q73mz_k,9843
6
+ markdown_convert/modules/constants.py,sha256=eUeIFRxZerP3E0Rgp_Nsl0Q38IBELwca5UO3fbUcxRA,1280
7
+ markdown_convert/modules/convert.py,sha256=n9PrM6b6CwALQrwuVNu2f9B7KA_AQhuvGUaZ9dUHH80,8883
8
8
  markdown_convert/modules/resources.py,sha256=tnW8JmCrJNBRbzOcaOVG6GX5jPC8Kzj3dA7gX0B935A,2488
9
- markdown_convert/modules/transform.py,sha256=uQbTtiSKDTXRs49OuDazpD2nSya4fpghzMS4BZ9zm_8,3120
9
+ markdown_convert/modules/transform.py,sha256=wUC22ENv8OeRfPPHt5Ez46ll9PfL3MYm2Sc6vHxe_a0,3138
10
10
  markdown_convert/modules/utils.py,sha256=NX0WegM8e8MPKNNmweTujAWO8ZghdB8LSGDx20K2E44,655
11
11
  markdown_convert/modules/validate.py,sha256=XV_k7cHeifEKDaltF26tCmabs2-Me5msP3enI_eVwfA,1517
12
- markdown_convert-1.2.38.dist-info/METADATA,sha256=gh3AU2ZAPkxrvn-ga9SkDsBhT7MagGfhMd1SZTOqip0,3939
13
- markdown_convert-1.2.38.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
- markdown_convert-1.2.38.dist-info/entry_points.txt,sha256=RCmzC7C0sX-SpzIP2Cr34rhg3lMd7BRx-exaZPfK8bU,68
15
- markdown_convert-1.2.38.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
16
- markdown_convert-1.2.38.dist-info/RECORD,,
12
+ markdown_convert-1.2.40.dist-info/METADATA,sha256=rlcQOUY2k1aZPNjhnHAr2bpGyanertNw0TOvfJ2jJJ4,3939
13
+ markdown_convert-1.2.40.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
14
+ markdown_convert-1.2.40.dist-info/entry_points.txt,sha256=RCmzC7C0sX-SpzIP2Cr34rhg3lMd7BRx-exaZPfK8bU,68
15
+ markdown_convert-1.2.40.dist-info/licenses/LICENSE,sha256=gXf5dRMhNSbfLPYYTY_5hsZ1r7UU1OaKQEAQUhuIBkM,18092
16
+ markdown_convert-1.2.40.dist-info/RECORD,,