44
44
from io import StringIO
45
45
from contextlib import redirect_stdout
46
46
47
+
47
48
def printn (line ):
48
49
"""Shortcut to print without new line"""
49
50
print (line , end = "" )
50
51
52
+
51
53
class CodeBlock :
52
54
"""The code block
53
55
@@ -73,70 +75,70 @@ class CodeBlock:
73
75
stdout: The standard output of current code piece
74
76
It will get overwritten by next code piece
75
77
"""
78
+
76
79
def __init__ (self , indent , backticks , lang , index , envs = None ):
77
80
self .indent = indent
78
81
self .backticks = backticks
79
82
self .lang = lang
80
- self .codes = ''
83
+ self .codes = ""
81
84
self .envs = envs or {}
82
- self .produced = ''
85
+ self .produced = ""
83
86
self .alive = True
84
87
self .index = index
85
88
self .piece = 0
86
- self .stdout = ''
89
+ self .stdout = ""
87
90
88
91
def compile_exec (self , code ):
89
92
"""Compile and execute the code"""
90
93
sourcefile = path .join (
91
94
tempfile ._get_default_tempdir (),
92
95
f"codeblock_{ self .index } _{ self .piece } -"
93
- f"{ next (tempfile ._get_candidate_names ())} "
96
+ f"{ next (tempfile ._get_candidate_names ())} " ,
94
97
)
95
- with open (sourcefile , 'w' ) as fsrc :
98
+ with open (sourcefile , "w" ) as fsrc :
96
99
fsrc .write (code )
97
- code = compile (code , sourcefile , mode = ' exec' )
100
+ code = compile (code , sourcefile , mode = " exec" )
98
101
sio = StringIO ()
99
102
with redirect_stdout (sio ):
100
103
exec (code , self .envs )
101
104
self .stdout = sio .getvalue ()
102
105
self .piece += 1
103
106
104
-
105
107
def feed (self , line ):
106
108
"""Feed a single line to the code block, with line break"""
107
- if self .lang not in (' python' , ' python3' ):
109
+ if self .lang not in (" python" , " python3" ):
108
110
self .produced += line
109
111
110
112
else :
111
- if not line .strip (): # empty line
113
+ if not line .strip (): # empty line
112
114
self .codes += "\n "
113
115
self .produced += line
114
116
else :
115
- line = line [len (self .indent ):]
117
+ line = line [len (self .indent ) :]
116
118
if CodeBlock .should_compile (line ):
117
119
if self .codes :
118
120
self .compile_exec (self .codes )
119
- self .codes = ''
121
+ self .codes = ""
120
122
self .produced += self .indent + self .compile_line (line )
121
123
else :
122
124
self .codes += line
123
125
self .produced += self .indent + line
124
126
125
127
def _compile_expr (self , line ):
126
128
"""Compile {_expr}"""
127
- varname = ' _expr'
128
- source = f' { varname } = { line } '
129
+ varname = " _expr"
130
+ source = f" { varname } = { line } "
129
131
self .compile_exec (source )
130
- code , comment = line .split ('#' , 1 )
132
+ code , comment = line .split ("#" , 1 )
131
133
comment = comment .format (** self .envs )
132
- return '#' .join ((code , comment ))
134
+ return "#" .join ((code , comment ))
133
135
134
136
def _compile_out (self , line ):
135
137
"""Compile {_out}"""
136
138
self .compile_exec (line )
137
- code , comment = line .split ('#' , 1 )
139
+ code , comment = line .split ("#" , 1 )
138
140
comment = comment .format (** self .envs , _out = self .stdout )
139
- return '#' .join ((code , comment ))
141
+ return "#" .join ((code , comment ))
140
142
141
143
def _compile_exc (self , line , msg = False ):
142
144
"""Compile {_exc} and {_exc_msg}"""
@@ -153,36 +155,36 @@ def _compile_exc(self, line, msg=False):
153
155
source += " + ': ' + str(exc)"
154
156
source += "\n "
155
157
self .compile_exec (source )
156
- code , comment = line .split ('#' , 1 )
158
+ code , comment = line .split ("#" , 1 )
157
159
comment = comment .format (** self .envs )
158
- return '#' .join ((code , comment ))
160
+ return "#" .join ((code , comment ))
159
161
160
162
def _compile_hidden (self , line ):
161
163
"""Compile {_hidden}"""
162
164
self .compile_exec (line )
163
- return ''
165
+ return ""
164
166
165
167
def _compile_var (self , line ):
166
168
"""Compile variables"""
167
169
self .compile_exec (line )
168
- code , comment = line .split ('#' , 1 )
170
+ code , comment = line .split ("#" , 1 )
169
171
comment = comment .format (** self .envs )
170
- return '#' .join ((code , comment ))
172
+ return "#" .join ((code , comment ))
171
173
172
174
def compile_line (self , line ):
173
175
"""Compile a single line"""
174
- code , comment = line .split ('#' , 1 )
176
+ code , comment = line .split ("#" , 1 )
175
177
if not code :
176
- return '#' + comment .format (** self .envs , _out = self .stdout )
177
- if ' {_hidden}' in comment :
178
+ return "#" + comment .format (** self .envs , _out = self .stdout )
179
+ if " {_hidden}" in comment :
178
180
return self ._compile_hidden (line )
179
- if re .search (r' \{_expr(?:!\w+)?\}' , comment ):
181
+ if re .search (r" \{_expr(?:!\w+)?\}" , comment ):
180
182
return self ._compile_expr (line )
181
- if re .search (r' \{_out(?:!\w+)?\}' , comment ):
183
+ if re .search (r" \{_out(?:!\w+)?\}" , comment ):
182
184
return self ._compile_out (line )
183
- if ' {_exc}' in comment :
185
+ if " {_exc}" in comment :
184
186
return self ._compile_exc (line )
185
- if ' {_exc_msg}' in comment :
187
+ if " {_exc_msg}" in comment :
186
188
return self ._compile_exc (line , msg = True )
187
189
188
190
return self ._compile_var (line )
@@ -207,7 +209,9 @@ def try_open(cls, line, envs, index):
207
209
return None
208
210
209
211
indent , backticks , lang = (
210
- matches .group (1 ), matches .group (2 ), matches .group (3 ),
212
+ matches .group (1 ),
213
+ matches .group (2 ),
214
+ matches .group (3 ),
211
215
)
212
216
return cls (indent , backticks , lang , index , envs )
213
217
@@ -218,19 +222,19 @@ def close(self, line):
218
222
self .alive = False
219
223
if self .codes :
220
224
self .compile_exec (self .codes )
221
- self .codes = ''
225
+ self .codes = ""
222
226
return True
223
227
224
228
return False
225
229
226
230
@staticmethod
227
231
def should_compile (line ):
228
232
"""Whether we should compile a line or treat it as a plain line"""
229
- if '#' not in line :
233
+ if "#" not in line :
230
234
return False
231
235
232
- comment = line .split ('#' , 1 )[1 ]
233
- return re .search (r' \{[^}]+\}' , comment )
236
+ comment = line .split ("#" , 1 )[1 ]
237
+ return re .search (r" \{[^}]+\}" , comment )
234
238
235
239
236
240
def compile_readme (rawfile ):
@@ -254,6 +258,7 @@ def compile_readme(rawfile):
254
258
if maybe_codeblock :
255
259
codeblock = maybe_codeblock
256
260
261
+
257
262
if __name__ == "__main__" :
258
263
if len (sys .argv ) < 2 :
259
264
print ("Usage: make-readme.py README.raw.md > README.md" )
0 commit comments