Skip to content

Commit bbd479b

Browse files
authored
Merge pull request #247 from EgorDm/feature/md-equations
Added conversion support for markdown equations.
2 parents 34b8729 + faa9ee8 commit bbd479b

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

notion/markdown.py

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import commonmark
22
import re
3+
import html
4+
from xml.dom import minidom
35

46
from commonmark.dump import prepare
57

@@ -69,16 +71,20 @@
6971
"\u3000",
7072
}
7173

72-
_NOTION_TO_MARKDOWN_MAPPER = {"i": "☃", "b": "☃☃", "s": "~~", "c": "`"}
74+
_NOTION_TO_MARKDOWN_MAPPER = {"i": "☃", "b": "☃☃", "s": "~~", "c": "`", "e": "$$"}
7375

74-
FORMAT_PRECEDENCE = ["s", "b", "i", "a", "c"]
76+
FORMAT_PRECEDENCE = ["s", "b", "i", "a", "c", "e"]
7577

7678

7779
def _extract_text_and_format_from_ast(item):
7880

7981
if item["type"] == "html_inline":
8082
if item.get("literal", "") == "<s>":
8183
return "", ("s",)
84+
if item.get("literal", "").startswith('<latex'):
85+
elem = minidom.parseString(item.get("literal", "") + '</latex>').documentElement
86+
equation = elem.attributes['equation'].value
87+
return "", ("e", equation)
8288

8389
if item["type"] == "emph":
8490
return item.get("literal", ""), ("i",)
@@ -118,6 +124,11 @@ def markdown_to_notion(markdown):
118124
markdown = markdown.replace("~~", "<s>", 1)
119125
markdown = markdown.replace("~~", "</s>", 1)
120126

127+
# commonmark doesn't support latex blocks, so we need to handle it ourselves
128+
def handle_latex(match):
129+
return f'<latex equation="{html.escape(match.group(0)[2:-2])}">\u204d</latex>'
130+
markdown = re.sub(r'(?<!\\\\|\$\$)(?:\\\\)*((\$\$)+)(?!(\$\$))(.+?)(?<!(\$\$))\1(?!(\$\$))', handle_latex, markdown)
131+
121132
# we don't want to touch dashes, so temporarily replace them here
122133
markdown = markdown.replace("-", "⸻")
123134

@@ -148,6 +159,12 @@ def markdown_to_notion(markdown):
148159
format.remove(("s",))
149160
literal = ""
150161

162+
if item["type"] == "html_inline" and literal == "</latex>":
163+
for f in filter(lambda f: f[0] == 'e', format):
164+
format.remove(f)
165+
break
166+
literal = ""
167+
151168
if item["type"] == "softbreak":
152169
literal = "\n"
153170

@@ -227,7 +244,15 @@ def notion_to_markdown(notion):
227244
if f[0] == "a":
228245
markdown += "["
229246

230-
markdown += stripped
247+
# Check wheter a format modifies the content
248+
content_changed = False
249+
for f in sorted_format:
250+
if f[0] == 'e':
251+
markdown += f[1]
252+
content_changed = True
253+
254+
if not content_changed:
255+
markdown += stripped
231256

232257
for f in reversed(sorted_format):
233258
if f[0] in _NOTION_TO_MARKDOWN_MAPPER:

0 commit comments

Comments
 (0)