vite/vite.py.html (view raw)
1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2<html>
3<head>
4<meta http-equiv="content-type" content="text/html; charset=UTF-8">
5<title>~/code/vite/vite/vite.py.html</title>
6<meta name="Generator" content="Vim/8.0">
7<meta name="plugin-version" content="vim8.1_v1">
8<meta name="syntax" content="python">
9<meta name="settings" content="use_css,no_foldcolumn,expand_tabs,prevent_copy=">
10<meta name="colorscheme" content="darkblue">
11<style type="text/css">
12<!--
13pre { font-family: monospace; color: #a8a8a8; background-color: #000000; }
14body { font-family: monospace; color: #a8a8a8; background-color: #000000; }
15* { font-size: 1em; }
16.Type { color: #00ff00; }
17.Identifier { color: #00ffff; }
18.Statement { color: #ffff00; }
19.PreProc { color: #ff40ff; }
20.Comment { color: #c00000; }
21.Constant { color: #ff40ff; }
22.Special { color: #af5f00; }
23-->
24</style>
25</head>
26<body>
27<pre id='vimCodeElement'>
28<span class="Comment"># vite - a simple and minimal static site generator, that JustWorks™</span>
29<span class="Comment"># Copyright (c) 2020 Anirudh Oppiliappan <x@icyphox.sh></span>
30<span class="Comment"># Licensed under the MIT license</span>
31
32<span class="PreProc">import</span> sys
33<span class="PreProc">import</span> pathlib
34<span class="PreProc">import</span> os
35<span class="PreProc">import</span> jinja2
36<span class="PreProc">import</span> time
37<span class="PreProc">import</span> http.server
38<span class="PreProc">import</span> socketserver
39<span class="PreProc">import</span> shutil
40<span class="PreProc">import</span> datetime
41<span class="PreProc">import</span> re
42
43<span class="PreProc">from</span> myrkdown <span class="PreProc">import</span> markdown_path
44<span class="PreProc">from</span> huepy <span class="PreProc">import</span> *
45<span class="PreProc">from</span> livereload <span class="PreProc">import</span> Server
46<span class="PreProc">from</span> subprocess <span class="PreProc">import</span> call
47
48
49<span class="Comment"># constants</span>
50PAGES_PATH = <span class="Constant">"</span><span class="Constant">pages/</span><span class="Constant">"</span>
51BUILD_PATH = <span class="Constant">"</span><span class="Constant">build/</span><span class="Constant">"</span>
52TEMPL_PATH = <span class="Constant">"</span><span class="Constant">templates/</span><span class="Constant">"</span>
53TEMPL_FILE = <span class="Constant">""</span>
54PORT = <span class="Constant">1911</span>
55
56
57<span class="Statement">def</span> <span class="Identifier">import_config</span>():
58 <span class="Statement">try</span>:
59 sys.path.append(os.getcwd())
60 <span class="Identifier">globals</span>()[<span class="Constant">"</span><span class="Constant">config</span><span class="Constant">"</span>] = <span class="Identifier">__import__</span>(<span class="Constant">"</span><span class="Constant">config</span><span class="Constant">"</span>)
61 <span class="Statement">global</span> TEMPL_FILE
62 TEMPL_FILE = os.path.join(TEMPL_PATH, config.template)
63 <span class="Statement">except</span> <span class="Type">ImportError</span>:
64 <span class="Identifier">print</span>(bad(<span class="Constant">"</span><span class="Constant">Error: config.py not found.</span><span class="Constant">"</span>))
65 <span class="Identifier">print</span>(que(<span class="Constant">"</span><span class="Constant">Are you sure you're in a project directory?</span><span class="Constant">"</span>))
66 sys.exit(<span class="Constant">1</span>)
67
68
69<span class="Statement">def</span> <span class="Identifier">create_project</span>(path):
70 <span class="Statement">try</span>:
71 abs_path = pathlib.Path(path).resolve()
72 cur_path = pathlib.Path(<span class="Constant">"</span><span class="Constant">.</span><span class="Constant">"</span>).resolve()
73 os.makedirs(os.path.join(path, <span class="Constant">"</span><span class="Constant">build</span><span class="Constant">"</span>))
74 os.mkdir(os.path.join(path, <span class="Constant">"</span><span class="Constant">pages</span><span class="Constant">"</span>))
75 os.mkdir(os.path.join(path, <span class="Constant">"</span><span class="Constant">templates</span><span class="Constant">"</span>))
76 os.mkdir(os.path.join(path, <span class="Constant">"</span><span class="Constant">static</span><span class="Constant">"</span>))
77 create_config(path)
78 create_template(path)
79 <span class="Identifier">print</span>(good(<span class="Constant">"</span><span class="Constant">Created project directory at %s.</span><span class="Constant">"</span> % (abs_path)))
80 <span class="Statement">except</span> <span class="Type">FileExistsError</span>:
81 <span class="Identifier">print</span>(bad(<span class="Constant">"</span><span class="Constant">Error: specified path exists.</span><span class="Constant">"</span>))
82
83
84<span class="Statement">def</span> <span class="Identifier">create_path</span>(path):
85 head, tail = os.path.split(path)
86 now = datetime.datetime.now()
87 today = now.strftime(<span class="Constant">"</span><span class="Constant">%Y-%m-%d</span><span class="Constant">"</span>)
88 url = os.path.splitext(os.path.basename(path))[<span class="Constant">0</span>]
89
90 <span class="Statement">try</span>:
91 os.makedirs(os.path.join(PAGES_PATH, head))
92 <span class="Statement">except</span> <span class="Type">FileExistsError</span>:
93 <span class="Statement">pass</span>
94 <span class="Statement">if</span> os.path.exists(os.path.join(PAGES_PATH, head, tail)):
95 <span class="Identifier">print</span>(bad(<span class="Constant">"</span><span class="Constant">Error: specified path exists.</span><span class="Constant">"</span>))
96 <span class="Statement">else</span>:
97 <span class="Statement">with</span> <span class="Identifier">open</span>(os.path.join(PAGES_PATH, head, tail), <span class="Constant">"</span><span class="Constant">w</span><span class="Constant">"</span>) <span class="Statement">as</span> f:
98 to_write = (
99 <span class="Constant">"""</span><span class="Constant">---</span>
100<span class="Constant">template:</span>
101<span class="Constant">url: {u}</span>
102<span class="Constant">title:</span>
103<span class="Constant">subtitle:</span>
104<span class="Constant">date: {t}</span>
105<span class="Constant">---</span><span class="Special">\n</span><span class="Constant">"""</span>
106 ).format(t=today, u=url)
107 f.write(to_write)
108 <span class="Identifier">print</span>(good(<span class="Constant">"</span><span class="Constant">Created %s.</span><span class="Constant">"</span>) % (os.path.join(PAGES_PATH, head, tail)))
109
110
111<span class="Statement">def</span> <span class="Identifier">create_config</span>(path):
112 <span class="Statement">with</span> <span class="Identifier">open</span>(os.path.join(path, <span class="Constant">"</span><span class="Constant">config.py</span><span class="Constant">"</span>), <span class="Constant">"</span><span class="Constant">w</span><span class="Constant">"</span>) <span class="Statement">as</span> f:
113 f.write(
114 <span class="Constant">"""</span><span class="Constant"># config.py - Vite's configuration script</span>
115
116<span class="Constant">title = ''</span>
117<span class="Constant">author = ''</span>
118<span class="Constant">header = ''</span>
119<span class="Constant">footer = '' </span>
120<span class="Constant">pre_build = []</span>
121<span class="Constant">post_build = []</span>
122<span class="Constant">template = 'index.html' # default is index.html</span><span class="Special">\n</span><span class="Constant">"""</span>
123 )
124
125
126<span class="Statement">def</span> <span class="Identifier">create_template</span>(path):
127 <span class="Statement">with</span> <span class="Identifier">open</span>(os.path.join(path, <span class="Constant">"</span><span class="Constant">templates</span><span class="Constant">"</span>, <span class="Constant">"</span><span class="Constant">index.html</span><span class="Constant">"</span>), <span class="Constant">"</span><span class="Constant">w</span><span class="Constant">"</span>) <span class="Statement">as</span> f:
128 f.write(
129 <span class="Constant">"""</span><span class="Constant"><!DOCTYPE html></span>
130<span class="Constant"><html></span>
131<span class="Constant"><header></span>
132<span class="Constant"> {{ header }}</span>
133<span class="Constant"> <title></span>
134<span class="Constant"> {{ title }} </span>
135<span class="Constant"> </title></span>
136<span class="Constant"></header></span>
137
138<span class="Constant"><body></span>
139<span class="Constant"> {{ body }}</span>
140<span class="Constant"></body></span>
141
142<span class="Constant"><footer></span>
143<span class="Constant"> {{ footer }}</span>
144<span class="Constant"> <p> {{ author }} </p></span>
145<span class="Constant"><footer></span>
146
147<span class="Constant"> </span><span class="Constant">"""</span>
148 )
149
150
151<span class="Comment"># jinja2</span>
152<span class="Statement">def</span> <span class="Identifier">jinja_render</span>(html, tmpl):
153 template_loader = jinja2.FileSystemLoader(<span class="Constant">"</span><span class="Constant">./</span><span class="Constant">"</span>)
154 env = jinja2.Environment(loader=template_loader)
155 <span class="Statement">try</span>:
156 template = env.get_template(tmpl)
157 <span class="Statement">except</span> jinja2.exceptions.TemplateNotFound:
158 template = env.get_template(TEMPL_FILE)
159 meta = html.metadata
160 output = template.render(
161 title=meta[<span class="Constant">"</span><span class="Constant">title</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">title</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> config.title,
162 author=meta[<span class="Constant">"</span><span class="Constant">author</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">author</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> config.author,
163 header=meta[<span class="Constant">"</span><span class="Constant">header</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">header</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> config.header,
164 url=meta[<span class="Constant">"</span><span class="Constant">url</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">url</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> <span class="Constant">""</span>,
165 footer=meta[<span class="Constant">"</span><span class="Constant">footer</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">footer</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> config.footer,
166 date=meta[<span class="Constant">"</span><span class="Constant">date</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">date</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> <span class="Constant">""</span>,
167 subtitle=meta[<span class="Constant">"</span><span class="Constant">subtitle</span><span class="Constant">"</span>] <span class="Statement">if</span> <span class="Constant">"</span><span class="Constant">subtitle</span><span class="Constant">"</span> <span class="Statement">in</span> meta <span class="Statement">else</span> <span class="Constant">""</span>,
168 body=html,
169 )
170 <span class="Statement">return</span> output
171
172
173<span class="Statement">def</span> <span class="Identifier">fm_template</span>(metadata):
174 <span class="Statement">try</span>:
175 page_template = os.path.join(os.path.join(TEMPL_PATH, metadata[<span class="Constant">"</span><span class="Constant">template</span><span class="Constant">"</span>]))
176 <span class="Statement">except</span> <span class="Type">KeyError</span>:
177 page_template = TEMPL_FILE
178 <span class="Statement">return</span> page_template
179
180
181<span class="Statement">def</span> <span class="Identifier">markdown_render</span>(filename):
182 html = markdown_path(
183 os.path.join(PAGES_PATH, filename),
184 extras=[
185 <span class="Constant">"</span><span class="Constant">metadata</span><span class="Constant">"</span>,
186 <span class="Constant">"</span><span class="Constant">fenced-code-blocks</span><span class="Constant">"</span>,
187 <span class="Constant">"</span><span class="Constant">header-ids</span><span class="Constant">"</span>,
188 <span class="Constant">"</span><span class="Constant">footnotes</span><span class="Constant">"</span>,
189 <span class="Constant">"</span><span class="Constant">smarty-pants</span><span class="Constant">"</span>,
190 <span class="Constant">"</span><span class="Constant">tables</span><span class="Constant">"</span>,
191 <span class="Constant">"</span><span class="Constant">link-patterns</span><span class="Constant">"</span>,
192 ],
193 link_patterns=[
194 (
195 re.compile(
196 <span class="Constant">r"</span><span class="Constant">((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+(:[0-9]+)?|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)</span><span class="Constant">"</span>
197 ),
198 <span class="Constant">r"</span><span class="Constant">\1</span><span class="Constant">"</span>,
199 )
200 ],
201 )
202 <span class="Statement">return</span> html
203
204
205<span class="Statement">def</span> <span class="Identifier">html_gen</span>():
206 <span class="Statement">def</span> <span class="Identifier">index_render</span>(f, d=<span class="Constant">""</span>):
207 index_html = markdown_render(os.path.join(d, f))
208 output = jinja_render(index_html, fm_template(index_html.metadata))
209 <span class="Statement">with</span> <span class="Identifier">open</span>(os.path.join(BUILD_PATH, d, <span class="Constant">"</span><span class="Constant">index.html</span><span class="Constant">"</span>), <span class="Constant">"</span><span class="Constant">w</span><span class="Constant">"</span>) <span class="Statement">as</span> ff:
210 ff.write(output)
211 <span class="Statement">if</span> d:
212 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Rendered </span><span class="Constant">"</span> + white(<span class="Constant">"</span><span class="Constant">%s/%s</span><span class="Constant">"</span>) % (d, f)))
213 <span class="Statement">else</span>:
214 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Rendered </span><span class="Constant">"</span> + white(<span class="Constant">"</span><span class="Constant">%s</span><span class="Constant">"</span>) % (f)))
215
216 <span class="Statement">def</span> <span class="Identifier">normal_render</span>(f, d=<span class="Constant">""</span>):
217 html_text = markdown_render(os.path.join(d, f))
218 html_file = os.path.splitext(os.path.join(BUILD_PATH, d, f))[<span class="Constant">0</span>]
219 os.mkdir(html_file)
220 output = jinja_render(html_text, fm_template(html_text.metadata))
221 <span class="Statement">with</span> <span class="Identifier">open</span>(os.path.join(html_file, <span class="Constant">"</span><span class="Constant">index.html</span><span class="Constant">"</span>), <span class="Constant">"</span><span class="Constant">w</span><span class="Constant">"</span>) <span class="Statement">as</span> ff:
222 ff.write(output)
223 <span class="Statement">if</span> d:
224 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Rendered </span><span class="Constant">"</span> + white(<span class="Constant">"</span><span class="Constant">%s/%s</span><span class="Constant">"</span>) % (d, f)))
225 <span class="Statement">else</span>:
226 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Rendered </span><span class="Constant">"</span> + white(<span class="Constant">"</span><span class="Constant">%s</span><span class="Constant">"</span>) % (f)))
227
228 <span class="Statement">for</span> root, dirs, files <span class="Statement">in</span> os.walk(PAGES_PATH):
229 <span class="Statement">for</span> d <span class="Statement">in</span> dirs:
230 os.mkdir(os.path.join(BUILD_PATH, d))
231 <span class="Statement">for</span> f <span class="Statement">in</span> os.listdir(os.path.join(PAGES_PATH, d)):
232 <span class="Statement">if</span> os.path.splitext(f)[<span class="Constant">1</span>] != <span class="Constant">"</span><span class="Constant">.md</span><span class="Constant">"</span>:
233 shutil.copyfile(
234 os.path.join(PAGES_PATH, d, f), os.path.join(BUILD_PATH, d, f)
235 )
236 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Copied </span><span class="Constant">"</span> + white(<span class="Constant">"</span><span class="Constant">%s/%s</span><span class="Constant">"</span>) % (d, f)))
237 <span class="Statement">elif</span> f == <span class="Constant">"</span><span class="Constant">_index.md</span><span class="Constant">"</span>:
238 index_render(f, d)
239 <span class="Statement">else</span>:
240 normal_render(f, d)
241
242 <span class="Statement">for</span> f <span class="Statement">in</span> os.listdir(PAGES_PATH):
243 <span class="Statement">if</span> os.path.isfile(os.path.join(PAGES_PATH, f)):
244 <span class="Statement">if</span> os.path.splitext(f)[<span class="Constant">1</span>] != <span class="Constant">"</span><span class="Constant">.md</span><span class="Constant">"</span>:
245 shutil.copyfile(
246 os.path.join(PAGES_PATH, f), os.path.join(BUILD_PATH, f)
247 )
248 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Copied </span><span class="Constant">"</span> + white(<span class="Constant">"</span><span class="Constant">%s</span><span class="Constant">"</span>) % (f)))
249 <span class="Statement">elif</span> f == <span class="Constant">"</span><span class="Constant">_index.md</span><span class="Constant">"</span>:
250 index_render(f)
251 <span class="Statement">else</span>:
252 normal_render(f)
253
254
255<span class="Statement">def</span> <span class="Identifier">server</span>():
256 <span class="Comment"># handler = http.server.SimpleHTTPRequestHandler</span>
257 <span class="Comment"># os.chdir(os.path.join(os.getcwd(), BUILD_PATH))</span>
258 server = Server()
259 <span class="Statement">try</span>:
260 <span class="Identifier">print</span>(
261 run(
262 f<span class="Constant">'</span><span class="Constant">Serving the {italic(yellow("build"))} directory at {white(f"<a href="http://localhost:{PORT}">http://localhost:{PORT}</a>")}</span><span class="Constant">'</span>
263 )
264 )
265 <span class="Identifier">print</span>(white(<span class="Constant">"</span><span class="Constant">Ctrl+C</span><span class="Constant">"</span>) + <span class="Constant">"</span><span class="Constant"> to stop.</span><span class="Constant">"</span>)
266 server.serve(port=PORT, root=<span class="Constant">"</span><span class="Constant">build/</span><span class="Constant">"</span>)
267 <span class="Statement">except</span> <span class="Type">KeyboardInterrupt</span>:
268 <span class="Identifier">print</span>(info(<span class="Constant">"</span><span class="Constant">Stopping server.</span><span class="Constant">"</span>))
269 sys.exit(<span class="Constant">1</span>)
270
271
272<span class="Statement">def</span> <span class="Identifier">clean</span>():
273 <span class="Statement">for</span> root, dirs, files <span class="Statement">in</span> os.walk(BUILD_PATH):
274 <span class="Statement">for</span> f <span class="Statement">in</span> files:
275 os.unlink(os.path.join(root, f))
276 <span class="Statement">for</span> d <span class="Statement">in</span> dirs:
277 shutil.rmtree(os.path.join(root, d))
278
279
280<span class="Statement">def</span> <span class="Identifier">builder</span>():
281 path = os.getcwd()
282 start = time.process_time()
283 <span class="Statement">if</span> <span class="Statement">not</span> os.listdir(os.path.join(path, PAGES_PATH)):
284 <span class="Identifier">print</span>(info(italic(<span class="Constant">"</span><span class="Constant">pages</span><span class="Constant">"</span>) + <span class="Constant">"</span><span class="Constant"> directory is empty. Nothing to build.</span><span class="Constant">"</span>))
285 sys.exit(<span class="Constant">1</span>)
286 <span class="Statement">else</span>:
287 <span class="Statement">try</span>:
288 <span class="Statement">if</span> config.pre_build != <span class="Constant">""</span>:
289 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Running pre-build actions...</span><span class="Constant">"</span>))
290 <span class="Statement">for</span> s <span class="Statement">in</span> config.pre_build:
291 <span class="Identifier">print</span>(info(f<span class="Constant">"</span><span class="Constant">{s}</span><span class="Constant">"</span>))
292 call(s)
293 <span class="Statement">except</span> <span class="Type">AttributeError</span>:
294 <span class="Statement">pass</span>
295 clean()
296 html_gen()
297 <span class="Statement">if</span> os.path.exists(os.path.join(os.getcwd(), <span class="Constant">"</span><span class="Constant">static</span><span class="Constant">"</span>)):
298 shutil.copytree(
299 os.path.join(os.getcwd(), <span class="Constant">"</span><span class="Constant">static</span><span class="Constant">"</span>), os.path.join(BUILD_PATH, <span class="Constant">"</span><span class="Constant">static</span><span class="Constant">"</span>)
300 )
301 <span class="Statement">try</span>:
302 <span class="Statement">if</span> config.post_build != <span class="Constant">""</span>:
303 <span class="Identifier">print</span>(run(<span class="Constant">"</span><span class="Constant">Running post-build actions...</span><span class="Constant">"</span>))
304 <span class="Statement">for</span> s <span class="Statement">in</span> config.post_build:
305 <span class="Identifier">print</span>(info(f<span class="Constant">"</span><span class="Constant">{s}</span><span class="Constant">"</span>))
306 call([s])
307 <span class="Statement">except</span> <span class="Type">AttributeError</span>:
308 <span class="Statement">pass</span>
309
310 <span class="Identifier">print</span>(good(<span class="Constant">"</span><span class="Constant">Done in %0.5fs.</span><span class="Constant">"</span> % (time.process_time() - start)))
311
312</pre>
313</body>
314</html>
315<!-- vim: set foldmethod=manual : -->