summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <git@mx.buetow.org>2021-05-21 05:18:10 +0100
committerPaul Buetow <git@mx.buetow.org>2021-05-21 05:18:10 +0100
commit85df071aa1a5aa73328fdc5969d3ca0ed9df2c08 (patch)
treeec8c11c9e1ad5dfa02c15e57212b239b75e52c87
parent9dbd7f008192fd506bf642944232334fad0ed55c (diff)
add readme
-rw-r--r--LICENSE24
-rw-r--r--README.md108
-rw-r--r--buetow.org.conf9
-rwxr-xr-xbuetow.org.sh107
-rw-r--r--footer.html.part2
-rw-r--r--header.html.part50
-rw-r--r--packages/assert.source.sh59
-rw-r--r--packages/atomfeed.source.sh128
-rw-r--r--packages/gemfeed.source.sh54
-rw-r--r--packages/generate.source.sh160
-rw-r--r--packages/git.source.sh50
-rw-r--r--packages/html.source.sh162
-rw-r--r--packages/log.source.sh30
-rw-r--r--packages/md.source.sh63
14 files changed, 2 insertions, 1004 deletions
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index fdddb29a..00000000
--- a/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-This is free and unencumbered software released into the public domain.
-
-Anyone is free to copy, modify, publish, use, compile, sell, or
-distribute this software, either in source code form or as a compiled
-binary, for any purpose, commercial or non-commercial, and by any
-means.
-
-In jurisdictions that recognize copyright laws, the author or authors
-of this software dedicate any and all copyright interest in the
-software to the public domain. We make this dedication for the benefit
-of the public at large and to the detriment of our heirs and
-successors. We intend this dedication to be an overt act of
-relinquishment in perpetuity of all present and future rights to this
-software under copyright law.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-For more information, please refer to <https://unlicense.org>
diff --git a/README.md b/README.md
index e162309d..f6d3aa4f 100644
--- a/README.md
+++ b/README.md
@@ -1,110 +1,6 @@
The buetow.org internet site
============================
-This is the source code of my personal internet site and blog engine. All content is written in Gemini Gemtext format, but the script `buetow.org.sh` generates multiple other static output formats from it. You can reach the site(s)...
+This repository contains the static files of my internet site. [gemini://buetow.org](gemini://buetow.org) and [https://buetow.org](https://buetow.org).
-* Via Gemini/Gemtext: [gemini://buetow.org](gemini://buetow.org) (You need a Gemini client for this)
-* Via "normal" HTML: [https://buetow.org](https://buetow.org) (Actually it's XHTML Transitional 1.0)
-* Via [Gemini Webproxy](https://portal.mozz.us/gemini/buetow.org)
-* Via [GitHub Markdown](https://github.com/snonux/buetow.org/blob/content-md/index.md)
-* Via [GitHub Page](https://snonux.github.io/buetow.org) (from Markdown)
-
-Have a look at the `content-*` branches of this buetow.org Git project for source samples.
-
-## Software I use to maintain this site
-
-* Text editor: [Vim](https://www.vim.org)
-* Gemini server: [a-h/gemini](https://github.com/a-h/gemini)
-* Bash
-* ShellCheck (if you want to run the tests)
-* Web server: [Apache HTTPD](https://httpd.apache.org) (for "normal" HTML site)
-* Obviously, I am also using GitHub for source code and GitHub Page hosting.
-
-# Getting started
-
-## Requirements
-
-These are the requirements of the `buetow.org.sh` static site generator script:
-
-* GNU Bash 5.x or higher
-* ShellCheck installed
-* GNU Sed
-* GNU Date
-* Git
-
-The script was tested on a recent Fedora Linux. For *BSD or macOS you would need to install GNU Sed, GNU Date, and a newer version of Bash.
-
-## Usage
-
-So you want such a pretty internet site too?
-
-To get started, just clone this repo (master branch) and run `./buetow.org.sh`. You will will be prompted with further instructions.
-
-You will notice soon, that all site content is located in `../buetow.org-content/` (you can configure the `BASE_CONTENT_DIR` in `buetow.org.conf`). There is one sub-directory per output format, e.g.:
-
-```
-../buetow.org-content/gemtext
-../buetow.org-content/html
-../buetow.org-content/md
-../buetow.org-content/meta
-```
-
-### Alternative config file path
-
-If you don't want to mess with `buetow.org.conf`, you can use an alternative config file path in `~/.config/buetow.org.conf`, which takes precedence if it exists. Another way is to set the `CONFIG_FILE_PATH` environment variable, e.g.:
-
-```
-export CONFIG_FILE_PATH=~/.config/my-site.geek.conf
-./buetow.org.sh --generate
-```
-
-### What is what
-
-Whereas, you only want to directly edit/add/remove content in the `gemtext` folder. The `buetow.org.sh` then will take the Gemtext and update all other formats accordingly. Summary of what is what:
-
-* `gemtext`: The Gemini Gemtext markup files of the internet site.
-* `html`: The XHTML version of it.
-* `md`: The Markdown version of it.
-* `meta`: Some meta data of all Gemtext blog posts. It's used by `buetow.org.sh` internally for Atom feed generation.
-
-### Special HTML configuration
-
-You will find the `./header.html.part` and `./footer.html.part` files, they are minimal template files for the HTML generation.
-
-### Special Markdown configuraiton
-
-`buetow.org.sh` will never touch the `../buetow.org-content/md/_config.yml` file (if it exists). That's a special configuration file for GitHub Pages.
-
-## Store all formats in Git
-
-I personally have for each directory in `../buetow.org-content/` a separate Git repository configured. So whenever something has changed it will be updated/added/removed to version control. The following will run the generator and commit everything to Git:
-
-```
-USE_GIT=yes ./buetow.org --generate
-```
-
-And the following will additionally perform a `git pull` and `git push` afterwards;
-
-```
-USE_GIT=yes GIT_PUSH=yes ./buetow.org --generate
-```
-
-You could add the `USE_GIT` and `GIT_PUSH` options to the `buetow.org.conf` config file too.
-
-## Publishing a blog post
-
-All what needs to be done is to create a new file in `./gemtext/gemfeed/YYYY-MM-DD-article-title-dash-separated.gmi`, whereas `YYYY-MM-DD` defines the publishing date of the blog post.
-
-A subsequent `./buetow.org.sh --generate` will then detect the new post and link it from `$BASE_CONTENT_DIR/gemtext/gemfeed/index.gmi`, link it from the main index `$BASE_CONTENT_DIR/gemtext/index.gmi`, and also add it to the Atom feed at `$BASE_CONTENT_DIR/gemtext/gemfeed/atom.xml`. The first level 1 Gemtext title (e.g. `# Title`) will be the displayed link name. `YYYY-MM-DD` will be the publishing date. There are various other settings, such as Author - they come from the `buetow.org.conf` configuration file.
-
-Once all of that is done, the `buetow.org.sh` script will convert the new post (plus all the indices and the Atom feed) to the other formats too (e.g. HTML, Markdown).
-
-You can also have a look at `$BASE_CONTENT_DIR/meta/gemfeed`. There is a meta file for each blog post stored. These meta files are required for the generation of the Atom feed. You can edit these meta files manually and run `./buetow.org.sh --generate` or `./buetow.org.sh --feed` again, in case you want to change some of the Atom feed content.
-
-## Finito
-
-After running `./buetow.org --genreate` you will have all static files ready to be published. But before you do that you could preview the content with `firefox ../buetow.org-content/html/index.html` or `glow ../buetow.org-content/md/index.md` (you get the idea).
-
-Have also a look at the generated `atom.xml` files. They make sense (at least) for Gemtext and HTML.
-
-Now it is up to you to setup a Gemini server for the Gemtext, a Webserver for the HTML and/or a GitHub page for the Markdowns.
+You can find more about my internet site and the static content generator at [snonux/gemtexter](https://github.com/snonux/gemtexter).
diff --git a/buetow.org.conf b/buetow.org.conf
deleted file mode 100644
index effeaef6..00000000
--- a/buetow.org.conf
+++ /dev/null
@@ -1,9 +0,0 @@
-declare -xr DOMAIN=buetow.org
-declare -xr SUBTITLE='Having fun with computers!'
-declare -xr AUTHOR='Paul Buetow'
-declare -xr EMAIL='comments@mx.buetow.org'
-declare -xr IMAGE_PATTERN='\.(jpg|png|gif)$'
-declare -xr ATOM_MAX_ENTRIES=42
-declare -xr CONTENT_BASE_DIR=../buetow.org-content
-declare -xr HTML_HEADER=./header.html.part
-declare -xr HTML_FOOTER=./header.html.part
diff --git a/buetow.org.sh b/buetow.org.sh
deleted file mode 100755
index 29eadbd0..00000000
--- a/buetow.org.sh
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env bash
-#
-# The buetow.org.sh static site generator
-# by Paul Buetow 2021
-
-declare -r ARG="$1"; shift
-declare DATE=date
-declare SED=sed
-declare GREP=grep
-which gdate &>/dev/null && DATE=gdate
-which gsed &>/dev/null && SED=gsed
-which ggrep &>/dev/null && GREP=ggrep
-readonly DATE
-readonly SED
-readonly GREP
-
-set -e
-
-if [[ -n "$CONFIG_FILE_PATH" ]]; then
- source "$CONFIG_FILE_PATH"
-elif [[ -f ~/.config/buetow.org.conf ]]; then
- source ~/.config/buetow.org.conf
-else
- source ./buetow.org.conf
-fi
-
-source ./packages/assert.source.sh
-source ./packages/git.source.sh
-source ./packages/atomfeed.source.sh
-source ./packages/gemfeed.source.sh
-source ./packages/generate.source.sh
-source ./packages/html.source.sh
-source ./packages/log.source.sh
-source ./packages/md.source.sh
-
-help () {
- cat <<HELPHERE
-$0's possible arguments:
- --feed Generates Gemtext Atom feed and Gemfeed.
- --generate Generates all known output formats (html, md, ...).
- If USE_GIT=yes set, all files will be commited to git too.
- If GIT_PUSH=yes is set, all content will be pushed to origin.
- --test Only runs some shellcheck and unit tests.
- --help Prints this retty text.
-Example:
- USE_GIT=yes GIT_PUSH=yes $0 --generate
-HELPHERE
-}
-
-setup () {
- if [ ! -d "$CONTENT_BASE_DIR" ]; then
- cat <<END
-The content base directory, does not exist. Run the following to create it, it
-also adds some sample Gemtext content:
-
- mkdir -p $CONTENT_BASE_DIR/{meta,md,html}
- git clone --branch content-gemtext https://github.com/snonux/buetow.org $CONTENT_BASE_DIR/gemtext
- rm -Rf $CONTENT_BASE_DIR/gemtext/.git
-
-Once done, you are ready to edit the files in $CONTENT_BASE_DIR/gemtext. Every
-time you want to generate other formats from Gemtext (e.g. HTML, Markdown), run
- $0 --generate
-again.
-
-For a list of other available arguments run
- $0 --help
-
-Pro tip: You could make all the directories in $CONTENT_BASE_DIR separate git
-repositories or branches. You can then run
- USE_GIT=yes $0 --generate
-so that all static files are commited to the content repositories too.
-END
- exit 1
- fi
-}
-
-main () {
- local -r arg="$1"; shift
-
- setup
-
- case $arg in
- --test)
- LOG_VERBOSE=yes
- assert::shellcheck
- html::test
- md::test
- ;;
- --feed)
- gemfeed::generate
- atomfeed::generate
- ;;
- --generate)
- gemfeed::generate
- atomfeed::generate
- generate::fromgmi html md
- ;;
- --help|*)
- help
- ;;
- esac
-
- return 0
-}
-
-main "$ARG"
-exit $?
diff --git a/footer.html.part b/footer.html.part
deleted file mode 100644
index 308b1d01..00000000
--- a/footer.html.part
+++ /dev/null
@@ -1,2 +0,0 @@
-</body>
-</html>
diff --git a/header.html.part b/header.html.part
deleted file mode 100644
index d499e512..00000000
--- a/header.html.part
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<title>%%TITLE%%</title>
-<link rel="shortcut icon" type="image/gif" href="/favicon.ico" />
-<style type="text/css">
-body {
- margin: auto;
- max-width: 900px;
- background-color: #FFFFEF;
- border: 1px dashed #880000;
- border-radius: 8px;
- padding: 5px;
-}
-img {
- display:block;
- max-width: 80%;
-}
-a.textlink:before {
- content: " ⇒ ";
- padding-left: 2px;
-}
-a.textlink {
- text-decoration: none;
- color: #FF0000;
-}
-a.textlink:hover {
- text-decoration: underline;
-}
-i {
- color: #48AAAD;
-}
-pre {
- background-color: #F1F8E9;
- border: 1px dashed #BB0000;
- border-radius: 8px;
- padding: 5px;
- font-family: "Lucida Console", "Courier New", monospace;
-}
-h1 {
- text-align: center;
- color: #880000;
-}
-h2, h3 {
- color: #BB0000;
-}
-</style>
-</head>
-<body>
diff --git a/packages/assert.source.sh b/packages/assert.source.sh
deleted file mode 100644
index d53a728e..00000000
--- a/packages/assert.source.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-# Unit test for whether 2 given strings equal.
-assert::equals () {
- local -r result="$1"; shift
- local -r expected="$1"; shift
- local -r callee=${FUNCNAME[1]}
-
- if [[ "$result" != "$expected" ]]; then
- cat <<ERROR | log::pipe ERROR
-In $callee expected
- '$expected'
-But got
- '$result'
-ERROR
- exit 2
- fi
-
- log VERBOSE "Result in $callee as expected: '$expected'"
-}
-
-# Unit test for whether a given string is not empty.
-assert::not_empty () {
- local -r name="$1"; shift
- local -r content="$1"; shift
- local -r callee=${FUNCNAME[1]}
-
- if [ -z "$content" ]; then
- log ERROR "In $callee expected '$name' not to be empty!"
- exit 2
- fi
-
- log VERBOSE "Result in $callee as expected not empty"
-}
-
-# Unit test for whether a given string matches a regex.
-assert::matches () {
- local -r name="$1"; shift
- local -r content="$1"; shift
- local -r regex="$1"; shift
- local -r callee=${FUNCNAME[1]}
-
- if ! $GREP -q -E "$regex" <<< "$content"; then
- log ERROR "In $callee expected '$name' to match '$regex'"
- exit 2
- fi
-
- log VERBOSE "Matching in $callee as expected"
-}
-
-# Checks if all the Bash scripts here are good.
-assert::shellcheck () {
- set -e
- shellcheck \
- --norc \
- --external-sources \
- --check-sourced \
- --exclude=SC2155,SC2010,SC2154,SC1090,SC2012 \
- ./"$0"
- set +e
-}
diff --git a/packages/atomfeed.source.sh b/packages/atomfeed.source.sh
deleted file mode 100644
index e1ee4064..00000000
--- a/packages/atomfeed.source.sh
+++ /dev/null
@@ -1,128 +0,0 @@
-# Retrieve meta data of a given blog post. Generate new meta info if not yet exists.
-atomfeed::meta () {
- local -r gmi_file_path="$1"; shift
- local -r meta_file=$($SED 's|gemtext|meta|; s|.gmi$|.meta|;' <<< "$gmi_file_path")
-
- log VERBOSE "Generating meta info for post $gmi_file_path"
-
- local is_draft=no
- if $GREP -E -q '\.draft\.meta$' <<< "$meta_file"; then
- is_draft=yes
- fi
-
- local -r meta_dir=$(dirname "$meta_file")
- if [[ ! -d "$meta_dir" ]]; then
- mkdir -p "$meta_dir"
- fi
-
- if [ ! -f "$meta_file" ]; then
- # Extract first heading as post title.
- local title=$($SED -n '/^# / { s/# //; p; q; }' "$gmi_file_path" | tr '"' "'")
- # Extract first paragraph from Gemtext
- local summary=$($SED -n '/^[A-Z]/ { p; q; }' "$gmi_file_path" | tr '"' "'")
- # Extract the date from the file name.
- local filename_date=$(basename "$gmi_file_path" | cut -d- -f1,2,3)
- local date=$($DATE --iso-8601=seconds --date "$filename_date $($DATE +%H:%M:%S)")
-
- cat <<META | tee "$meta_file"
-local meta_date="$date"
-local meta_author="$AUTHOR"
-local meta_email="$EMAIL"
-local meta_title="$title"
-local meta_summary="$summary. .....to read on please visit my site."
-META
- if [[ $is_draft == no ]]; then
- git::add meta "$meta_file"
- fi
- return
- fi
-
- cat "$meta_file"
- if [[ $is_draft == yes ]]; then
- rm "$meta_file"
- fi
-}
-
-# Retrieve the core content as XHTML of the blog post.
-atomfeed::content () {
- local -r gmi_file_path="$1"; shift
- log VERBOSE "Retrieving feed content from $gmi_file_path"
-
- # sed: Remove all before the first header
- # sed: Make HTML links absolute, Atom relative URLs feature seems a mess
- # across different Atom clients.
- html::fromgmi < <($SED '/Go back to the main site/d' "$gmi_file_path") |
- $SED "
- s|href=\"\./|href=\"https://$DOMAIN/gemfeed/|g;
- s|src=\"\./|src=\"https://$DOMAIN/gemfeed/|g;
- "
-}
-
-# Generate an atom.xml feed file.
-atomfeed::generate () {
- local -r gemfeed_dir="$CONTENT_BASE_DIR/gemtext/gemfeed"
- local -r atom_file="$gemfeed_dir/atom.xml"
- local -r now=$($DATE --iso-8601=seconds)
- log INFO "Generating Atom feed to $atom_file"
-
- assert::not_empty now "$now"
-
- cat <<ATOMHEADER > "$atom_file.tmp"
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <updated>$now</updated>
- <title>$DOMAIN feed</title>
- <subtitle>$SUBTITLE</subtitle>
- <link href="gemini://$DOMAIN/gemfeed/atom.xml" rel="self" />
- <link href="gemini://$DOMAIN/" />
- <id>gemini://$DOMAIN/</id>
-ATOMHEADER
-
- while read -r gmi_file; do
- # Load cached meta information about the post.
- source <(atomfeed::meta "$gemfeed_dir/$gmi_file")
-
- # Get HTML content for the feed
- local content="$(atomfeed::content "$gemfeed_dir/$gmi_file")"
-
- assert::not_empty meta_title "$meta_title"
- assert::not_empty meta_date "$meta_date"
- assert::not_empty meta_author "$meta_author"
- assert::not_empty meta_email "$meta_email"
- assert::not_empty meta_summary "$meta_summary"
- assert::not_empty content "$content"
-
- cat <<ATOMENTRY >> "$atom_file.tmp"
- <entry>
- <title>$meta_title</title>
- <link href="gemini://$DOMAIN/gemfeed/$gmi_file" />
- <id>gemini://$DOMAIN/gemfeed/$gmi_file</id>
- <updated>$meta_date</updated>
- <author>
- <name>$meta_author</name>
- <email>$meta_email</email>
- </author>
- <summary>$meta_summary</summary>
- <content type="xhtml">
- <div xmlns="http://www.w3.org/1999/xhtml">
- $content
- </div>
- </content>
- </entry>
-ATOMENTRY
- done < <(gemfeed::get_posts | head -n $ATOM_MAX_ENTRIES)
-
- cat <<ATOMFOOTER >> "$atom_file.tmp"
-</feed>
-ATOMFOOTER
-
- # Delete the 3rd line of the atom feeds (global feed update timestamp)
- if ! diff -u <($SED 3d "$atom_file") <($SED 3d "$atom_file.tmp"); then
- log INFO 'Feed got something new!'
- mv "$atom_file.tmp" "$atom_file"
- git::add gemtext "$atom_file"
- else
- log INFO 'Nothing really new in the feed'
- rm "$atom_file.tmp"
- fi
-}
diff --git a/packages/gemfeed.source.sh b/packages/gemfeed.source.sh
deleted file mode 100644
index c842bb13..00000000
--- a/packages/gemfeed.source.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-# Filter out blog posts from other files in the gemfeed dir.
-gemfeed::get_posts () {
- local -r gemfeed_dir="$CONTENT_BASE_DIR/gemtext/gemfeed"
- local -r gmi_pattern='^[0-9]{4}-[0-9]{2}-[0-9]{2}-.*\.gmi$'
- local -r draft_pattern='\.draft\.gmi$'
-
- ls "$gemfeed_dir" |
- $GREP -E "$gmi_pattern" |
- $GREP -E -v "$draft_pattern" |
- sort -r
-}
-
-# Add the links from gemfeed/index.gmi to the main index site.
-gemfeed::updatemainindex () {
- local -r index_gmi="$CONTENT_BASE_DIR/gemtext/index.gmi"
- local -r gemfeed_dir="$CONTENT_BASE_DIR/gemtext/gemfeed"
-
- log VERBOSE "Updating $index_gmi with posts from $gemfeed_dir"
-
- # Remove old gemfeeds from main index
- $SED '/^=> .\/gemfeed\/[0-9].* - .*/d;' "$index_gmi" > "$index_gmi.tmp"
- # Add current gemfeeds to main index
- $SED -n '/^=> / { s| ./| ./gemfeed/|; p; }' "$gemfeed_dir/index.gmi" >> "$index_gmi.tmp"
-
- mv "$index_gmi.tmp" "$index_gmi"
- git::add gemtext "$index_gmi"
-}
-
-# Generate a index.gmi in the ./gemfeed subdir.
-gemfeed::generate () {
- local -r gemfeed_dir="$CONTENT_BASE_DIR/gemtext/gemfeed"
- log INFO "Generating Gemfeed index for $gemfeed_dir"
-
-cat <<GEMFEED > "$gemfeed_dir/index.gmi.tmp"
-# $DOMAIN's Gemfeed
-
-## $SUBTITLE
-
-GEMFEED
-
- gemfeed::get_posts | while read -r gmi_file; do
- # Extract first heading as post title.
- local title=$($SED -n '/^# / { s/# //; p; q; }' "$gemfeed_dir/$gmi_file" | tr '"' "'")
- # Extract the date from the file name.
- local filename_date=$(basename "$gemfeed_dir/$gmi_file" | cut -d- -f1,2,3)
-
- echo "=> ./$gmi_file $filename_date - $title" >> "$gemfeed_dir/index.gmi.tmp"
- done
-
- mv "$gemfeed_dir/index.gmi.tmp" "$gemfeed_dir/index.gmi"
- git::add gemtext "$gemfeed_dir/index.gmi"
-
- gemfeed::updatemainindex
-}
diff --git a/packages/generate.source.sh b/packages/generate.source.sh
deleted file mode 100644
index 98cd2154..00000000
--- a/packages/generate.source.sh
+++ /dev/null
@@ -1,160 +0,0 @@
-# Generate a HTML or Markdown link from given Gemtext link.
-generate::make_link () {
- local -r what="$1"; shift
- local -r line="${1/=> }"; shift
- local link
- local descr
-
- while read -r token; do
- if [ -z "$link" ]; then
- link="$token"
- elif [ -z "$descr" ]; then
- descr="$token"
- else
- descr="$descr $token"
- fi
- done < <(echo "$line" | tr ' ' '\n')
-
- if $GREP -E -q "$IMAGE_PATTERN" <<< "$link"; then
- if [[ "$what" == md ]]; then
- md::make_img "$link" "$descr"
- else
- html::make_img "$link" "$(html::encode "$descr")"
- fi
- return
- fi
-
- if [[ "$what" == md ]]; then
- md::make_link "$link" "$descr"
- else
- html::make_link "$link" "$(html::encode "$descr")"
- fi
-}
-
-# Add other docs (e.g. images, videos) from Gemtext to output format.
-generate::fromgmi_add_docs () {
- local -r src="$1"; shift
- local -r format="$1"; shift
- local -r dest=${src/gemtext/$format}
- local -r dest_dir=$(dirname "$dest")
-
- if [[ ! -d "$dest_dir" ]]; then
- mkdir -p "$dest_dir"
- fi
- cp "$src" "$dest"
- git::add "$format" "$dest"
-}
-
-# Remove docs from output format which aren't present in Gemtext anymore.
-generate::fromgmi_cleanup_docs () {
- local -r src="$1"; shift
- local -r format="$1"; shift
- local dest=${src/.$format/.gmi}
- dest=${dest/$format/gemtext}
-
- if [[ ! -f "$dest" ]]; then
- git::rm "$format" "$src"
- fi
-}
-
-# Convert the Gemtext Atom feed to a HTML Atom feed.
-generate::convert_gmi_atom_to_html_atom () {
- local -r format="$1"; shift
- if [[ "$format" != html ]]; then
- return
- fi
-
- log INFO 'Converting Gemtext Atom feed to HTML Atom feed'
-
- $SED 's|.gmi|.html|g; s|gemini://|https://|g' \
- < $CONTENT_BASE_DIR/gemtext/gemfeed/atom.xml \
- > $CONTENT_BASE_DIR/html/gemfeed/atom.xml
-
- git::add "$format" "$CONTENT_BASE_DIR/html/gemfeed/atom.xml"
-}
-
-# Internal helper function for generate::fromgmi
-generate::_fromgmi () {
- local -r src="$1"; shift
- local -r format="$1"; shift
- local dest=${src/gemtext/$format}
- dest=${dest/.gmi/.$format}
- local dest_dir=$(dirname "$dest")
-
- if [[ ! -d "$dest_dir" ]]; then
- mkdir -p "$dest_dir"
- fi
-
- if [[ "$format" == html ]]; then
- cat "$HTML_HEADER" > "$dest.tmp"
- html::fromgmi < "$src" >> "$dest.tmp"
- cat "$HTML_FOOTER" >> "$dest.tmp"
-
- elif [[ "$format" == md ]]; then
- md::fromgmi < "$src" >> "$dest.tmp"
- fi
-
- local title=$($SED -n '/^# / { s/# //; p; q; }' "$src" | tr '"' "'")
- if [[ -z "$title" ]]; then
- title=$SUBTITLE
- fi
- $SED -i "s|%%TITLE%%|$title|g" "$dest.tmp"
- mv "$dest.tmp" "$dest"
-
- git::add "$format" "$dest"
-}
-
-# Generate a given output format from a Gemtext file.
-generate::fromgmi () {
- local -i num_gmi_files=0
- local -i num_doc_files=0
-
- log INFO "Generating $* from Gemtext"
-
- while read -r src; do
- num_gmi_files=$(( num_gmi_files + 1 ))
- for format in "$@"; do
- generate::_fromgmi "$src" "$format"
- done
- done < <(find "$CONTENT_BASE_DIR/gemtext" -type f -name \*.gmi)
-
- log INFO "Converted $num_gmi_files Gemtext files"
-
- # Add non-.gmi files to html dir.
- log VERBOSE "Adding other docs to $*"
-
- while read -r src; do
- num_doc_files=$(( num_doc_files + 1 ))
- for format in "$@"; do
- generate::fromgmi_add_docs "$src" "$format"
- done
- done < <(find "$CONTENT_BASE_DIR/gemtext" -type f | $GREP -E -v '(\.git.*|\.gmi|atom.xml|\.tmp)$')
-
- log INFO "Added $num_doc_files other documents to each of $*"
-
- # Add atom feed for HTML
- for format in "$@"; do
- generate::convert_gmi_atom_to_html_atom "$format"
- done
-
- # Remove obsolete files from ./html/.
- # Note: The _config.yml is the config file for GitHub pages (md format).
- for format in "$@"; do
- find "$CONTENT_BASE_DIR/$format" -type f |
- $GREP -E -v '(\.git.*|_config.yml)$'|
- while read -r src; do
- generate::fromgmi_cleanup_docs "$src" "$format"
- done
- done
-
- if [[ -z "$GIT_COMMIT_MESSAGE" ]]; then
- GIT_COMMIT_MESSAGE='Publishing new version'
- fi
- git::commit gemtext "$GIT_COMMIT_MESSAGE"
- git::commit meta "$GIT_COMMIT_MESSAGE"
-
- for format in "$@"; do
- git::commit "$format" "$GIT_COMMIT_MESSAGE"
- log INFO "$format can be found in $CONTENT_BASE_DIR/$format now"
- done
-}
diff --git a/packages/git.source.sh b/packages/git.source.sh
deleted file mode 100644
index c502b008..00000000
--- a/packages/git.source.sh
+++ /dev/null
@@ -1,50 +0,0 @@
-# Add a static content file to git
-git::add () {
- if [[ "$USE_GIT" != yes ]]; then
- return
- fi
-
- local -r content_dir="$CONTENT_BASE_DIR/$1"; shift
- local file="$1"; shift
- file=${file/$content_dir/.\/}
-
- cd "$content_dir" &>/dev/null
- git add "$file"
- cd - &>/dev/null
-}
-
-# Remove a static content file from git
-git::rm () {
- if [[ "$USE_GIT" != yes ]]; then
- return
- fi
-
- local -r content_dir="$CONTENT_BASE_DIR/$1"; shift
- local file="$1"; shift
- file=${file/$content_dir/.\/}
-
- cd "$content_dir" &>/dev/null
- git rm "$file"
- cd - &>/dev/null
-}
-
-# Commit all changes
-git::commit () {
- if [[ "$USE_GIT" != yes ]]; then
- return
- fi
-
- local -r content_dir="$CONTENT_BASE_DIR/$1"; shift
- local -r message="$1"; shift
-
- cd "$content_dir" &>/dev/null
- set +e
- git commit -a -m "$message"
- if [[ "$GIT_PUSH" == yes ]]; then
- log INFO "Invoking git pull/push in $content_dir"
- git pull
- git push
- fi
- set -e
- cd - &>/dev/null
-}
diff --git a/packages/html.source.sh b/packages/html.source.sh
deleted file mode 100644
index 6049c2f9..00000000
--- a/packages/html.source.sh
+++ /dev/null
@@ -1,162 +0,0 @@
-# Convert special characters to their HTML codes
-html::encode () {
- $SED '
- s|\&|\&amp;|g;
- s|<|\&lt;|g;
- s|>|\&gt;|g;
- ' <<< "$@"
-}
-
-# Make a HTML paragraph.
-html::make_paragraph () {
- local -r text="$1"; shift
-
- if [[ -n "$text" ]]; then
- echo "<p>$(html::encode "$text")</p>"
- fi
-}
-
-# Make a HTML header.
-html::make_heading () {
- local -r text=$($SED -E 's/^#+ //' <<< "$1"); shift
- local -r level="$1"; shift
- echo "<h${level}>$(html::encode "$text")</h${level}>"
-}
-
-# Make a HTML quotation
-html::make_quote () {
- local -r quote="${1/> }"
- echo "<p class=\"quote\"><i>$(html::encode "$quote")</i></p>"
-}
-
-# Make a HTML image
-html::make_img () {
- local link="$1"; shift
- local descr="$1"; shift
-
- if [ -z "$descr" ]; then
- echo -n "<a href=\"$link\"><img src=\"$link\" /></a>"
- else
- echo -n "<i>$descr:</i>"
- echo -n "<a href=\"$link\"><img alt=\"$descr\" title=\"$descr\" src=\"$link\" /></a>"
- fi
-
- echo "<br />"
-}
-
-# Make a HTML hyperlink
-html::make_link () {
- local link="$1"; shift
- local descr="$1"; shift
-
- if ! $GREP -F -q '://' <<< "$link"; then
- link=${link/.gmi/.html}
- fi
-
- if [[ -z "$descr" ]]; then
- descr="$link"
- fi
-
- echo "<a class=\"textlink\" href=\"$link\">$descr</a><br />"
-}
-
-# Convert Gemtext to HTML
-html::fromgmi () {
- local is_list=no
- local is_plain=no
-
- while IFS='' read -r line; do
- if [[ "$is_list" == yes ]]; then
- if [[ "$line" == '* '* ]]; then
- echo "<li>$(html::encode "${line/\* /}")</li>"
- else
- is_list=no
- echo "</ul>"
- fi
- continue
-
- elif [[ "$is_plain" == yes ]]; then
- if [[ "$line" == '```'* ]]; then
- echo "</pre>"
- is_plain=no
- else
- html::encode "$line"
- fi
- continue
- fi
-
- case "$line" in
- '* '*)
- is_list=yes
- echo "<ul>"
- echo "<li>${line/\* /}</li>"
- ;;
- '```'*)
- is_plain=yes
- echo "<pre>"
- ;;
- '# '*)
- html::make_heading "$line" 1
- ;;
- '## '*)
- html::make_heading "$line" 2
- ;;
- '### '*)
- html::make_heading "$line" 3
- ;;
- '> '*)
- html::make_quote "$line"
- ;;
- '=> '*)
- generate::make_link html "$line"
- ;;
- *)
- html::make_paragraph "$line"
- ;;
- esac
- done
-}
-
-# Test HTML package.
-html::test () {
- local line='Hello world! This is a paragraph.'
- assert::equals "$(html::make_paragraph "$line")" '<p>Hello world! This is a paragraph.</p>'
-
- line=''
- assert::equals "$(html::make_paragraph "$line")" ''
-
- line='Foo &<>& Bar!'
- assert::equals "$(html::make_paragraph "$line")" '<p>Foo &amp;&lt;&gt;&amp; Bar!</p>'
-
- line='# Header 1'
- assert::equals "$(html::make_heading "$line" 1)" '<h1>Header 1</h1>'
-
- line='## Header 2'
- assert::equals "$(html::make_heading "$line" 2)" '<h2>Header 2</h2>'
-
- line='### Header 3'
- assert::equals "$(html::make_heading "$line" 3)" '<h3>Header 3</h3>'
-
- line='> This is a quote'
- assert::equals "$(html::make_quote "$line")" '<p class="quote"><i>This is a quote</i></p>'
-
- line='=> https://example.org'
- assert::equals "$(generate::make_link html "$line")" \
- '<a class="textlink" href="https://example.org">https://example.org</a><br />'
-
- line='=> index.html'
- assert::equals "$(generate::make_link html "$line")" \
- '<a class="textlink" href="index.html">index.html</a><br />'
-
- line='=> http://example.org Description of the link'
- assert::equals "$(generate::make_link html "$line")" \
- '<a class="textlink" href="http://example.org">Description of the link</a><br />'
-
- line='=> http://example.org/image.png'
- assert::equals "$(generate::make_link html "$line")" \
- '<a href="http://example.org/image.png"><img src="http://example.org/image.png" /></a><br />'
-
- line='=> http://example.org/image.png Image description'
- assert::equals "$(generate::make_link html "$line")" \
- '<i>Image description:</i><a href="http://example.org/image.png"><img alt="Image description" title="Image description" src="http://example.org/image.png" /></a><br />'
-}
diff --git a/packages/log.source.sh b/packages/log.source.sh
deleted file mode 100644
index 56c6587e..00000000
--- a/packages/log.source.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-# Log a message.
-log () {
- local -r level="$1"; shift
- local message
-
- for message in "$@"; do
- echo "$message"
- done | log::_pipe "$level"
-}
-
-# Log a stream through a pipe.
-log::pipe () {
- log::_pipe "$1"
-}
-
-# Internal log implementation.
-log::_pipe () {
- local -r level="$1"; shift
-
- if [[ "$level" == VERBOSE && -z "$LOG_VERBOSE" ]]; then
- return
- fi
-
- local -r callee=${FUNCNAME[2]}
- local -r stamp=$($DATE +%Y%m%d-%H%M%S)
-
- while read -r line; do
- echo "$level|$stamp|$callee|$line" >&2
- done
-}
diff --git a/packages/md.source.sh b/packages/md.source.sh
deleted file mode 100644
index e7bfae11..00000000
--- a/packages/md.source.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-# Make a Markdown image.
-md::make_img () {
- local link="$1"; shift
- local descr="$1"; shift
-
- if [ -z "$descr" ]; then
- echo "[![$link]($link)]($link) "
- else
- echo "[![$descr]($link \"$descr\")]($link) "
- fi
-}
-
-# Make a Markdown hyperlink.
-md::make_link () {
- local link="$1"; shift
- local descr="$1"; shift
-
- if ! $GREP -F -q '://' <<< "$link"; then
- link=${link/.gmi/.md}
- fi
- if [[ -z "$descr" ]]; then
- descr="$link"
- fi
-
- echo "[$descr]($link) "
-}
-
-# Convert Gemtext to Markdown.
-md::fromgmi () {
- while IFS='' read -r line; do
- case "$line" in
- '=> '*)
- generate::make_link md "$line"
- ;;
- *)
- echo "$line"
- ;;
- esac
- done
-}
-
-# Test the Markdown package.
-md::test () {
- local line='=> https://example.org'
- assert::equals "$(generate::make_link md "$line")" \
- '[https://example.org](https://example.org) '
-
- line='=> index.md'
- assert::equals "$(generate::make_link md "$line")" \
- '[index.md](index.md) '
-
- line='=> http://example.org Description of the link'
- assert::equals "$(generate::make_link md "$line")" \
- '[Description of the link](http://example.org) '
-
- line='=> http://example.org/image.png'
- assert::equals "$(generate::make_link md "$line")" \
- '[![http://example.org/image.png](http://example.org/image.png)](http://example.org/image.png) '
-
- line='=> http://example.org/image.png Image description'
- assert::equals "$(generate::make_link md "$line")" \
- '[![Image description](http://example.org/image.png "Image description")](http://example.org/image.png) '
-}