How its maked
About this site
This is version 2.0 of my personal website. I made version 1.0 using
Jekyll,
a static site generator, and a fork of Minimal
Mistakes, a Jekyll theme. The idea of this approach is that it is
“easy” to get a good looking site up and running with little
configuration (a single yaml
file), and you can write blog
posts in markdown rather than html. My experience with Jekyll and the
Minimal Mistakes theme was that it actually made things more
complicated, it was not easily customizable, and it was not made by
me.
For example, trying to get Mathjax to work on the Jekyll site was a
pain and required Jekyll’s custom liquid markup language. I had to
create a folder _includes/head
with a file
custom.html
with the following content.
{% if page.mathjax %}<script type="text/javascript" async
src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
{% endif %}
<script type="text/x-mathjax-config">
.Hub.Config({
MathJaxextensions: ["tex2jax.js"],
jax: ["input/TeX", "output/HTML-CSS"],
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
processEscapes: true
,
}"HTML-CSS": { availableFonts: ["TeX"] }
;
})</script>
and add the yaml
front matter mathjax: true
to each of the markdown files to get \(\LaTeX\) to work. I also found the
gem
dependencies to be difficult to manage/install and the
site could take 20 minutes to update after being pushed to GitHub.
Version 2.0 is made without the bloat using make
,
pandoc
, and some css
.
How this site is made
I am still able to write blog posts and pages using markdown by the help of a short makefile.
SRC_DIRS := _posts _projects _pages
MD_FILES := $(shell find $(SRC_DIRS) -type f -name '*.md')
HTML_FILES := $(patsubst _%.md,%.html,$(MD_FILES))
PD_FLAGS = --standalone --toc --mathjax \
-c /assets/css/master.css \
--include-before-body ./assets/navigation.html \
--include-after-body ./assets/footer.html \
--highlight-style breezedark
all: $(HTML_FILES) index makefile
posts/%.html: _posts/%.md
pandoc $(PD_FLAGS) $^ -o $@
projects/%.html: _projects/%.md
pandoc $(PD_FLAGS) $^ -o $@
pages/%.html: _pages/%.md
pandoc $(PD_FLAGS) $^ -o $@
index:
python ./assets/python/generate_posts_index.py
$(PD_FLAGS) _posts/index.md -o posts/index.html
pandoc 's/\(href=".*\).md">/\1.html">/' ./posts/index.html
sed -i.bak
rm ./posts/index.html.bak
clean:
rm $(HTML_FILES)
serve:
echo Serving the site at http://127.0.0.1:8000/
python3 -m http.server
This makefile will convert any markdown file in _posts
,
_projects
, or _pages
to a corresponding html
file posts
, projects
, or
pages
.
The basic directory structure of the site then look like this:
.
├── index.html
├── makefile
├── _pages
│ └── command_line.md
├── pages
│ ├── about.html
│ ├── command_line.html
│ └── links.html
├── _posts
│ ├── 2020-08-04-first-post.md
│ ├── 2021-05-26-wsl.md
│ └── index.md
├── posts
│ ├── 2020-08-04-first-post.html
│ ├── 2021-05-26-wsl.html
│ ├── index.html
├── _projects
│ ├── vim-terminator.md
└── projects
├── index.html
├── vim-terminator.html
The cool thing about this approach is that the .html
files are generated only when the corresponding .md
file
has changed. This makes it incredibly fast to build and preview the
website offline. All I have to do is type make
. This
directory layout also allows the .html
and .md
files to link to other files in the project without issues from the
conversion process.
The posts/index.html
file is automatically generated
from a simple python script that I whipped together. It even allows for
tagging of posts using yaml
front matter in the same way
the complicated Jekyll site did. The code to produce the index file is
below:
#!/usr/bin/env python3
from pathlib import Path
import yaml
= sorted(Path('./_posts/').glob('*.md'), reverse=True)
FILES = [f for f in FILES if 'index.md' not in f.name]
FILES = Path('./_posts/index.md')
INDEX
def parse_frontmatter(file):
with open(file, 'r') as f:
= next(f)
line if line != '---\n':
return
= ''
frontmatter = next(f)
line while line != '---\n':
+= line
frontmatter = next(f)
line return yaml.safe_load(frontmatter)
with open(INDEX, 'w') as f:
'---\n')
f.write('title: Posts\n')
f.write('---\n')
f.write('\n')
f.write(
'| | | | |\n')
f.write('|:--- | :---- | :--- | :--- |\n')
f.write(for file in FILES:
= parse_frontmatter(file)
frontmatter = frontmatter.get('title')
title = frontmatter.get('categories')
categories if categories is None:
= ''
categories else:
= ', '.join(categories)
categories
= file.name[:10]
date f'| Ɣ | {date} | [{title}]({str(file.name)}) | *{categories}* | \n') f.write(