markdown_convert 1.2.43__tar.gz → 1.2.45__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: markdown_convert
3
- Version: 1.2.43
3
+ Version: 1.2.45
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>
@@ -59,6 +59,8 @@ Unlike other similar tools, `markdown-convert`:
59
59
  - **Custom CSS** `markdown-convert file.md --css=style.css` extends the default CSS with your own stylesheet.
60
60
  - **Pipe tables, checkboxes, header links, CSS paged media features and more!**
61
61
 
62
+ Check out [CUSTOM_SYNTAX.md](https://github.com/Julynx/markdown_convert/blob/main/CUSTOM_SYNTAX.md) for all the extra features and how to use them.
63
+
62
64
  ## Installation
63
65
 
64
66
  `markdown-convert` is available on PyPI and can be installed via pip:
@@ -39,6 +39,8 @@ Unlike other similar tools, `markdown-convert`:
39
39
  - **Custom CSS** `markdown-convert file.md --css=style.css` extends the default CSS with your own stylesheet.
40
40
  - **Pipe tables, checkboxes, header links, CSS paged media features and more!**
41
41
 
42
+ Check out [CUSTOM_SYNTAX.md](https://github.com/Julynx/markdown_convert/blob/main/CUSTOM_SYNTAX.md) for all the extra features and how to use them.
43
+
42
44
  ## Installation
43
45
 
44
46
  `markdown-convert` is available on PyPI and can be installed via pip:
@@ -329,3 +329,74 @@ math {
329
329
  text-rendering: optimizeLegibility;
330
330
  font-family: "Latin Modern Math", "Cambria Math", serif;
331
331
  }
332
+
333
+ /* Classes for custom containers */
334
+ .red,
335
+ .r {
336
+ color: red;
337
+ }
338
+
339
+ .green,
340
+ .g {
341
+ color: green;
342
+ }
343
+
344
+ .blue,
345
+ .b {
346
+ color: blue;
347
+ }
348
+
349
+ .yellow {
350
+ color: goldenrod;
351
+ }
352
+
353
+ .orange {
354
+ color: orange;
355
+ }
356
+
357
+ .purple {
358
+ color: purple;
359
+ }
360
+
361
+ .white {
362
+ color: white;
363
+ }
364
+
365
+ .black {
366
+ color: black;
367
+ }
368
+
369
+ .gray {
370
+ color: gray;
371
+ }
372
+
373
+ .brown {
374
+ color: brown;
375
+ }
376
+
377
+ .pink {
378
+ color: pink;
379
+ }
380
+
381
+ .underline,
382
+ .u {
383
+ text-decoration: underline;
384
+ }
385
+
386
+ .highlight,
387
+ .hl {
388
+ background-color: yellow;
389
+ }
390
+
391
+ .keyboard,
392
+ .key {
393
+ font-family:
394
+ "Segoe UI Symbol", "DejaVu Sans", "Liberation Sans", "Arial",
395
+ "sans-serif";
396
+ font-size: 0.9rem;
397
+ background-color: var(--color-text-background);
398
+ border: 1px solid var(--color-border);
399
+ border-radius: 0.3em;
400
+ padding: 0.1em 0.4em;
401
+ box-shadow: rgba(100, 100, 100, 0.4) 0px 2px 4px 0px;
402
+ }
@@ -19,6 +19,7 @@ from .transform import (
19
19
  render_mermaid_diagrams,
20
20
  create_html_document,
21
21
  render_checkboxes,
22
+ create_spans,
22
23
  )
23
24
  from .utils import drop_duplicates
24
25
 
@@ -135,6 +136,7 @@ def convert(
135
136
  html = create_sections(html)
136
137
  html = render_mermaid_diagrams(html, nonce=nonce)
137
138
  html = render_checkboxes(html)
139
+ html = create_spans(html)
138
140
 
139
141
  _generate_pdf_with_playwright(
140
142
  html,
@@ -206,6 +208,7 @@ def convert_text(markdown_text, css_text=None, *, extend_default_css=True):
206
208
  html = create_sections(html)
207
209
  html = render_mermaid_diagrams(html, nonce=nonce)
208
210
  html = render_checkboxes(html)
211
+ html = create_spans(html)
209
212
 
210
213
  return _generate_pdf_with_playwright(
211
214
  html,
@@ -110,3 +110,56 @@ def render_checkboxes(html):
110
110
  parts[part_index] = parts[part_index].replace(checked, checked_html)
111
111
 
112
112
  return "".join(parts)
113
+
114
+
115
+ def create_spans(html):
116
+ """
117
+ Renders custom spans in the HTML content by replacing classname{{ content }} tags.
118
+ Args:
119
+ html (str): HTML content.
120
+ Returns:
121
+ str: HTML content with rendered custom spans.
122
+ """
123
+ soup = BeautifulSoup(html, "html.parser")
124
+
125
+ # Regex to match classname{{ content }}
126
+ # It captures the class name and the content
127
+ pattern = re.compile(r"([a-zA-Z0-9_-]+){{\s*(.*?)\s*}}")
128
+
129
+ # We need to find all text nodes and replace the pattern
130
+ for text_node in soup.find_all(string=True):
131
+ # Skip text nodes inside code, pre, script, style tags
132
+ if text_node.parent.name in ["code", "pre", "script", "style"]:
133
+ continue
134
+
135
+ content = str(text_node)
136
+ if "{{" in content:
137
+ new_content_nodes = []
138
+ last_end = 0
139
+ for match in pattern.finditer(content):
140
+ # Add text before the match
141
+ before = content[last_end : match.start()]
142
+ if before:
143
+ new_content_nodes.append(soup.new_string(before))
144
+
145
+ # Create the new span tag
146
+ class_name = match.group(1)
147
+ inner_text = match.group(2)
148
+ new_span = soup.new_tag("span", attrs={"class": class_name})
149
+ new_span.string = inner_text
150
+ new_content_nodes.append(new_span)
151
+
152
+ last_end = match.end()
153
+
154
+ # Add remaining text after the last match
155
+ after = content[last_end:]
156
+ if after:
157
+ new_content_nodes.append(soup.new_string(after))
158
+
159
+ if new_content_nodes:
160
+ # Replace the original text node with the new nodes
161
+ for node in reversed(new_content_nodes):
162
+ text_node.insert_after(node)
163
+ text_node.extract()
164
+
165
+ return str(soup)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "markdown_convert"
7
- version = "1.2.43"
7
+ version = "1.2.45"
8
8
  description = "Convert Markdown files to PDF from your command line."
9
9
  authors = [
10
10
  { name = "Julio Cabria", email = "juliocabria@tutanota.com" },