-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
243 additions
and
183 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,48 @@ | ||
# Staticsite | ||
# Staticsite (Version 2) | ||
|
||
This is a simple static html blog generator using only 278 lines (as of this submission) of shell code. | ||
This is a simple static html blog generator using only 320 lines (as of this submission) of shell code. | ||
|
||
## Organization | ||
## Differences from Version 1 | ||
|
||
- Posts can now be spread over several folders. | ||
- Configuration takes place in the file blogconfig instead of the script. | ||
- There is no need for the use of INSERTBASEURL anymore since all html files are contained in the same folder. | ||
- Tagindex files are now located at `tag_<tagname>.html` | ||
- A post called `<post>.md` located in directory `<dir>` is located at `<dir>_<post>.html` | ||
- The compilation step does not compile posts that have not been changed. | ||
|
||
Posts are placed within the `posts` directory and are written in markdown, and have `.md` extension (anything else can be used to effectively save drafts inplace, for example). | ||
## Organization | ||
|
||
Each post begins with a metadata section delimited by lines containing nothing but dashes. | ||
Posts are placed within dedicated directories, written in markdown, and have `.md` extension (anything else can be used to effectively save drafts inplace, for example). | ||
|
||
Each post begins with a metadata section delimited by lines containing nothing but dashes `---`. | ||
The currently supported metadata is: `title:`, `date:`, `modified:`, `tags:`. | ||
|
||
The `tags` line is a space-separated list of tags that you may want to place in the file. | ||
- The `tags` line is a space-separated list of tags that you may want to place in the file. | ||
- The lines with `date` and `modified` are recomended to be in format `YYYY-MM-DD` since these can be easily ordered in lexicographic order. | ||
- The `title` line is the title of the post and it gets rendered as a heading at the top of the post. | ||
|
||
The script generates a `tagindex.html` page for each tag in a post, which by default only has the tag name as title and lists the posts tagged with that tag. | ||
The directories used by the script are registered at blogconfig in a line marked `postdirs: ` which is a space separated list of directory names (don't use directory names with spaces). | ||
|
||
Optionally, by creating the file `tag/<tag-name>/tagindex.md` the rendered markdown can be included above the list of posts. | ||
For each post `directory/post.md` the script compiles it to an html file located at `cache/directory_post.md` (notice the `_`), registers each tag `tagname` in the corresponding `cache/tag_tagname.html` file and registers the post at `index.html`. | ||
|
||
The main index.html file is created by providing `tag/MAININDEX/tagindex.md`. | ||
To view the output of the site after compilation simply point your browser to `cache/index.html`. | ||
|
||
Tag files can be enriched with an introduction by writing the corresponding `tag_tagname.md` file in the directory `indices`. Similar, a file named `index.md` in the directory `indices` will be rendered into the `index.html` file. | ||
|
||
## Dependencies | ||
|
||
The script uses mostly standard tools like sed(1) and awk(1) for text manipulation. The only non-standard tool that it makes use of is the lowdown(1) to compile markdown into html. | ||
The `compilesite` script depends on: | ||
- lowdown (for compiling markdown to html) | ||
- sqlite3 (for keeping a searchable database of the post metadata) | ||
|
||
## Running | ||
|
||
before running you should change the variables `blogname` and `baseurl` at the top of `makeposts.sh` | ||
before running you should change the `blogconfig` file to reflect your options. | ||
|
||
After writing all your posts, the whole thing can be compiled by running `./makeposts` and deployed into the default `/var/www/htdocs` by running `./deploy.sh` as root. | ||
After writing all your posts, the whole thing can be compiled by running `./compilesite` and deployed into the default `/var/www/htdocs` by running `./deploy` as root. | ||
|
||
## Notes | ||
|
||
This was written in openbsd and there may be slight differences in the syntax for sed and awk commands. | ||
|
||
To generate a locally viewable copy simply run `makeposts.sh local` and the resulting webpage saved in the `deploy` directory should be fully functional | ||
This was written in openbsd and there may be slight differences in the syntax for sed(1) and stat(1). If there is a failure with stat(1) the commented lines next to them run in archlinux. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
blogtitle: my blog title | ||
baseurl: https://my-url.com | ||
postdirs: posts otherposts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
#!/bin/sh | ||
|
||
yell() { echo ": $*" >&2; } | ||
die () { yell "$*"; exit 111; } | ||
try () { "$@" || die "cannot $*" ; } | ||
|
||
blogtitle=`try sed -n 's/blogtitle: *//p' blogconfig` | ||
postdirs=`try sed -n 's/postdirs: *//p' blogconfig` | ||
baseurl=`try sed -n 's/baseurl: *//p' blogconfig` | ||
|
||
mkdir -p cache | ||
|
||
touch cache/dirtytags | ||
dirty=0 | ||
|
||
# open database | ||
sqlite3 cache/posts.db "create table if not exists posts ( title TEXT, prefix TEXT, date TEXT, modified TEXT, tag TEXT)" | ||
|
||
isnewer () { | ||
new=$1 | ||
old=$2 | ||
####### in open bsd | ||
newstamp=`stat -f "%Sm" -t "%Y%m%d%H%M%S" $new` | ||
#newstamp=`stat -c "%Y" $new` | ||
if [ ! -f $old ]; then | ||
echo "0" | ||
return 0 | ||
fi | ||
|
||
oldstamp=`stat -f "%Sm" -t "%Y%m%d%H%M%S" $old` | ||
#oldstamp=`stat -c "%Y" $old` | ||
if [ $newstamp -ge $oldstamp ]; then | ||
echo "0" | ||
else | ||
echo "1" | ||
fi | ||
return 0 | ||
} | ||
|
||
processheader () { | ||
# add or update post entry(/ies) in database | ||
fileprefix=$1 | ||
header=cache/$fileprefix.head | ||
title=`sed -n 's/^title: *//p' $header` | ||
date=`sed -n 's/^date: *//p' $header` | ||
modified=`sed -n 's/^modified: *//p' $header` | ||
if [ "$modified" = "" ]; then | ||
modified=$date | ||
fi | ||
sqlite3 cache/posts.db "delete from posts where prefix = \"$fileprefix\"" | ||
tags=`sed -n 's/^tags: *//p' $header` | ||
if [ "$tags" = "" ]; then | ||
sqlite3 cache/posts.db "insert into posts values (\"$title\",\"$fileprefix\",\"$date\",\"$modified\",\"\")" | ||
else | ||
for tag in $tags; do | ||
sqlite3 cache/posts.db "insert into posts values (\"$title\",\"$fileprefix\",\"$date\",\"$modified\",\"$tag\")" | ||
done | ||
fi | ||
} | ||
|
||
htmlhead () { | ||
prefix=$1 | ||
title=`sqlite3 cache/posts.db "select distinct title from posts where prefix = \"$prefix\""` | ||
echo "<title>${blogtitle}:${title}</title>" | ||
} | ||
|
||
dateandtags () { | ||
prefix=$1 | ||
date=`sqlite3 cache/posts.db "select distinct date from posts where prefix = \"$prefix\""` | ||
echo "<b>published: ${date}</b>" | ||
modified=`sqlite3 cache/posts.db "select distinct modified from posts where prefix = \"$prefix\""` | ||
if [ ! "$date" = "$modified" ] ; then | ||
echo "<b>last modified: ${modified}</b>" | ||
fi | ||
echo "<br/>" | ||
tags=`sqlite3 cache/posts.db "select distinct tag from posts where prefix = \"$prefix\""` | ||
for tag in $tags; do | ||
echo $tag >> cache/dirtytags | ||
echo "<a href=tag_${tag}.html>${tag}</a>" | ||
done | ||
} | ||
|
||
|
||
htmlbody () { | ||
prefix=$1 | ||
title=`sqlite3 cache/posts.db "select distinct title from posts where prefix = \"$prefix\""` | ||
echo "<h1 class=\"blog-title\"><a href=\"index.html\">${blogtitle}</a></h1>" | ||
echo "<h1 class=\"post-title\">${title}</h1>" | ||
dateandtags $prefix | ||
lowdown -e math cache/${prefix}.body | ||
} | ||
|
||
|
||
metadatawarning() { | ||
post=$1 | ||
cat << EOF | ||
WARNING, there may be a problem with processing metadata in $post, please make | ||
sure that there are exactly 2 instances of lines comprising _only_ dashes at | ||
the head of the file, and containing nothing but the metadata in between. | ||
EOF | ||
grep '^--*$' -n -C1 $post | ||
} | ||
|
||
processpost () { | ||
post=$1 | ||
baseurl=$2 | ||
outprefix=`echo $post | sed 's@/@_@g;s/.md$//'` | ||
recompute=`isnewer $post cache/$outprefix.html` | ||
if [ "$recompute" = "0" ]; then | ||
echo processing $post | ||
dirty=1 | ||
sed -n '/^--*$/,/^--*$/p' $post | sed '1d;$d' > cache/$outprefix.head | ||
sed '/^--*$/,/^--*$/d' $post > cache/$outprefix.body | ||
nbars=`sed -n '/^--*$/p' $post | wc -l` | ||
if [ $nbars -ne 2 ]; then | ||
metadatawarning $post >&2 | ||
fi | ||
processheader $outprefix | ||
htmlbody $outprefix > cache/${outprefix}_body.html | ||
htmlhead $outprefix > cache/${outprefix}_head.html | ||
./html-templater -h cache/${outprefix}_head.html cache/${outprefix}_body.html > cache/${outprefix}.html | ||
# rm cache/${outprefix}_body.html cache/${outprefix}_head.html cache/${outprefix}.head cache/${outprefix}.body | ||
fi | ||
} | ||
|
||
processdir () { | ||
dir=$1 | ||
baseurl=$2 | ||
|
||
# fail if directory doesn't exist | ||
[ -d $dir ] || die "FAILED no such directory \"$dir\"" | ||
|
||
# fail silently if directory doesn't have posts | ||
for post in `ls $dir/*.md 2>/dev/null`; do | ||
processpost $post $baseurl | ||
done | ||
} | ||
|
||
makeindex () { | ||
headfile=cache/index_head.html | ||
bodyfile=cache/index_body.html | ||
printf "<title>${blogtitle}</title>" > $headfile | ||
printf "<h1 class=\"blog-title\">%s</h1>\n" $blogtitle > $bodyfile | ||
if [ -f "indices/index.md" ]; then | ||
lowdown -e math indices/index.md | sed "s@INSERTBASEURL@$baseurl@g" >> $bodyfile | ||
fi | ||
echo >> $bodyfile | ||
prefixes=`sqlite3 cache/posts.db "select distinct prefix from posts order by date desc"` | ||
for prefix in $prefixes; do | ||
indexline $prefix >> $bodyfile | ||
done | ||
./html-templater -h $headfile $bodyfile > cache/index.html | ||
rm $headfile $bodyfile | ||
} | ||
|
||
maketagindex () { | ||
tags=`cat cache/dirtytags | sort | uniq` | ||
for tag in $tags; do | ||
headfile=cache/tag_${tag}_head.html | ||
bodyfile=cache/tag_${tag}_body.html | ||
printf "<title>${blogtitle} - ${tag} (tag)</title>" > $headfile | ||
printf "<h1 class=\"blog-title\">%s</h1>\n" $blogtitle > $bodyfile | ||
printf "<h2 class=\"blog-title\">%s</h1>\n" $tag >> $bodyfile | ||
if [ -f "indices/tag_${tag}.md" ]; then | ||
lowdown -e math indices/tag_${tag}.md | sed "s@INSERTBASEURL@$baseurl@g" >> $bodyfile | ||
fi | ||
echo >> $bodyfile | ||
prefixes=`sqlite3 cache/posts.db "select distinct prefix from posts where tag = \"$tag\" order by date desc"` | ||
for prefix in $prefixes; do | ||
indexline $prefix >> $bodyfile | ||
done | ||
./html-templater -h $headfile $bodyfile > cache/tag_${tag}.html | ||
rm $headfile $bodyfile | ||
done | ||
} | ||
|
||
indexline () { | ||
prefix=$1 | ||
title=`sqlite3 cache/posts.db "select distinct title from posts where prefix = \"$prefix\""` | ||
printf "<h3 class=\"indexline-title\"><a href=\"$prefix.html\">%s</a></h3>\n" "$title" | ||
dateandtags $prefix | ||
} | ||
|
||
# process each of the directories | ||
for dir in $postdirs; do | ||
try processdir $dir $baseurl | ||
done | ||
|
||
# reindex | ||
maketagindex | ||
if [ $dirty = 1 ]; then | ||
makeindex | ||
fi | ||
|
||
# vi: et ts=4 sts=4 : |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/bin/sh | ||
|
||
for file in cache/*.html; | ||
do | ||
filename=${file##cache/} | ||
install -m 500 -o www -g www cache/$filename /var/www/htdocs/$filename | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Welcome to my new static website! | ||
Behold how nothing moves! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This tag is utterly useless. |
Oops, something went wrong.