-
Notifications
You must be signed in to change notification settings - Fork 12
/
markdown_preview.py
83 lines (65 loc) · 2.87 KB
/
markdown_preview.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Copyright (C) 2022 - 2023 Alessandro Iepure
#
# SPDX-License-Identifier: GPL-3.0-or-later
from gi.repository import Gio, GObject
import markdown2
class MarkdownPreviewService():
def __init__(self):
self._cancellable = Gio.Cancellable()
self._html_file = Gio.File.new_tmp("me.iepure.devtoolbox.XXXXXX")[0]
def set_markdown(self, markdown:str):
self._markdown = markdown
def get_cancellable(self) -> Gio.Cancellable:
return self._cancellable
def async_finish(self, result:Gio.AsyncResult, caller:GObject.Object):
if not Gio.Task.is_valid(result, caller):
return -1
self._markdown = None
return result.propagate_value().value
def get_html_file_path(self):
return self._html_file.get_path()
def build_html_from_markdown_async(self, caller:GObject.Object, callback:callable):
task = Gio.Task.new(caller, None, callback, self._cancellable)
task.set_return_on_cancel(True)
task.run_in_thread(self.build_html_from_markdown_thread)
def build_html_from_markdown_thread(self, task:Gio.Task, source_object:GObject.Object, task_data:object, cancelable:Gio.Cancellable):
if task.return_error_if_cancelled():
return
outcome = self.build_html_from_markdown(self._markdown)
task.return_value(outcome)
def build_html_from_markdown(self, markdown_str:str):
self._markdown_css = ""
self._code_colors = ""
self._scrollpos_script = ""
if not self._markdown_css:
gfile = Gio.File.new_for_uri("resource:///me/iepure/devtoolbox/markdown-preview/github-markdown-dark.css")
self._markdown_css = gfile.load_contents(None)[1].decode("utf-8")
if not self._code_colors:
gfile = Gio.File.new_for_uri("resource:///me/iepure/devtoolbox/markdown-preview/fenced-code-colors.css")
self._code_colors = gfile.load_contents(None)[1].decode("utf-8")
if not self._scrollpos_script:
gfile = Gio.File.new_for_uri("resource:///me/iepure/devtoolbox/markdown-preview/scrollpos-script.js")
self._scrollpos_script = gfile.load_contents(None)[1].decode("utf-8")
output = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
"""
output += self._markdown_css
output += self._code_colors
output += """</style>
<script>
"""
output += self._scrollpos_script
output += """</script>
</head>
<body class="markdown-body">
"""
output += markdown2.markdown(markdown_str, extras=["tables", "fenced-code-blocks", "header-ids", "smarty-pants", "cuddled-lists", "strike"])
output += """</body>
</html>
"""
with open(self._html_file.get_path(), "w", encoding="utf-8", errors="xmlcharrefreplace") as output_file:
output_file.write(output)
return self._html_file.get_path()