forked from onyx-lang/onyx-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompile.onyx
118 lines (95 loc) · 3.07 KB
/
compile.onyx
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//+optional-semicolons
use core.os
use core.io
use core.iter
use core.encoding.json
use core {
printf
tprintf
}
Examples_Dir :: "./examples"
Compilation_Dir :: "./compilation"
Example :: struct {
code: str
title: str
name: str
tags: [] str
author: str
description: str
}
ExamplesMetadata :: struct {
by_tag: json.Value
// These examples will not have the code property set,
// to avoid lot of bloat.
list: [..] Example
}
main :: () {
examples: [..] Example
//
// Find and process all examples
for file in os.list_directory(Examples_Dir) {
name := file->name()
if !name->ends_with(".onyx") do continue
contents := os.get_contents(os.path_join(Examples_Dir, name))
basename := str.bisect(name, ".") |> str.copy()
ex: Example
ex.name = basename
if !contents->starts_with("/*===") {
logf(.Error, "'{}' is not a valid example because it does not contain a metadata block.", name)
}
metadata, code := str.bisect(contents, "===*/")
ex.code = str.strip_whitespace(code)
for md in metadata->split_iter("\n") {
key, value := str.bisect(md, ":")
key = str.strip_whitespace(key)
value = str.strip_whitespace(value)
switch key {
case "title" do ex.title = value
case "author" do ex.author = value
case "description" do ex.description = value
case "tags" do ex.tags = str.split_iter(value, " ")->collect()
}
}
examples << ex
}
//
// Output processed examples into compilation folder.
if !os.dir_exists(Compilation_Dir) {
os.dir_create(Compilation_Dir)
}
for &ex in examples {
logf(.Info, "Generating {}", ex.name)
use f := os.open(os.path_join(Compilation_Dir, tprintf("{}.html", ex.name)), .Write)->unwrap()
use w := io.Writer.make(&f)
io.write_format(&w, "<h1 class='title'>{}</h1>\n", ex.title)
io.write_format(&w, "<p class='author'>{}</p>\n", ex.author)
io.write_format(&w, "<div class='description'>{}</div>\n", ex.description)
io.write_format(&w, "<pre class='hljs'><code class='language-onyx'>{}</code></pre>\n", ex.code)
}
//
// Output metadata.
md: ExamplesMetadata
md.list = iter.as_iter(examples)
->map(x => Example.{
title = x.title,
name = x.name,
description = x.description,
author = x.author,
tags = x.tags,
})
->collect()
by_tag := make(Map(str, [..] str))
for &ex in examples {
for tag in ex.tags {
example_list := by_tag->get_ptr_or_create(tag)
example_list->push(ex.name)
}
}
md.by_tag = json.empty_object()
for by_tag->as_iter() {
json.set(md.by_tag, it.key, json.from_any(&it.value))
}
use f := os.open(os.path_join(Compilation_Dir, "index.json"), .Write).Ok?
use w := io.Writer.make(&f)
json.encode(&w, md)
}