init commit

This commit is contained in:
Yan Lin 2026-01-30 16:19:41 +01:00
commit 52b82fe03f
13 changed files with 372 additions and 0 deletions

1
.envrc Normal file
View file

@ -0,0 +1 @@
use flake

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
public/
.direnv/
.DS_Store

15
config.toml Normal file
View file

@ -0,0 +1,15 @@
base_url = "https://blog.yanlincs.com"
title = "Yan Lin's Blog"
description = "Personal blog of Yan Lin, Postdoctoral Researcher at Aalborg University"
default_language = "en"
compile_sass = true
minify_html = false
generate_feeds = true
feed_filenames = ["rss.xml"]
[markdown]
highlight_code = true
highlight_theme = "css"
[extra]
author = "Yan Lin"

7
content/_index.md Normal file
View file

@ -0,0 +1,7 @@
+++
title = "Welcome"
+++
My name is Yan Lin, and this is my personal blog where I occasionally post my thoughts and findings during research.
I am a postdoctoral researcher in the Department of Computer Science at Aalborg University. My research interests include spatiotemporal data mining, representation learning, and AI for science.

7
content/blog/_index.md Normal file
View file

@ -0,0 +1,7 @@
+++
title = "Blog"
sort_by = "date"
paginate_by = 10
+++
Occasional thoughts and findings from research and beyond.

View file

@ -0,0 +1,27 @@
+++
title = "Hello, Zola"
date = 2026-01-30
draft = false
+++
This blog has migrated from Quartz to Zola. The previous version was feature-rich with backlinks, graph views, and Obsidian integration. This new version prioritizes simplicity.
## Why the Change?
Quartz is excellent for digital gardens and interconnected notes. However, for a straightforward blog, it carries unnecessary complexity. Zola offers:
- **Fast builds**: Written in Rust, compilation is nearly instant
- **Simple structure**: Plain markdown files with TOML frontmatter
- **No JavaScript dependency**: Static HTML output
- **Nix-friendly**: Single binary, easy to include in flake
## What to Expect
The content focus remains the same:
- Machine learning techniques
- AI systems and infrastructure
- Conference paper summaries
- Occasional homelab notes
The design is intentionally minimal. No fancy features, just words on a page.

26
flake.nix Normal file
View file

@ -0,0 +1,26 @@
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }: let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
in {
devShells = forAllSystems (pkgs: {
default = pkgs.mkShell {
packages = with pkgs; [
zola
(writeShellScriptBin "serve" ''
zola serve --open
'')
(writeShellScriptBin "build" ''
zola build
'')
];
shellHook = ''
echo "Zola blog development environment"
echo "Commands: serve, build, zola"
'';
};
});
};
}

170
sass/style.scss Normal file
View file

