Switch to Makefile + ssg build system; add a dynamic nav
The old build system worked, but ssg adds some features while still being simple and easy to hack on: * set page title from the h1 tag, rather than the file name * generate a sitemap (which we adapt to also generate a nav) This site doesn't need a dynamic nav, but the Anarchy Planet docs site will have a lot of rapidly changing pages and will benefit from a dynamic nav. This way we can use the same build system for both sites.
This commit is contained in:
parent
5f0252aedc
commit
05b50d5c5f
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
dst
|
||||
tmp
|
||||
|
13
Makefile
Normal file
13
Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
include config.mk
|
||||
|
||||
SRC ?= src
|
||||
DST ?= dst
|
||||
|
||||
all: html
|
||||
|
||||
html:
|
||||
$(SSG) $(SRC) $(DST) $(TITLE) $(BASE_URL) $(CONTACT_EMAIL)
|
||||
|
||||
clean:
|
||||
@rm -f $(DST)/*
|
||||
@rm -f $(DST)/.files
|
66
README.md
66
README.md
@ -1,26 +1,20 @@
|
||||
# Anarchy Planet web site
|
||||
|
||||
This repo is to generate a static site for anarchyplanet.org to
|
||||
replace the existing site. The goal is to generate the site from
|
||||
markdown files by converting the markdown to html and applying minimal
|
||||
styling.
|
||||
This repo includes markdown files for [the Anarchy Planet web
|
||||
site](https://anarchyplanet.org/) and tools to generate a static
|
||||
HTML site from the source files.
|
||||
|
||||
The advantage to this method is that all of the content can be
|
||||
contained in a single directory without being obscured by the rest of
|
||||
the code that's needed to make a website run (such as html). This will
|
||||
(eventually!) make it easy to update content as well as export into
|
||||
other formats or potential website generators.
|
||||
|
||||
This informal README will be replaced with an official README with
|
||||
instructions for how to contribute to the site, but first we have to
|
||||
figure out how ourselves! All methods are also open for discussion,
|
||||
the only requirement that notnull hopes for is pure markdown files in
|
||||
a single directory, but sceox is welcome to change publish.sh to a
|
||||
make script. :)
|
||||
|
||||
You can see this method in action (maybe! if we didn't break it) at
|
||||
You can see this method in action at
|
||||
[https://testing.anarchyplanet.org](https://testing.anarchyplanet.org).
|
||||
|
||||
## Contributing
|
||||
|
||||
If you are familiar with editing markdown and using git, you should
|
||||
already be able to figure out how to contribute.
|
||||
|
||||
TODO: write docs for someone who's not familiar with editing markdown
|
||||
and/or using git.
|
||||
|
||||
## Dependencies
|
||||
|
||||
We use [lowdown](https://kristaps.bsd.lv/lowdown/) for markdown
|
||||
@ -31,22 +25,24 @@ conversion. See its documentation:
|
||||
* [lowdown(5)](https://kristaps.bsd.lv/lowdown/lowdown.5.html) which
|
||||
describes the lanuage syntax
|
||||
|
||||
The rest of the heavy lifting is done by a modified version of
|
||||
[ssg](https://www.romanzolotarev.com/ssg.html) which is included
|
||||
in this source code.
|
||||
|
||||
## TODOs
|
||||
|
||||
### TODO discuss and decide on sections
|
||||
|
||||
notnull's proposals for the sections are:
|
||||
|
||||
- home
|
||||
- projects (not services)
|
||||
- webring (instead of 'others')
|
||||
- contact (probably just a mailto: link)
|
||||
|
||||
### TODO write copy for sections
|
||||
|
||||
What rocinante has done on
|
||||
[anarchist news](https://anarchistnews.org/content/anarchy-planet) is
|
||||
already pretty great. Maybe these could be more verbose, but maybe
|
||||
they are fine the way they are!
|
||||
|
||||
### TODO we need a favicon
|
||||
* [ ] TODO discuss and decide on sections
|
||||
- notnull's proposals for the sections are:
|
||||
* home
|
||||
* projects (not services)
|
||||
* webring (instead of 'others')
|
||||
* contact (probably just a mailto: link)
|
||||
* [ ] write copy for sections
|
||||
- What rocinante has done on
|
||||
[anarchist news](https://anarchistnews.org/content/anarchy-planet)
|
||||
is already pretty great. Maybe these could be more verbose, but
|
||||
maybe they are fine the way they are!
|
||||
* [ ] add a favicon
|
||||
* [ ] use an automatic toc generator
|
||||
- and add to Makefile (make toc)
|
||||
- see https://github.com/ekalinin/github-markdown-toc
|
||||
|
10
config.mk
Normal file
10
config.mk
Normal file
@ -0,0 +1,10 @@
|
||||
TITLE = "Anarchy Planet"
|
||||
BASE_URL = "anarchyplanet.org"
|
||||
CONTACT_EMAIL = "contact@anarchyplanet.org"
|
||||
|
||||
# static site generator
|
||||
SSG = ./ssg6
|
||||
|
||||
# source and destination directories
|
||||
SRC = src
|
||||
DST = dst
|
@ -1,5 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="style.css">
|
6
nav.html
6
nav.html
@ -1,6 +0,0 @@
|
||||
<nav>
|
||||
<a href="/index.html">home</a>
|
||||
<a href="/projects.html">projects</a>
|
||||
<a href="/webring.html">webring</a>
|
||||
<a href="mailto:join@anarchyplanet.org">contact</a>
|
||||
</nav>
|
30
publish.sh
30
publish.sh
@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PUB_DIR=${1:-/home/html/planet/static}
|
||||
MD_FILES=md/*.md
|
||||
OTHER_FILES=*.css
|
||||
|
||||
if ! test -d $PUB_DIR; then
|
||||
echo "error: PUB_DIR does not exist:" $PUB_DIR
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -d tmp || mkdir tmp
|
||||
|
||||
for f in $MD_FILES
|
||||
do
|
||||
filename=$(basename -- $f .md)
|
||||
echo "publishing md/$filename.md to $PUB_DIR/$filename.html"
|
||||
lowdown -o tmp/$filename.html $f
|
||||
sed -i 's/^/ /' tmp/$filename.html
|
||||
cp head.html tmp/
|
||||
# set the title
|
||||
title="$(echo $filename | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) substr($i,2) }}1')"
|
||||
echo " <title>$title • Anarchy Planet</title>" >> tmp/head.html
|
||||
echo " </head>" >> tmp/head.html
|
||||
echo " <body>" >> tmp/head.html
|
||||
# compile the elements in order
|
||||
cat tmp/head.html nav.html tmp/$filename.html foot.html tail.html \
|
||||
> $PUB_DIR/$filename.html
|
||||
done
|
||||
cp $OTHER_FILES $PUB_DIR
|
7
src/_header.html
Normal file
7
src/_header.html
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="/style.css">
|
||||
</head>
|
275
ssg6
Executable file
275
ssg6
Executable file
@ -0,0 +1,275 @@
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# https://rgz.ee/bin/ssg6
|
||||
# Copyright 2018-2019 Roman Zolotarev <hi@romanzolotarev.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
main() {
|
||||
test -n "$1" || usage
|
||||
test -n "$2" || usage
|
||||
test -n "$3" || usage
|
||||
test -n "$4" || usage
|
||||
test -d "$1" || no_dir "$1"
|
||||
test -d "$2" || no_dir "$2"
|
||||
|
||||
src=$(readlink_f "$1")
|
||||
dst=$(readlink_f "$2")
|
||||
tmp=/tmp/ssg
|
||||
test -d $tmp || mkdir -p $tmp
|
||||
|
||||
IGNORE=$(
|
||||
if ! test -f "$src/.ssgignore"; then
|
||||
printf ' ! -path "*/.*"'
|
||||
return
|
||||
fi
|
||||
while read -r x; do
|
||||
test -n "$x" || continue
|
||||
printf ' ! -path "*/%s*"' "$x"
|
||||
done <"$src/.ssgignore"
|
||||
)
|
||||
|
||||
# files
|
||||
|
||||
title="$3"
|
||||
|
||||
h_file="$src/_header.html"
|
||||
nav_file="$tmp/_nav.html"
|
||||
foot_file="$src/_footer.html"
|
||||
|
||||
test -n "$5" && contact_email="$5"
|
||||
|
||||
urls=$(list_pages "$src")
|
||||
test -n "$urls" &&
|
||||
render_nav "$urls" "$base_url" "$title" "$contact_email" >"$nav_file"
|
||||
|
||||
test -f "$foot_file" && FOOTER=$(cat "$foot_file") && export FOOTER
|
||||
if test -f "$nav_file"; then
|
||||
cat $h_file $nav_file > "$tmp/_header.html"
|
||||
h_file="$tmp/_header.html"
|
||||
fi
|
||||
test -f "$h_file" && HEADER=$(cat "$h_file") && export HEADER
|
||||
|
||||
list_dirs "$src" |
|
||||
(cd "$src" && cpio -pdu "$dst")
|
||||
|
||||
fs=$(
|
||||
if test -f "$dst/.files"; then
|
||||
list_affected_files "$src" "$dst/.files"
|
||||
else
|
||||
list_files "$1"
|
||||
fi
|
||||
)
|
||||
|
||||
if test -n "$fs"; then
|
||||
echo "$fs" | tee "$dst/.files"
|
||||
|
||||
if echo "$fs" | grep -q '\.md$'; then
|
||||
if test -x "$(which lowdown 2>/dev/null)"; then
|
||||
echo "$fs" | grep '\.md$' |
|
||||
render_md_files_lowdown "$src" "$dst" "$title"
|
||||
else
|
||||
if test -x "$(which Markdown.pl 2>/dev/null)"; then
|
||||
echo "$fs" | grep '\.md$' |
|
||||
render_md_files_Markdown_pl "$src" "$dst" "$title"
|
||||
else
|
||||
echo "couldn't find lowdown nor Markdown.pl"
|
||||
exit 3
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$fs" | grep '\.html$' |
|
||||
render_html_files "$src" "$dst" "$title"
|
||||
|
||||
echo "$fs" | grep -Ev '\.md$|\.html$' |
|
||||
(cd "$src" && cpio -pu "$dst")
|
||||
fi
|
||||
|
||||
printf '[ssg] ' >&2
|
||||
print_status 'file, ' 'files, ' "$fs" >&2
|
||||
|
||||
# sitemap
|
||||
|
||||
base_url="$4"
|
||||
date=$(date +%Y-%m-%d)
|
||||
|
||||
test -n "$urls" &&
|
||||
render_sitemap "$urls" "$base_url" "$date" >"$dst/sitemap.xml"
|
||||
|
||||
print_status 'url' 'urls' "$urls" >&2
|
||||
echo >&2
|
||||
}
|
||||
|
||||
readlink_f() {
|
||||
file="$1"
|
||||
cd "$(dirname "$file")"
|
||||
file=$(basename "$file")
|
||||
while test -L "$file"; do
|
||||
file=$(readlink "$file")
|
||||
cd "$(dirname "$file")"
|
||||
file=$(basename "$file")
|
||||
done
|
||||
dir=$(pwd -P)
|
||||
echo "$dir/$file"
|
||||
}
|
||||
|
||||
print_status() {
|
||||
test -z "$3" && printf 'no %s' "$2" && return
|
||||
|
||||
echo "$3" | awk -v singular="$1" -v plural="$2" '
|
||||
END {
|
||||
if (NR==1) printf NR " " singular
|
||||
if (NR>1) printf NR " " plural
|
||||
}'
|
||||
}
|
||||
|
||||
usage() {
|
||||
echo "usage: ${0##*/} src dst title base_url [contact_email]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
no_dir() {
|
||||
echo "${0##*/}: $1: No such directory" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
list_dirs() {
|
||||
cd "$1" && eval "find . -type d ! -name '.' ! -path '*/_*' $IGNORE"
|
||||
}
|
||||
|
||||
list_files() {
|
||||
cd "$1" && eval "find . -type f ! -name '.' ! -path '*/_*' $IGNORE"
|
||||
}
|
||||
|
||||
list_dependant_files() {
|
||||
e="\\( -name '*.html' -o -name '*.md' -o -name '*.css' -o -name '*.js' \\)"
|
||||
cd "$1" && eval "find . -type f ! -name '.' ! -path '*/_*' $IGNORE $e"
|
||||
}
|
||||
|
||||
list_newer_files() {
|
||||
cd "$1" && eval "find . -type f ! -name '.' $IGNORE -newer $2"
|
||||
}
|
||||
|
||||
has_partials() {
|
||||
grep -qE '^./_.*\.html$|^./_.*\.js$|^./_.*\.css$'
|
||||
}
|
||||
|
||||
list_affected_files() {
|
||||
fs=$(list_newer_files "$1" "$2")
|
||||
|
||||
if echo "$fs" | has_partials; then
|
||||
list_dependant_files "$1"
|
||||
else
|
||||
echo "$fs"
|
||||
fi
|
||||
}
|
||||
|
||||
render_html_files() {
|
||||
while read -r f; do
|
||||
render_html_file "$3" <"$1/$f" >"$2/$f"
|
||||
done
|
||||
}
|
||||
|
||||
render_md_files_lowdown() {
|
||||
while read -r f; do
|
||||
lowdown \
|
||||
--html-no-escapehtml \
|
||||
--html-no-skiphtml \
|
||||
--parse-no-metadata \
|
||||
--parse-no-autolink <"$1/$f" |
|
||||
render_html_file "$3" \
|
||||
>"$2/${f%\.md}.html"
|
||||
done
|
||||
}
|
||||
|
||||
render_md_files_Markdown_pl() {
|
||||
while read -r f; do
|
||||
Markdown.pl <"$1/$f" |
|
||||
render_html_file "$3" \
|
||||
>"$2/${f%\.md}.html"
|
||||
done
|
||||
}
|
||||
|
||||
render_html_file() {
|
||||
# h/t Devin Teske
|
||||
awk -v title="$1" '
|
||||
{ body = body "\n" $0 }
|
||||
END {
|
||||
body = substr(body, 2)
|
||||
if (body ~ /<\/?[Hh][Tt][Mm][Ll]/) {
|
||||
print body
|
||||
exit
|
||||
}
|
||||
if (match(body, /<[[:space:]]*[Hh]1(>|[[:space:]][^>]*>)/)) {
|
||||
t = substr(body, RSTART + RLENGTH)
|
||||
sub("<[[:space:]]*/[[:space:]]*[Hh]1.*", "", t)
|
||||
gsub(/^[[:space:]]*|[[:space:]]$/, "", t)
|
||||
if (t) title = t " — " title
|
||||
}
|
||||
n = split(ENVIRON["HEADER"], header, /\n/)
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (match(tolower(header[i]), "<title></title>")) {
|
||||
head = substr(header[i], 1, RSTART - 1)
|
||||
tail = substr(header[i], RSTART + RLENGTH)
|
||||
print head "<title>" title "</title>" tail
|
||||
} else print header[i]
|
||||
}
|
||||
print body
|
||||
print ENVIRON["FOOTER"]
|
||||
}'
|
||||
}
|
||||
|
||||
list_pages() {
|
||||
e="\\( -name '*.html' -o -name '*.md' \\)"
|
||||
cd "$1" && eval "find . -type f ! -path '*/.*' ! -path '*/_*' $IGNORE $e" |
|
||||
sed 's#^./##;s#.md$#.html#;s#/index.html$#/#'
|
||||
}
|
||||
|
||||
render_sitemap() {
|
||||
urls="$1"
|
||||
base_url="$2"
|
||||
date="$3"
|
||||
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>'
|
||||
echo '<urlset'
|
||||
echo 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
|
||||
echo 'xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9'
|
||||
echo 'http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"'
|
||||
echo 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'
|
||||
echo "$urls" |
|
||||
sed -E 's#^(.*)$#<url><loc>'"$base_url"'/\1</loc><lastmod>'"$date"'</lastmod><priority>1.0</priority></url>#'
|
||||
echo '</urlset>'
|
||||
}
|
||||
render_nav() {
|
||||
urls="$1"
|
||||
base_url="$2"
|
||||
title="$3"
|
||||
contact_email="$4" # optional
|
||||
|
||||
echo '<header>'
|
||||
echo '<nav>'
|
||||
echo "<h2>${title}</h2>"
|
||||
echo '<ul>'
|
||||
echo "$urls" |
|
||||
sed -E 's#^(.*)\.(.*)$# <li><a href="'"$base_url"'/\1.\2">\1</a></li>#'
|
||||
test -n "$contact_email" &&
|
||||
echo ' <li><a href="mailto:'"$contact_email"'">contact</a>'
|
||||
echo '</ul>'
|
||||
echo '</nav>'
|
||||
echo '</header>'
|
||||
echo '<main>'
|
||||
}
|
||||
|
||||
main "$@"
|
Loading…
Reference in New Issue
Block a user