Skip to content

Commit

Permalink
version 2
Browse files Browse the repository at this point in the history
  • Loading branch information
crvs committed Dec 31, 2019
1 parent 4c9c099 commit bc55a84
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 183 deletions.
42 changes: 27 additions & 15 deletions README.md
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.

3 changes: 3 additions & 0 deletions blogconfig
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
195 changes: 195 additions & 0 deletions compilesite
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 :
7 changes: 7 additions & 0 deletions deploy
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
11 changes: 0 additions & 11 deletions deploy.sh

This file was deleted.

2 changes: 2 additions & 0 deletions indices/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Welcome to my new static website!
Behold how nothing moves!
1 change: 1 addition & 0 deletions indices/tag_useless.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This tag is utterly useless.
Loading

0 comments on commit bc55a84

Please sign in to comment.