Compare commits

...

6 commits

Author SHA1 Message Date
Yann Esposito (Yogsototh) 14361d5289
I think it's good now 2021-04-27 15:32:55 +02:00
Yann Esposito (Yogsototh) 4ddc050e2c
a few fixes 2021-04-27 15:21:06 +02:00
Yann Esposito (Yogsototh) b0760a35cb
Almost complete 2021-04-27 15:06:55 +02:00
Yann Esposito (Yogsototh) f512d18a59
Almost done 2021-04-27 15:02:02 +02:00
Yann Esposito (Yogsototh) f89c62a6d4
makefile in progress 2021-04-27 14:34:29 +02:00
Yann Esposito (Yogsototh) b74e8e401a
wip 2021-04-26 22:53:10 +02:00
26 changed files with 350 additions and 33 deletions

94
Makefile Normal file
View file

@ -0,0 +1,94 @@
# Generate my website out of org-mode/gemini files
#
# maybe check https://themattchan.com/blog/2017-02-28-make-site-generator.html
# From https://github.com/fcanas/bake/blob/master/Makefile
# Finally https://www.arsouyes.org/blog/2017/10_Static_website/
all: allatend
SRC_DIR ?= src
DST_DIR ?= _site
SRC_RAW_FILES := $(shell find $(SRC_DIR) -type f)
DST_RAW_FILES := $(patsubst $(SRC_DIR)/%,$(DST_DIR)/%,$(SRC_RAW_FILES))
ALL += $(DST_RAW_FILES)
# COPY EVERYTHING
$(DST_DIR)/% : $(SRC_DIR)/%
mkdir -p "$(dir $@)"
cp "$<" "$@"
# ORG -> HTML
EXT := .org
SRC_PANDOC_FILES ?= $(shell find $(SRC_DIR) -type f -name "*$(EXT)")
DST_PANDOC_FILES ?= $(subst $(EXT),.html, \
$(subst $(SRC_DIR),$(DST_DIR), \
$(SRC_PANDOC_FILES)))
ALL += $(DST_PANDOC_FILES)
TEMPLATE ?= templates/post.html
CSS = /css/y.css
PANDOC := pandoc \
-c $(CSS) \
--template=$(TEMPLATE) \
--from org \
--to html5 \
--standalone
$(DST_DIR)/%.html: $(SRC_DIR)/%.org $(TEMPLATE)
mkdir -p $(dir $@)
$(PANDOC) $< \
--output $@
# HTML INDEX
HTML_INDEX := $(DST_DIR)/index.html
MKINDEX := engine/mk-index.sh
$(HTML_INDEX): $(DST_PANDOC_FILES) $(MKINDEX)
mkdir -p $(DST_DIR)
$(MKINDEX)
ALL += $(HTML_INDEX)
# ORG -> GEMINI
EXT := .org
SRC_GMI_FILES ?= $(shell find $(SRC_DIR) -type f -name "*$(EXT)")
DST_GMI_FILES ?= $(subst $(EXT),.gmi, \
$(subst $(SRC_DIR),$(DST_DIR), \
$(SRC_GMI_FILES)))
ALL += $(DST_GMI_FILES)
GMI := engine/org2gemini.sh
$(DST_DIR)/%.gmi: $(SRC_DIR)/%.org $(GMI)
mkdir -p $(dir $@)
$(GMI) "$<" "$@"
# OPTIM PHASE
OPTIM_DIR ?= _optim
OPTIM := engine/pre-deploy.sh
$(OPTIM_DIR)/index.html:$(DST_RAW_FILES) $(DST_GMI_FILES) $(DST_PANDOC_FILES) $(HTML_INDEX) $(OPTIM)
mkdir -p $(OPTIM_DIR)
$(OPTIM)
optim: $(OPTIM_DIR)/index.html
# DEPLOY
deploy: $(OPTIM_DIR)/index.html
engine/sync.sh # deploy to her.esy.fun
engine/ye-com-fastpublish.hs # deploy to yannesposito.com (via github pages)
allatend: $(ALL)
.PHONY: clean
clean:
-rm -rf $(DST_DIR)/*
-rm -rf $(OPTIM_DIR)/*

156
engine/mk-index.sh Executable file
View file

@ -0,0 +1,156 @@
#!/usr/bin/env zsh
cd "$(git rev-parse --show-toplevel)" || exit 1
# Directory
webdir="_site"
postsdir="$webdir/posts"
indexfile="$webdir/index.html"
# maximal number of articles to put in the RSS file
maxarticles=100
# RSS Metas
rsstitle="her.esy.fun"
rssurl="https://her.esy.fun/rss.xml"
websiteurl="https://her.esy.fun"
rssdescription="her.esy.fun articles, mostly random personal thoughts"
rsslang="en"
rssauthor="yann@esposito.host (Yann Esposito)"
rssimgurl="https://her.esy.fun/img/FlatAvatar.png"
# HTML Accessors (similar to CSS accessors)
dateaccessor='.yyydate'
contentaccessor='#content'
# title and keyword shouldn't be changed
titleaccessor='title'
keywordsaccessor='meta[name=keywords]::attr(content)'
formatdate() {
# format the date for RSS
local d="$1"
# echo "DEBUG DATE: $d" >&2
LC_TIME=en_US date --date $d +'%a, %d %b %Y %H:%M:%S %z'
}
finddate(){ < $1 hxselect -c $dateaccessor | sed 's/\[//g;s/\]//g;s/ .*$//' }
findtitle(){ < $1 hxselect -c $titleaccessor }
getcontent(){
< $1 hxselect $contentaccessor | \
perl -pe 'use URI; $base="'$2'"; s# (href|src)="((?!https?://)[^"]*)"#" ".$1."=\"".URI->new_abs($2,$base)->as_string."\""#eig' }
findkeywords(){ < $1 hxselect -c $keywordsaccessor | sed 's/,/ /g' }
mkcategories(){
for keyword in $*; do
printf "\\n<span class=\"tag\">%s</span>" $keyword
done
}
autoload -U colors && colors
tmpdir=$(mktemp -d)
typeset -a dates
dates=( )
for fic in $postsdir/**/*.html; do
if echo $fic|egrep -- '-(mk|min|sci|modern).html$'>/dev/null; then
continue
fi
postfile="$(echo "$fic"|sed 's#^'$postsdir'/##')"
blogfile="$(echo "$fic"|sed 's#^'$webdir'/##')"
printf "%-30s" $postfile
xfic="$tmpdir/$fic.xml"
mkdir -p $(dirname $xfic)
hxclean $fic > $xfic
d=$(finddate $xfic)
echo -n " [$d]"
rssdate=$(formatdate $d)
title=$(findtitle $xfic)
keywords=( $(findkeywords $xfic) )
printf ": %-55s" "$title ($keywords)"
categories=$(mkcategories $keywords)
absoluteurl="${websiteurl}/${blogfile}"
{ printf "\\n<li>"
printf "\\n<a href=\"%s\">%s</a>" "${blogfile}" "$title"
printf "\\n<span class=\"pubDate\">%s</span>%s" "$d"
printf "<span class=\"tags\">%s</span>" "$categories"
printf "\\n</li>\\n\\n"
} >> "$tmpdir/${d}-$(basename $fic).index"
dates=( $d $dates )
echo " [${fg[green]}OK${reset_color}]"
done
echo "Publishing"
for fic in $(ls $tmpdir/*.index | sort -r | head -n $maxarticles ); do
echo "${fic:t}"
cat $fic >> $tmpdir/index
done
rssmaxdate=$(formatdate $(for d in $dates; do echo $d; done | sort -r | head -n 1))
rssbuilddate=$(formatdate $(date))
title="Index"
description="Index of latest posts."
author="Yann Esposito"
{
cat <<END
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>$title</title>
<meta name="author" content="$author">
<link rel="stylesheet" href="/css/y.css"/>
<link rel="alternate" type="application/rss+xml" href="/rss.xml" />
<link rel="icon" href="/favicon.ico">
</head>
<body>
<div id="labels">
<div class="content">
<span id="logo">
<a href="/">
<svg width="5em" viewBox="0 0 64 64">
<circle cx="32" cy="32" r="30" stroke="var(--b2)" stroke-width="2" fill="var(--b03)"/>
<circle cx="32" cy="32" r="12" stroke="var(--r)" stroke-width="2" fill="var(--o)"/>
<circle cx="32" cy="32" r="6" stroke-width="0" fill="var(--y)"/>
<ellipse cx="32" cy="14" rx="14" ry="8" stroke-width="0" fill="var(--b3)"/>
</svg>
</a>
</div>
</div>
<div class="main">
<div id="preamble" class="status">
<div class="content">
<h1>$title</h1>
<div class="meta">
<span class="yyydate">$date</span> on
<a href="https://her.esy.fun">
<span class="author">$author</span>'s blog</a>
</div>
<div class="abstract">
$description
</div>
</div>
</div>
<div id="content">
END
cat $tmpdir/index
cat <<END
</div>
<div id="postamble" class="status">
<div class="content">
<nav>
<a href="/index.html">Home</a> |
<a href="/slides.html">Slides</a> |
<a href="/about-me.html">About</a>
<span class="details"> (<a href="https://gitea.esy.fun/yogsototh">code</a>
<a href="https://espial.esy.fun/u:yogsototh">bookmarks</a>
<a href="https://espial.esy.fun/u:yogsototh/notes">notes</a>)</span> |
<a href="#preamble">↑ Top ↑</a>
</nav>
</div>
</div>
</div>
</body>
</html>
END
} > "$indexfile"
rm -rf $tmpdir
echo "* RSS [done]"

View file

@ -19,7 +19,7 @@ rssauthor="yann@esposito.host (Yann Esposito)"
rssimgurl="https://her.esy.fun/img/FlatAvatar.png"
# HTML Accessors (similar to CSS accessors)
dateaccessor='.article-date'
dateaccessor='.yyydate'
contentaccessor='#content'
# title and keyword shouldn't be changed
titleaccessor='title'
@ -27,11 +27,12 @@ keywordsaccessor='meta[name=keywords]::attr(content)'
formatdate() {
# format the date for RSS
local d=$1
local d="$1"
# echo "DEBUG DATE: $d" >&2
LC_TIME=en_US date --date $d +'%a, %d %b %Y %H:%M:%S %z'
}
finddate(){ < $1 hxselect -c $dateaccessor }
finddate(){ < $1 hxselect -c $dateaccessor | sed 's/\[//g;s/\]//g;s/ .*$//' }
findtitle(){ < $1 hxselect -c $titleaccessor }
getcontent(){
< $1 hxselect $contentaccessor | \

View file

@ -4,19 +4,19 @@ cd "$(git rev-parse --show-toplevel)" || exit 1
webdir="_optim"
retrieve_classes_in_html () {
cat $webdir/**/*.html(N) | \
cat $webdir/**/*.html | \
perl -pe 's/class="?([a-zA-Z0-9_-]*)/\nCLASS: $1\n/g'
}
retrieve_classes_in_css () {
cat $webdir/**/*.css(N) | \
cat $webdir/**/*.css | \
perl -pe 's/ \.([a-zA-Z-_][a-zA-Z0-9-_]*)/\nCLASS:$1\n/g'
}
classes=( $( {retrieve_classes_in_html; retrieve_classes_in_css}| \
egrep "^CLASS: [^ ]*$" |\
sort -u | \
awk 'length($2)>2 && $2 !~ /(web-file-size|article-date|example|src)/ {print length($2),$2}'|\
awk 'length($2)>2 && $2 !~ /(gzwebfilesize|webfilesize|yyydate|example|src)/ {print length($2),$2}'|\
sort -rn | \
awk '{print $2}') )