@ -0,0 +1,170 @@
:root {
--bg: #fff;
--fg: #222;
--accent: #284b63;
--muted: #666;
--border: #e5e5e5;
--code-bg: #f5f5f5;
--max-width: 42rem;
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #161618;
--fg: #ebebec;
--accent: #7b97aa;
--muted: #999;
--border: #333;
--code-bg: #1e1e1e;
}
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 18px;
line-height: 1.6;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: var(--bg);
color: var(--fg);
max-width: var(--max-width);
margin: 0 auto;
padding: 2rem 1rem;
}
a {
color: var(--accent);
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
header nav {
display: flex;
gap: 1.5rem;
margin-bottom: 3rem;
padding-bottom: 1rem;
border-bottom: 1px solid var(--border);
.site-title {
font-weight: 600;
}
}
main {
min-height: 60vh;
}
h1, h2, h3 {
margin: 1.5rem 0 0.75rem;
line-height: 1.3;
}
h1 { font-size: 1.75rem; }
h2 { font-size: 1.4rem; }
h3 { font-size: 1.15rem; }
p, ul, ol {
margin-bottom: 1rem;
}
ul, ol {
padding-left: 1.5rem;
}
.post-header {
margin-bottom: 2rem;
h1 {
margin-bottom: 0.5rem;
}
time {
color: var(--muted);
font-size: 0.9rem;
}
}
.post-list {
list-style: none;
padding: 0;
li {
display: flex;
gap: 1rem;
margin-bottom: 0.5rem;
time {
color: var(--muted);
font-size: 0.9rem;
min-width: 6rem;
}
}
}
.recent-posts {
margin-top: 3rem;
}
code {
font-family: "Fira Code", "SF Mono", Consolas, monospace;
font-size: 0.9em;
background: var(--code-bg);
padding: 0.1em 0.3em;
border-radius: 3px;
}
pre {
background: var(--code-bg);
padding: 1rem;
overflow-x: auto;
border-radius: 4px;
margin-bottom: 1rem;
code {
background: none;
padding: 0;
}
}
blockquote {
border-left: 3px solid var(--accent);
padding-left: 1rem;
margin: 1rem 0;
color: var(--muted);
}
.pagination {
display: flex;
justify-content: space-between;
margin-top: 2rem;
padding-top: 1rem;
border-top: 1px solid var(--border);
}
.not-found {
text-align: center;
padding: 3rem 0;
h1 {
font-size: 4rem;
margin-bottom: 1rem;
}
}
footer {
margin-top: 3rem;
padding-top: 1rem;
border-top: 1px solid var(--border);
color: var(--muted);
font-size: 0.9rem;
}

11
templates/404.html Normal file
View file

@ -0,0 +1,11 @@
{% extends "base.html" %}
{% block title %}Not Found - {{ config.title }}{% endblock title %}
{% block content %}
<article class="not-found">
<h1>404</h1>
<p>Page not found.</p>
<p><a href="{{ get_url(path='/') }}">Return home</a></p>
</article>
{% endblock content %}

35
templates/base.html Normal file
View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="{{ lang | default(value="en") }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{{ config.title }}{% endblock title %}</title>
<meta name="description" content="{% block description %}{{ config.description }}{% endblock description %}">
<link rel="stylesheet" href="{{ get_url(path='style.css') }}">
<link rel="alternate" type="application/rss+xml" title="RSS" href="{{ get_url(path='rss.xml') }}">
<!-- KaTeX for math rendering -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"
onload="renderMathInElement(document.body, {
delimiters: [
{left: '$$', right: '$$', display: true},
{left: '$', right: '$', display: false}
]
});"></script>
</head>
<body>
<header>
<nav>
<a href="{{ get_url(path='/') }}" class="site-title">{{ config.title }}</a>
<a href="{{ get_url(path='blog') }}">Blog</a>
</nav>
</header>
<main>
{% block content %}{% endblock content %}
</main>
<footer>
<p>&copy; {{ now() | date(format="%Y") }} {{ config.extra.author }}</p>
</footer>
</body>
</html>

20
templates/index.html Normal file
View file

@ -0,0 +1,20 @@
{% extends "base.html" %}
{% block content %}
<article class="homepage">
{{ section.content | safe }}
</article>
<section class="recent-posts">
<h2>Recent Posts</h2>
{% set blog = get_section(path="blog/_index.md") %}
<ul class="post-list">
{% for page in blog.pages | slice(end=5) %}
<li>
<time datetime="{{ page.date }}">{{ page.date | date(format="%Y-%m-%d") }}</time>
<a href="{{ page.permalink }}">{{ page.title }}</a>
</li>
{% endfor %}
</ul>
</section>
{% endblock content %}

17
templates/page.html Normal file
View file

@ -0,0 +1,17 @@
{% extends "base.html" %}
{% block title %}{{ page.title }} - {{ config.title }}{% endblock title %}
{% block content %}
<article>
<header class="post-header">
<h1>{{ page.title }}</h1>
{% if page.date %}
<time datetime="{{ page.date }}">{{ page.date | date(format="%B %d, %Y") }}</time>
{% endif %}
</header>
<div class="content">
{{ page.content | safe }}
</div>
</article>
{% endblock content %}

33
templates/section.html Normal file
View file

@ -0,0 +1,33 @@
{% extends "base.html" %}
{% block title %}{{ section.title }} - {{ config.title }}{% endblock title %}
{% block content %}
<h1>{{ section.title }}</h1>
{% if section.content %}
<div class="section-content">
{{ section.content | safe }}
</div>
{% endif %}
<ul class="post-list">
{% for page in section.pages %}
<li>
<time datetime="{{ page.date }}">{{ page.date | date(format="%Y-%m-%d") }}</time>
<a href="{{ page.permalink }}">{{ page.title }}</a>
</li>
{% endfor %}
</ul>
{% if paginator %}
<nav class="pagination">
{% if paginator.previous %}
<a href="{{ paginator.previous }}">&larr; Newer</a>
{% endif %}
{% if paginator.next %}
<a href="{{ paginator.next }}">Older &rarr;</a>
{% endif %}
</nav>
{% endif %}
{% endblock content %}