1
1
import re
2
- from xml .etree .ElementTree import ElementTree , SubElement
2
+ from xml .etree .ElementTree import Element , SubElement
3
3
4
4
from django .conf import settings
5
5
from markdown import Extension , Markdown
9
9
10
10
11
11
class SchoolImageTreeprocessor (Treeprocessor ):
12
- def run (self , root : ElementTree ):
12
+ def run (self , root : Element ):
13
13
for elem in root .iter ("img" ):
14
14
image_url = elem .get ("src" )
15
15
if image_url is None :
@@ -35,7 +35,7 @@ def run(self, root: ElementTree):
35
35
36
36
37
37
class CodeBlocksProcessor (Preprocessor ):
38
- def run (self , lines ) -> list [str ]:
38
+ def run (self , lines : list [ str ] ) -> list [str ]:
39
39
new_lines = []
40
40
inside = 0
41
41
for line in lines :
@@ -45,29 +45,37 @@ def run(self, lines) -> list[str]:
45
45
46
46
if line == "```vstup" :
47
47
new_lines .append ("<io>" )
48
- # new_lines.append("### Vstup ")
48
+ new_lines .append ("<io:input> " )
49
49
new_lines .append ("```" )
50
50
inside = 1
51
51
elif line == "```vystup" :
52
- # new_lines.append("### Výstup ")
52
+ new_lines .append ("<io:output> " )
53
53
new_lines .append ("```" )
54
- inside = 2
55
- elif line == "```" and inside == 2 :
54
+ inside = 3
55
+ elif line == "```" :
56
56
new_lines .append ("```" )
57
- new_lines .append ("</io>" )
58
- inside = 0
57
+ if inside == 3 :
58
+ new_lines .append ("</io:output>\n " )
59
+ new_lines .append ("</io>" )
60
+ inside = 0
61
+ elif inside == 1 :
62
+ new_lines .append ("</io:input>\n " )
63
+ inside = 2
59
64
else :
60
65
new_lines .append (line )
61
66
return new_lines
62
67
63
68
64
- class BoxBlockProcessor (BlockProcessor ):
65
- RE_FENCE_START = r"<io>"
66
- RE_FENCE_END = r"</io>"
69
+ class FencedBlockProcessor (BlockProcessor ):
70
+ RE_FENCE_START : str
71
+ RE_FENCE_END : str
67
72
68
- def test (self , parent , block ) -> bool :
73
+ def test (self , parent : Element , block : str ) -> bool :
69
74
return re .match (self .RE_FENCE_START , block ) is not None
70
75
76
+ def fence_logic (self , parent : Element , blocks : list [str ]) -> None :
77
+ raise NotImplementedError ()
78
+
71
79
def run (self , parent , blocks ):
72
80
original_block = blocks [0 ]
73
81
blocks [0 ] = re .sub (self .RE_FENCE_START , "" , blocks [0 ])
@@ -77,26 +85,60 @@ def run(self, parent, blocks):
77
85
if re .search (self .RE_FENCE_END , block ):
78
86
# remove fence
79
87
blocks [block_num ] = re .sub (self .RE_FENCE_END , "" , block )
80
- # render fenced area inside a new div
81
- e = SubElement (parent , "div" )
82
- e .set ("class" , "io" )
83
- inp = SubElement (e , "h3" )
84
- inp .text = "Vstup"
85
- out = SubElement (e , "h3" )
86
- out .text = "Výstup"
87
-
88
- self .parser .parseBlocks (e , blocks [0 : block_num + 1 ])
88
+
89
+ self .fence_logic (parent , blocks [0 : block_num + 1 ])
90
+
89
91
# remove used blocks
90
- for i in range (0 , block_num + 1 ):
92
+ for _ in range (0 , block_num + 1 ):
91
93
blocks .pop (0 )
92
94
return True # or could have had no return statement
93
95
# No closing marker! Restore and do nothing
94
96
blocks [0 ] = original_block
95
97
return False # equivalent to our test() routine returning False
96
98
97
99
100
+ class BoxBlockProcessor (FencedBlockProcessor ):
101
+ RE_FENCE_START = r"<io>"
102
+ RE_FENCE_END = r"</io>"
103
+
104
+ def fence_logic (self , parent , blocks ):
105
+ d = SubElement (parent , "div" )
106
+ d .set ("class" , "io" )
107
+ self .parser .parseBlocks (d , blocks )
108
+
109
+
110
+ class IOInputBlockProcessor (FencedBlockProcessor ):
111
+ RE_FENCE_START = r"<io:input>"
112
+ RE_FENCE_END = r"</io:input>"
113
+
114
+ def fence_logic (self , parent , blocks ):
115
+ d = SubElement (parent , "div" )
116
+ inp = SubElement (d , "h3" )
117
+ inp .text = "Vstup"
118
+ self .parser .parseBlocks (d , blocks )
119
+
120
+
121
+ class IOOutputBlockProcessor (FencedBlockProcessor ):
122
+ RE_FENCE_START = r"<io:output>"
123
+ RE_FENCE_END = r"</io:output>"
124
+
125
+ def fence_logic (self , parent , blocks ):
126
+ d = SubElement (parent , "div" )
127
+ inp = SubElement (d , "h3" )
128
+ inp .text = "Výstup"
129
+ self .parser .parseBlocks (d , blocks )
130
+
131
+
98
132
class KspSchoolExtension (Extension ):
99
133
def extendMarkdown (self , md : Markdown ) -> None : # noqa: N802
100
134
md .treeprocessors .register (SchoolImageTreeprocessor (md ), "ksp_school_images" , 0 )
101
135
md .preprocessors .register (CodeBlocksProcessor (md ), "IO_code_blocks" , 100000 )
102
- md .parser .blockprocessors .register (BoxBlockProcessor (md .parser ), "box" , 100000 )
136
+ md .parser .blockprocessors .register (
137
+ BoxBlockProcessor (md .parser ), "IO_box" , 100000
138
+ )
139
+ md .parser .blockprocessors .register (
140
+ IOInputBlockProcessor (md .parser ), "IO_input" , 100000
141
+ )
142
+ md .parser .blockprocessors .register (
143
+ IOOutputBlockProcessor (md .parser ), "IO_output" , 100000
144
+ )
0 commit comments