3
engine/search-bad-keywords.sh Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
rg -w '#\+keywords:.*,' -t org

View file

@ -21,7 +21,7 @@ type -a filelist
if (($#>0)); then
filelist=( $* )
else
filelist=( $webdir/**/*.html(.) )
filelist=( $webdir/*/*.html(.) $webdir/posts/*.html )
fi
for fic in $filelist; do
@ -73,6 +73,6 @@ for fic in $filelist; do
gzsizeinfos="$gzsizeinfos)"
fi
print -- $sizeinfos
perl -pi -e 's#(<span class="?web-file-size"?>)[^<]*(</span>)#$1'"$sizeinfos"'$2#;s#(<span class="?gzweb-file-size"?>)[^<]*(</span>)#$1'"$gzsizeinfos"'$2#' $fic
perl -pi -e 's#(<span class="?webfilesize"?>)[^<]*(</span>)#$1'"$sizeinfos"'$2#;s#(<span class="?gzwebfilesize"?>)[^<]*(</span>)#$1'"$gzsizeinfos"'$2#' $fic
done
rm -rf $tmpdir

View file

@ -3,7 +3,7 @@ html {
font-size: 16px;
line-height: calc(1ex/0.37); }
#TOC {text-align: left;}
html,body { margin: 0; padding: 0; border: 0; }
html,body { margin: 0; padding: 0 0 3em 0; border: 0; }
.main { min-height: calc(100vh - 1em); }
h1,h2,h3,h4,h5,h6 {
line-height: calc(1ex/0.42);
@ -266,3 +266,6 @@ code { background: var(--rbg); }
.kw { color:var(--y); }
.st { color:var(--g); }
.co { color:var(--fg0); }
.pubDate { font-size: .7em; color: var(--b1); }
.tag { font-size: .7em; background-color: var(--b1); }

View file

@ -2,7 +2,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2021-01-10 Sun]
#+KEYWORDS: haskell, clojure, architecture, programming
#+KEYWORDS: haskell clojure architecture programming
#+DESCRIPTION: Here is a simple description on how to architect a big functional programming application.
#+OPTIONS: auto-id:t toc:nil

View file

@ -3,7 +3,7 @@
#+date: [2020-02-10 Mon]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+keywords: Haskell, programming, functional, tutorial
#+keywords: Haskell programming functional tutorial
#+DESCRIPTION: How to write Haskell application.
#+OPTIONS: auto-id:t toc:t
#+STARTUP: overview

View file

@ -4,7 +4,7 @@
#+created: [2020-01-18 Sat]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+keywords: Haskell, Clojure, programming, fp
#+keywords: Haskell Clojure functional-programming
#+DESCRIPTION: Simulate some abstractions in Clojure vs Haskell
#+OPTIONS: auto-id:t toc:t
#+STARTUP: overview

View file

@ -2,7 +2,7 @@
#+Author: Yann Esposito
#+Email: yann@esposito.host
#+Date: [2020-06-14 Sun]
#+KEYWORDS: nix, programming
#+KEYWORDS: nix programming
#+DESCRIPTION: In this article I explain how I use nix. As a brew replacement, as home environment manager, to have reproductible dev environment.
#+LANGUAGE: en
#+LANG: en

View file

@ -2,7 +2,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-07-04]
#+KEYWORDS: programming, blog, org-mode
#+KEYWORDS: programming blog org-mode
#+DESCRIPTION: Different divagations about my experiences in the professional world of Software Developer
#+begin_comment

View file

@ -3,7 +3,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-08-17 Sat 16:00]
#+KEYWORDS: programming, blog, org-mode, web, css
#+KEYWORDS: programming blog org-mode web css
#+DESCRIPTION: Meta article about how I generate this blog.
#+OPTIONS: auto-id:t

View file

@ -3,7 +3,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-08-18 Sun]
#+KEYWORDS: programming, blog, org-mode
#+KEYWORDS: programming blog org-mode
#+DESCRIPTION: A script I use to load safely an eLISP file when entering a new project directory.
#+OPTIONS: auto-id:t

View file

@ -3,7 +3,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-09-23 Mon]
#+KEYWORDS: blog, self-hosting, web, zen, minimalism
#+KEYWORDS: blog self-hosting web zen minimalism
#+DESCRIPTION: How I protect myself against attention grabbers and many social media anti-patterns.
#+OPTIONS: auto-id:t

View file

@ -3,7 +3,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-09-30 Mon]
#+KEYWORDS: programming, web
#+KEYWORDS: programming web
#+DESCRIPTION: How I generate RSS feed via command line
#+OPTIONS: auto-id:t

View file

@ -3,7 +3,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-10-19 Sat]
#+KEYWORDS: self-hosting, chat, irc
#+KEYWORDS: self-hosting chat irc
#+DESCRIPTION: Why and how to have modern and respectful chat system with IRC.
#+OPTIONS: auto-id:t toc:t

View file

@ -2,7 +2,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-11-10 Sun]
#+KEYWORDS: self-hosting, chat, irc
#+KEYWORDS: self-hosting chat irc
#+DESCRIPTION: Change the profile of iTerm in sync with macOS preferences.
#+OPTIONS: auto-id:t toc:nil

View file

@ -2,7 +2,7 @@
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+DATE: [2019-12-06 Fri]
#+KEYWORDS: blog, shell, script
#+KEYWORDS: blog shell script
#+DESCRIPTION: Optimize the size of a full static website by taking advantage
#+DESCRIPTION: of information found in both HTML and CSS.
#+OPTIONS: auto-id:t toc:nil

View file

@ -3,7 +3,7 @@
#+date: [2019-12-15 Sun]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+keywords: Haskell, programming, functional, tutorial
#+keywords: Haskell programming functional tutorial
#+DESCRIPTION: A short and intense introduction to Haskell. This is an update of my old (2012) article. A lot of things have changed since then. Mostly I changed my approach about the easiest way to install a Haskell playground. I removed the not as important part, and added a short introduction about starting a new project.
#+OPTIONS: auto-id:t toc:t
#+STARTUP: overview

View file

@ -2,7 +2,7 @@
#+date: [2020-02-29 Sat]
#+author: Yann Esposito
#+EMAIL: yann@esposito.host
#+keywords: org-mode, blog
#+keywords: org-mode blog
#+DESCRIPTION: Add links to code block during orgmode export.
#+OPTIONS: auto-id:t toc:t
#+STARTUP: overview

View file

@ -5,7 +5,7 @@
#+Author: Yann Esposito
#+Email: yann@esposito.host
#+Date: [2020-05-09 Sat]
#+KEYWORDS: emacs, softwares
#+KEYWORDS: emacs softwares
#+DESCRIPTION: Modern tools tend to disapears. An app on the web will change, and could break for the worst. Quite often investing in long living tools which are harder start with will be worth the investment.
#+LANGUAGE: en
#+LANG: en

View file

@ -1,5 +1,5 @@
#+TITLE: Slides
#+KEYWORDS: programming, presentations, slides
#+KEYWORDS: programming presentations slides
#+AUTHOR: Yann Esposito
#+EMAIL: yann@esposito.host
#+LANGUAGE: en

60
templates/post.html Normal file
View file

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>$title$</title>
<meta name="author" content="$author$">
<meta name="description" content="$description$">
<meta name="keywords" content="$keywords$">
<link rel="stylesheet" href="/css/y.css"/>
<link rel="alternate" type="application/rss+xml" href="/rss.xml" />
<link rel="icon" href="/favicon.ico">
</head>
<body>
<div id="labels">
<div class="content">
<span id="logo">
<a href="/">
<svg width="5em" viewBox="0 0 64 64">
<circle cx="32" cy="32" r="30" stroke="var(--b2)" stroke-width="2" fill="var(--b03)"/>
<circle cx="32" cy="32" r="12" stroke="var(--r)" stroke-width="2" fill="var(--o)"/>
<circle cx="32" cy="32" r="6" stroke-width="0" fill="var(--y)"/>
<ellipse cx="32" cy="14" rx="14" ry="8" stroke-width="0" fill="var(--b3)"/>
</svg>
</a>
</div>
</div>
<div class="main">
<div id="preamble" class="status">
<div class="content">
<h1>$title$</h1>
<div class="meta">
<span class="yyydate">$date$</span> on
<a href="https://her.esy.fun">
<span class="author">$author$</span>'s blog</a>
</div>
<div class="abstract">
$description$
</div>
</div>
</div>
<div id="content">
$body$
</div>
<div id="postamble" class="status">
<div class="content">
<nav>
<a href="/index.html">Home</a> |
<a href="/slides.html">Slides</a> |
<a href="/about-me.html">About</a>
<span class="details"> (<a href="https://gitea.esy.fun/yogsototh">code</a>
<a href="https://espial.esy.fun/u:yogsototh">bookmarks</a>
<a href="https://espial.esy.fun/u:yogsototh/notes">notes</a>)</span> |
<a href="#preamble">↑ Top ↑</a>
</nav>
</div>
</div>
</div>
</body>
</html>

View file

@ -3,10 +3,10 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{title}}</title>
<meta name="author" content="{{author}}">
<meta name="description" content="{{description}}">
<meta name="keywords" content="{{#tags}}{{.}}{{^last}} {{/last}}{{/tags}}">
<title>$title$</title>
<meta name="author" content="$author$">
<meta name="description" content="$description$">
<meta name="keywords" content="$keywords$">
<link rel="stylesheet" href="/css/y.css"/>
<link rel="alternate" type="application/rss+xml" href="/rss.xml" />
<link rel="icon" href="/favicon.ico">
@ -18,21 +18,21 @@
<div class="content">
<h1>{{title}}</h1>
<div class="meta">
<span class="article-date">{{date}}</span> on
<span class="article-date">$date$</span> on
<a href="https://her.esy.fun">
<span class="author">{{author}}</span>'s blog</a> -
<span class="author">$author$</span>'s blog</a> -
<a href="{{orgsource}}">source</a> -
<a href="{{txtsource}}">gmi</a> -
<a href="{{pdf}}">pdf</a> -
<a class="permalink" href="{{permalink}}">§permalink</a>
</div>
<div class="abstract">
{{description}}
$description$
</div>
</div>
</div>
<div id="content">
{{{body}}}
$body$
<br/>
<a href="{{geminiurl}}"><code>=> This article is also available on gemini</code></a>
</div>