|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing some Markdown extensions. |
|
8 """ |
|
9 |
|
10 import re |
|
11 |
|
12 from markdown.extensions import Extension |
|
13 from markdown.preprocessors import Preprocessor |
|
14 |
|
15 from markdown.inlinepatterns import SimpleTagInlineProcessor |
|
16 |
|
17 ###################################################################### |
|
18 ## Code below is an enhanced copy of the Mermaid extension |
|
19 ## |
|
20 ## Original code Copyright 2018-2020 [Olivier Ruelle] |
|
21 ## License: GNU GPLv3 |
|
22 ###################################################################### |
|
23 |
|
24 MermaidRegex = re.compile( |
|
25 r"^(?P<mermaid_sign>[\~\`]){3}[ \t]*[Mm]ermaid[ \t]*$" |
|
26 ) |
|
27 MermaidRegexFullText = re.compile( |
|
28 r"([\~\`]){3}[ \t]*[Mm]ermaid" |
|
29 ) |
|
30 |
|
31 |
|
32 class MermaidPreprocessor(Preprocessor): |
|
33 """ |
|
34 Class implementing a markdown pre-processor for Mermaid. |
|
35 """ |
|
36 def run(self, lines): |
|
37 """ |
|
38 Public method to do the pre-processing. |
|
39 |
|
40 @param lines text lines to be processed |
|
41 @type list of str |
|
42 @return processed lines |
|
43 @rtype list of str |
|
44 """ |
|
45 new_lines = [] |
|
46 mermaid_sign = "" |
|
47 m_start = None |
|
48 m_end = None |
|
49 in_mermaid_code = False |
|
50 is_mermaid = False |
|
51 old_line = "" |
|
52 for line in lines: |
|
53 # Wait for starting line with MermaidRegex |
|
54 # (~~~ or ``` following by [mM]ermaid ) |
|
55 if not in_mermaid_code: |
|
56 m_start = MermaidRegex.match(line) |
|
57 else: |
|
58 m_end = re.match(r"^[" + mermaid_sign + "]{3}[ \t]*$", line) |
|
59 if m_end: |
|
60 in_mermaid_code = False |
|
61 |
|
62 if m_start: |
|
63 in_mermaid_code = True |
|
64 mermaid_sign = m_start.group("mermaid_sign") |
|
65 if not re.match(r"^[\ \t]*$", old_line): |
|
66 new_lines.append("") |
|
67 if not is_mermaid: |
|
68 is_mermaid = True |
|
69 new_lines.append('<div class="mermaid">') |
|
70 m_start = None |
|
71 elif m_end: |
|
72 new_lines.append('</div>') |
|
73 new_lines.append("") |
|
74 m_end = None |
|
75 elif in_mermaid_code: |
|
76 new_lines.append( |
|
77 line.strip() |
|
78 .replace("<", "<") |
|
79 .replace(">", ">") |
|
80 ) |
|
81 else: |
|
82 |
|
83 new_lines.append(line) |
|
84 |
|
85 old_line = line |
|
86 |
|
87 if is_mermaid: |
|
88 new_lines.append('') |
|
89 new_lines.append( |
|
90 '<script>mermaid.initialize({startOnLoad:true});</script>' |
|
91 ) |
|
92 |
|
93 return new_lines |
|
94 |
|
95 |
|
96 class MermaidExtension(Extension): |
|
97 """ |
|
98 Class implementing a Markdown Extension for Mermaid. |
|
99 """ |
|
100 def extendMarkdown(self, md, md_globals): |
|
101 """ |
|
102 Public method to register the extension. |
|
103 |
|
104 @param md reference to markdown |
|
105 @param md_globals global config parameters |
|
106 """ |
|
107 md.preprocessors.register(MermaidPreprocessor(md), 'mermaid', 35) |
|
108 md.registerExtension(self) |
|
109 |
|
110 ###################################################################### |
|
111 ## Some extension to some basic additions |
|
112 ###################################################################### |
|
113 |
|
114 |
|
115 class SimplePatternExtension(Extension): |
|
116 """ |
|
117 Class implementing a Markdown extension for ~, ~~, ^, ^^ and ==. |
|
118 |
|
119 Note: This is a very simple pattern extension that might conflict with |
|
120 formulas set for MathJax. Use the 'pymdown-extensions' package in this |
|
121 case. |
|
122 """ |
|
123 DEL_RE = r'(~~)(.+?)~~' |
|
124 SUB_RE = r'(~)(.+?)~' |
|
125 INS_RE = r'(\^\^)(.*?)\^\^' |
|
126 SUP_RE = r'(\^)(.*?)\^' |
|
127 MARK_RE = r'(==)(.*?)==' |
|
128 |
|
129 def extendMarkdown(self, md): |
|
130 """ |
|
131 Public method to register the extension. |
|
132 |
|
133 @param md reference to markdown |
|
134 """ |
|
135 md.inlinePatterns.register( |
|
136 SimpleTagInlineProcessor(self.SUB_RE, 'sub'), 'subscript', 30) |
|
137 md.inlinePatterns.register( |
|
138 SimpleTagInlineProcessor(self.DEL_RE, 'del'), 'deleted', 40) |
|
139 md.inlinePatterns.register( |
|
140 SimpleTagInlineProcessor(self.SUP_RE, 'sup'), 'superscript', 30) |
|
141 md.inlinePatterns.register( |
|
142 SimpleTagInlineProcessor(self.INS_RE, 'ins'), 'inserted', 40) |
|
143 md.inlinePatterns.register( |
|
144 SimpleTagInlineProcessor(self.MARK_RE, 'mark'), 'mark', 40) |