Lots of updates - restructured, added things...

This commit is contained in:
2026-05-14 20:38:40 +03:00
parent 74ada1c5cf
commit 3b98043a61
10 changed files with 323 additions and 88 deletions
+76 -16
View File
@@ -10,13 +10,7 @@
org-html-head-include-scripts nil) org-html-head-include-scripts nil)
(setq site-nav (setq site-nav
"<nav> "<div class=\"site-contact\">
<div class=\"nav-links\">
<a href=\"/\">Home</a>
<a href=\"/about.html\">About</a>
<a href=\"/blog.html\">Blog</a>
</div>
<div class=\"nav-contact\">
<a href=\"mailto:aner@zakobar.com\" class=\"contact-link\"> <a href=\"mailto:aner@zakobar.com\" class=\"contact-link\">
<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\"/><path d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\"/></svg> <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\"/><path d=\"m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\"/></svg>
aner@zakobar.com aner@zakobar.com
@@ -25,8 +19,52 @@
<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\"/><rect x=\"2\" y=\"9\" width=\"4\" height=\"12\"/><circle cx=\"4\" cy=\"4\" r=\"2\"/></svg> <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\"/><rect x=\"2\" y=\"9\" width=\"4\" height=\"12\"/><circle cx=\"4\" cy=\"4\" r=\"2\"/></svg>
linkedin.com/in/aner-zakobar linkedin.com/in/aner-zakobar
</a> </a>
</div> </div>")
</nav>")
(setq blog-nav
"<div class=\"blog-nav\">
<a href=\"/\" class=\"back-link\">← aner.zakobar.com</a>
</div>")
(defun things-extract-keyword (file keyword)
"Extract #+KEYWORD: value from FILE, or nil if absent/empty."
(with-temp-buffer
(insert-file-contents file)
(goto-char (point-min))
(when (re-search-forward
(concat "^#\\+" keyword ":[ \t]*\\(.*\\)$") nil t)
(let ((v (string-trim (match-string 1))))
(unless (string= v "") v)))))
(defun things-generate-page (_project)
"Scan things/ and write content/generated/things-body.org."
(let* ((things-dir "./things")
(gen-dir "./content/generated")
(files (when (file-directory-p things-dir)
(file-expand-wildcards (concat things-dir "/*.org") t))))
(make-directory gen-dir t)
(with-temp-file (concat gen-dir "/things-body.org")
(insert "#+BEGIN_EXPORT html\n<div class=\"things-grid\">\n")
(dolist (file files)
(let* ((title (things-extract-keyword file "THINGS_TITLE"))
(desc (things-extract-keyword file "THINGS_DESC"))
(path (things-extract-keyword file "THINGS_PATH"))
)
(when (and title desc path)
(insert
(concat
"<div class=\"things-card\">\n"
" <div class=\"things-card-body\">\n"
" <h3><a href=\"/" path "/\">" title "</a></h3>\n"
" <p>" desc "</p>\n"
" </div>\n"
"</div>\n")))))
(insert "</div>\n#+END_EXPORT\n"))))
(defun site-prepare (project)
"Run all site preparation steps."
(blog-generate-listings project)
(things-generate-page project))
(defun blog-extract-title (file) (defun blog-extract-title (file)
"Extract #+TITLE: value from FILE." "Extract #+TITLE: value from FILE."
@@ -77,24 +115,29 @@
(concat (concat
"*[[" link "][" title "]]* — " date "\n\n" "*[[" link "][" title "]]* — " date "\n\n"
excerpt "\n\n" excerpt "\n\n"
"[[" link "][Read more →]]\n\n" "[[" link "][Read more →]]\n\n")))))
"-----\n\n")))))
(make-directory gen-dir t) (make-directory gen-dir t)
(with-temp-file (concat gen-dir "/recent-posts.org") (with-temp-file (concat gen-dir "/recent-posts.org")
(let ((first t))
(dolist (file (seq-take files 3)) (dolist (file (seq-take files 3))
(insert (funcall make-entry file)))) (unless first (insert "-----\n\n"))
(insert (funcall make-entry file))
(setq first nil))))
(with-temp-file (concat gen-dir "/all-posts.org") (with-temp-file (concat gen-dir "/all-posts.org")
(let ((first t))
(dolist (file files) (dolist (file files)
(insert (funcall make-entry file)))))) (unless first (insert "-----\n\n"))
(insert (funcall make-entry file))
(setq first nil))))))
(setq org-publish-project-alist (setq org-publish-project-alist
`(("site-pages" `(("site-pages"
:base-directory "./content" :base-directory "./content"
:base-extension "org" :base-extension "org"
:publishing-directory "./public" :publishing-directory "./public"
:recursive t :recursive t
:exclude "generated/" :exclude "generated/\\|blog/"
:publishing-function org-html-publish-to-html :publishing-function org-html-publish-to-html
:preparation-function blog-generate-listings :preparation-function site-prepare
:html-head-include-default-style nil :html-head-include-default-style nil
:html-head-include-scripts nil :html-head-include-scripts nil
:html-head "<link rel=\"stylesheet\" href=\"/style.css\"><script src=\"/animation.js\" defer></script>" :html-head "<link rel=\"stylesheet\" href=\"/style.css\"><script src=\"/animation.js\" defer></script>"
@@ -106,6 +149,23 @@
:section-numbers nil :section-numbers nil
:with-toc nil) :with-toc nil)
("site-blog"
:base-directory "./content/blog"
:base-extension "org"
:publishing-directory "./public/blog"
:recursive nil
:publishing-function org-html-publish-to-html
:html-head-include-default-style nil
:html-head-include-scripts nil
:html-head "<link rel=\"stylesheet\" href=\"/style.css\"><script src=\"/animation.js\" defer></script>"
:html-preamble ,blog-nav
:html-postamble nil
:with-author nil
:with-creator nil
:with-timestamps nil
:section-numbers nil
:with-toc nil)
("site-static" ("site-static"
:base-directory "./static" :base-directory "./static"
:base-extension "css\\|js\\|png\\|jpg\\|jpeg\\|gif\\|svg\\|ico\\|woff2\\|woff\\|ttf" :base-extension "css\\|js\\|png\\|jpg\\|jpeg\\|gif\\|svg\\|ico\\|woff2\\|woff\\|ttf"
@@ -114,6 +174,6 @@
:publishing-function org-publish-attachment) :publishing-function org-publish-attachment)
("site" ("site"
:components ("site-pages" "site-static")))) :components ("site-pages" "site-blog" "site-static"))))
(org-publish "site" t) (org-publish "site" t)
-6
View File
@@ -1,6 +0,0 @@
#+TITLE: About
#+DESCRIPTION: About me
* General Background
I was born. I grew up. I learned to code. I learned basic linear algebra. I made this site. This about sums it up.
-6
View File
@@ -1,6 +0,0 @@
#+TITLE: Blog
#+DESCRIPTION: All blog posts
* All Posts
#+INCLUDE: generated/all-posts.org
+4 -3
View File
@@ -1,9 +1,10 @@
#+TITLE: Aner Zakobar's Personal Waste of Bits #+TITLE: Aner Zakobar's Personal Waste of Bits
#+DESCRIPTION: Personal website #+DESCRIPTION: Personal website
* Recent Blog Posts * Things
#+INCLUDE: generated/recent-posts.org
#+INCLUDE: generated/things-body.org
* Blog
#+INCLUDE: generated/all-posts.org
-10
View File
@@ -1,10 +0,0 @@
#+TITLE: Projects
#+DESCRIPTION: About me
* Embedding Golf
Look at the embedding golf
* Around the world look
Look around the world
Generated
+95 -1
View File
@@ -1,5 +1,41 @@
{ {
"nodes": { "nodes": {
"ar-globe-explorer": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1778763816,
"narHash": "sha256-V1CZ3p0nEtPtp9gDBgaR3csBlD1rcQiNDlEma/iOjmE=",
"owner": "anerisgreat",
"repo": "ar-world-border-viewer",
"rev": "8e2ed6cd72fa69ccb690dfcefeddf11ef27b6762",
"type": "github"
},
"original": {
"owner": "anerisgreat",
"repo": "ar-world-border-viewer",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1696426674,
"narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": { "flake-utils": {
"inputs": { "inputs": {
"systems": "systems" "systems": "systems"
@@ -34,10 +70,47 @@
"type": "github" "type": "github"
} }
}, },
"nixpkgs-python": {
"inputs": {
"flake-compat": "flake-compat",
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1733319315,
"narHash": "sha256-cFQBdRmtIZFVjr2P6NkaCOp7dddF93BC0CXBwFZFaN0=",
"owner": "cachix",
"repo": "nixpkgs-python",
"rev": "01263eeb28c09f143d59cd6b0b7c4cc8478efd48",
"type": "github"
},
"original": {
"owner": "cachix",
"repo": "nixpkgs-python",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1719253556,
"narHash": "sha256-A/76RFUVxZ/7Y8+OMVL1Lc8LRhBxZ8ZE2bpMnvZ1VpY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "fc07dc3bdf2956ddd64f24612ea7fc894933eb2e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": { "root": {
"inputs": { "inputs": {
"ar-globe-explorer": "ar-globe-explorer",
"flake-utils": "flake-utils", "flake-utils": "flake-utils",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs",
"word-embedding-golf": "word-embedding-golf"
} }
}, },
"systems": { "systems": {
@@ -54,6 +127,27 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"word-embedding-golf": {
"inputs": {
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-python": "nixpkgs-python"
},
"locked": {
"lastModified": 1778780013,
"narHash": "sha256-iG8zEn8Qe2dWnxr3zRTWGJaO8yQbfJRaqllckDObMnM=",
"owner": "anerisgreat",
"repo": "word-embedding-golf",
"rev": "1fc4dd0324d0988bd6e4590e7cd625657d31e496",
"type": "github"
},
"original": {
"owner": "anerisgreat",
"repo": "word-embedding-golf",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",
+67 -16
View File
@@ -5,15 +5,15 @@
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
# Sub-projects: uncomment and replace URLs when ready word-embedding-golf = {
# project-a = { url = "github:anerisgreat/word-embedding-golf";
# url = "path:/path/to/project-a"; inputs.nixpkgs.follows = "nixpkgs";
# inputs.nixpkgs.follows = "nixpkgs"; };
# };
# project-b = { ar-globe-explorer = {
# url = "path:/path/to/project-b"; url = "github:anerisgreat/ar-world-border-viewer";
# inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
# }; };
}; };
outputs = { self, nixpkgs, flake-utils, ... } @ inputs: outputs = { self, nixpkgs, flake-utils, ... } @ inputs:
@@ -21,9 +21,9 @@
let let
pkgs = import nixpkgs { inherit system; }; pkgs = import nixpkgs { inherit system; };
# Sub-project outputs — uncomment when inputs above are added wordEmbeddingGolfPkg = inputs.word-embedding-golf.packages.${system}.default;
# subProjectA = inputs.project-a.packages.${system}.default;
# subProjectB = inputs.project-b.packages.${system}.default; arGlobeExplorerPkg = inputs.ar-globe-explorer.packages.${system}.default;
site = pkgs.stdenv.mkDerivation { site = pkgs.stdenv.mkDerivation {
name = "personal-site"; name = "personal-site";
@@ -40,9 +40,19 @@
installPhase = '' installPhase = ''
cp -r public/. $out/ cp -r public/. $out/
# Sub-project integration: when adding a sub-project, add lines like: mkdir -p $out/word-embedding-golf
# mkdir -p $out/project-a cp -r ${wordEmbeddingGolfPkg}/. $out/word-embedding-golf/
# cp -r <subProjectA-store-path>/. $out/project-a/
mkdir -p $out/ar-globe-explorer
cp -r ${arGlobeExplorerPkg}/. $out/ar-globe-explorer/
# Inject a "back to site" banner into all sub-project HTML pages
BANNER='<div id="back-banner" style="position:fixed;top:0;left:0;right:0;padding:.4rem 1rem;background:rgba(0,0,0,.82);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:9999;font-family:-apple-system,BlinkMacSystemFont,sans-serif;font-size:.82rem;border-bottom:1px solid rgba(255,255,255,.08);"><a href="/" style="color:#93c5fd;text-decoration:none;font-weight:500;"> aner.zakobar.com</a></div>'
for dir in $out/word-embedding-golf $out/ar-globe-explorer; do
find "$dir" -name "*.html" | while IFS= read -r f; do
sed -i -E "s|<body([^>]*)>|<body\1>$BANNER|" "$f"
done
done
''; '';
}; };
@@ -95,6 +105,47 @@
''; '';
}; };
new-thing = pkgs.writeShellApplication {
name = "new-thing";
runtimeInputs = [ pkgs.coreutils pkgs.gnused ];
excludeShellChecks = [ "SC2001" ];
text = ''
if [ $# -lt 3 ]; then
echo "Usage: new-thing \"Title\" \"flake-url\" \"Short description\""
exit 1
fi
title="$1"
flake_url="$2"
desc="$3"
slug=$(echo "$title" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-//;s/-$//')
camel=$(echo "$slug" | sed 's/-\([a-z]\)/\u\1/g')
filename="things/''${slug}.org"
mkdir -p things
cat > "$filename" <<EOF
#+THINGS_TITLE: $title
#+THINGS_DESC: $desc
#+THINGS_PATH: $slug
#+THINGS_FLAKE: $flake_url
EOF
echo "Created: $filename"
echo ""
echo "Add to flake.nix inputs:"
echo " ''${slug} = {"
echo " url = \"$flake_url\";"
echo " inputs.nixpkgs.follows = \"nixpkgs\";"
echo " };"
echo ""
echo "Add let binding before 'site =':"
echo " ''${camel}Pkg = inputs.''${slug}.packages.\''${system}.default;"
echo ""
echo "Add to installPhase after 'cp -r public/. \$out/':"
echo " mkdir -p \$out/''${slug}"
echo " cp -r \''${''${camel}Pkg}/. \$out/''${slug}/"
echo ""
echo "Then run: nix flake lock"
'';
};
new-post = pkgs.writeShellApplication { new-post = pkgs.writeShellApplication {
name = "new-post"; name = "new-post";
runtimeInputs = [ pkgs.coreutils pkgs.gnused ]; runtimeInputs = [ pkgs.coreutils pkgs.gnused ];
@@ -123,7 +174,7 @@ EOF
packages.default = site; packages.default = site;
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
packages = [ new-post ]; packages = [ new-post new-thing ];
}; };
apps = { apps = {
+63 -20
View File
@@ -48,8 +48,7 @@ body {
padding: 0 1.25rem; padding: 0 1.25rem;
} }
/* ── Layout — center preamble and content ────────────── */ /* ── Layout — center content ─────────────────────────── */
#preamble,
#content, #content,
#postamble { #postamble {
max-width: var(--max-width); max-width: var(--max-width);
@@ -57,8 +56,11 @@ body {
margin-right: auto; margin-right: auto;
} }
/* ── Navigation ──────────────────────────────────────── */ /* ── Contact header ──────────────────────────────────── */
#preamble nav { .site-contact {
max-width: var(--max-width);
margin-left: auto;
margin-right: auto;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
@@ -67,27 +69,23 @@ body {
margin-bottom: 2.5rem; margin-bottom: 2.5rem;
} }
.nav-links { /* ── Blog back nav ───────────────────────────────────── */
display: flex; .blog-nav {
gap: 1.5rem; max-width: var(--max-width);
margin-left: auto;
margin-right: auto;
padding: 1.25rem 0;
border-bottom: 1px solid var(--border);
margin-bottom: 2.5rem;
} }
.nav-links a { .back-link {
color: var(--fg); color: var(--muted);
text-decoration: none; text-decoration: none;
font-weight: 500; font-size: 0.9rem;
font-size: 0.95rem;
letter-spacing: 0.01em;
} }
.nav-links a:hover { color: var(--accent); } .back-link:hover { color: var(--accent); }
.nav-contact {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 0.25rem;
}
/* ── Content ─────────────────────────────────────────── */ /* ── Content ─────────────────────────────────────────── */
#content { #content {
@@ -223,3 +221,48 @@ th {
} }
.contact-link:hover { color: var(--accent); } .contact-link:hover { color: var(--accent); }
/* ── Things grid ─────────────────────────────────────── */
.things-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 1.25rem;
margin-top: 1.5rem;
}
.things-card {
border: 1px solid var(--border);
border-radius: 8px;
overflow: hidden;
background: var(--code-bg);
display: flex;
flex-direction: column;
}
.things-card-body {
padding: 0.9rem 1rem 1rem;
flex: 1;
display: flex;
flex-direction: column;
}
.things-card-body h3 {
margin-top: 0;
margin-bottom: 0.4rem;
font-size: 1rem;
}
.things-card-body h3 a {
color: var(--fg);
text-decoration: none;
}
.things-card-body h3 a:hover { color: var(--accent); }
.things-card-body p {
color: var(--muted);
font-size: 0.88rem;
margin-bottom: 0;
line-height: 1.5;
}
+4
View File
@@ -0,0 +1,4 @@
#+THINGS_TITLE: AR Globe Explorer
#+THINGS_DESC: View real-world locations of other countries relative to your position - do you know where other countries REALLY are?
#+THINGS_PATH: ar-globe-explorer
#+THINGS_FLAKE: https://github.com/anerisgreat/ar-world-border-viewer
+4
View File
@@ -0,0 +1,4 @@
#+THINGS_TITLE: Word Embedding Golf
#+THINGS_DESC: Learn about word embeddings in this tiny time waster!
#+THINGS_PATH: word-embedding-golf
#+THINGS_FLAKE: github:anerisgreat/word-embedding-golf