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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="description" content="RAGHURAM SUBRAMANI ~ COMPROMYSE | Hacker & Programmer">
<title>MSG | COMPROMYSE</title>
<link rel="apple-touch-icon" sizes="180x180" href="/assets/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon/favicon-16x16.png">
<link rel="manifest" href="/assets/favicon/site.webmanifest">
<link href="/assets/stylesheet.css" rel="stylesheet" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Jersey+15&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/base16/ashes.min.css" defer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<script defer>hljs.highlightAll();</script>
</head>
<body class="bg-zinc-900 text-pink-300 font-['Jersey_15'] selection:text-pink-900 selection:bg-pink-100 lg:text-xl">
<div class="min-h-screen flex flex-col">
<nav class="w-full mx-auto mt-10">
<div class="flex flex-wrap items-center px-10 gap-4 text-center text-lg lg:text-2xl">
<a href="/" class="cursor-pointer font-bold hover:underline justify-center button">
COMPROMYSE
</a>
<div class="flex items-center gap-4 flex-wrap justify-center md:justify-left">
<a href="/projects" class="hover:underline">
[ PROJECTS ]
</a>
</div>
</div>
</nav>
<div class="flex flex-grow flex-col py-8 px-14 items-center">
<div class="text-center flex flex-col gap-4 w-full max-w-100">
<h1 class="text-5xl font-semibold">MSG</h1>
<div>
<h4 class="text-xl">An incredibly opinionated, hackable, minimal Static Site Generator.</h4>
<h6 class="text-center text-sm border-t-4 mt-2 py-1">C</h6>
</div>
<a href="https://github.com/compromyse/msg" target="_blank" class="button">SOURCE</a>
</div>
<div class="prose md:prose-lg lg:prose-2xl prose-pink prose-invert w-full max-w-256 pt-12">
<p>See <a href="https://github.com/compromyse/compromyse.xyz">github.com/compromyse/compromyse.xyz</a> for an example site.</p>
<p>The point of this project was very simple; I was in the mood to write a static site generator. I figured I’d start with the most basic feature, “includes,” and it ended up expanding to supporting nested for loops. All I required was a simple static site generator that doesn’t overdo it. Besides, who doesn’t like writing a lexer and generation engine in C.</p>
<h3>Compilation & Usage</h3>
<p><pre><code class="sh"># REQUIREMENTS: CMake, Git, GCC/Clang, GNUMake/Ninja
$ git clone https://github.com/compromyse/msg
$ mkdir build && cd build
$ cmake ..
$ make # or ninja
$ ./msg -h
msg: The Minimal Static Site Generator
Usage: ./msg [-h] [-w] [-v] [-o <output>] <directory>
-h : Help
-w : Watch working directory for changes
-v : Verbose
-o <output>: Output directory
<directory>: Working directory
</code></pre>
</p>
<h3>Site Structure</h3>
<p>The site structure is actually fairly simple. <code>/config.cfg</code> describes the static directories, in this case only “assets.” It could be any number of files & folders, though.</p>
<p>Since I wanted to manually define all the resources (pages), I added a list <code>resources</code> in <code>/config.cfg</code> to encapsulate the collection of web pages. This was largely inspired by C build systems, where each C file is listed in an array of filenames (See <a href="https://github.com/compromyse/msg/blob/main/CMakeLists.txt#L6">CMakeLists.txt for msg</a>).</p>
<p>The partials though, must be placed in the hardcoded <code>/partials</code> folder. They may, however, be placed in subdirectories therein. I didn’t see much of a point allowing multiple partial directories (and likewise with templates).</p>
<p><pre><code class="sh">.
├── assets
│ └── me.webp
├── config.cfg
├── index.html
├── partials
│ ├── footer.html
│ ├── navbar.html
├── projects.html
└── templates
└── base.html
</code></pre>
</p>
<h3>Features</h3>
<h4>Includes - include files from <code>/partials</code></h4>
<p>This directive simply fetches the file content of the operand, in this case <code>/partials/navbar.html</code> and replaces the caller’s body with it.</p>
<p><pre><code class="html"><!-- index.html -->
<html>
<body>
{{ include "navbar.html" }}
...
</body>
</html>
</code></pre>
</p>
<h4>Contentfor - define content for templates</h4>
<p>In this particular case, the template must have <code>content</code> directives, whose bodies are defined using <code>contentfor</code> directives. The example is fairly self-explanatory.</p>
<p><pre><code class="html"><!-- templates/base.html -->
<html>
<head>
{{ content "head" }}
</head>
<body>
{{ body }}
</body>
</html>
<!-- index.html -->
{{ contentfor "head" }}
<title>HOME</title>
{{ endcontent }}
<p>...</p>
</code></pre>
</p>
<h4>Eachdo - iterate over resources</h4>
<p>These are actually fairly complicated; EACHDOs iterate over some array of strings or nested-configs.</p>
<p>In the first example, the source being iterated over is the current page’s <code>links</code> config. For each link, it’s simply printing the respective href and label.</p>
<p><pre><code class="html"><!-- projects/xyz.html -->
links = [
href = https://example.org
label = abc
___
href = https://google.com
label = test
]
---
<h1>XYZ!</h1>
{{ eachdo page.links }}
<p>{{ put href }}</p>
<p>{{ put label }}</p>
{{ endeachdo }}
</code></pre>
With this example, <code>/index.html</code> is iterating over the <code>projects</code> resource (just the /projects directory excluding index.html). For each of the pages, it’s simply printing the page’s title in a paragraph tag.</p>
<p><pre><code class="html"><!-- projects/xyz.html -->
title = XYZ
---
<h1>XYZ!</h1>
<!-- index.html -->
{{ eachdo resources.projects }}
<p>{{ put title }}</p>
{{ endeachdo }}
</code></pre>
This example is much like the first one, but instead of the links being defined in the current page, it’s defined in <code>/config.cfg</code>.</p>
<p><pre><code class="html"><!-- config.cfg -->
links = [
href = https://github.com/compromyse
label = GITHUB
___
href = https://www.linkedin.com/in/compromyse
label = LINKEDIN
]
<!-- index.html -->
{{ eachdo config.links }}
<a href="{{ put href }}" class="button" target="_blank">{{ put label }}</a>
{{ endeachdo }}
</code></pre>
</p>
<h4>Page Options - specify template, priority in EACHDO iterations, etc.</h4>
<p>Some page options can be defined in a page’s config, such as the template that needs to be used, and the priority of this particular page when the resource containing the page (projects) is iterated over.</p>
<p><pre><code class="html"><!-- projects/xyz.html -->
template = base_tailwind.html
priority = 100
---
<h1 class="p-2">XYZ!</h1>
</code></pre>
<code>Licensed under GPLv3</code></p>
</div>
</div>
<footer class="w-full pb-4 pt-12 px-8 text-sm md:text-lg">
<div class="text-center">
<p>The Quieter You Become, The More You Are Able To Hear.</p>
</div>
</footer>
</div>
</body>
</html>
|