From 85cc20507d3541b62d06ec60ad0dc719b6244966 Mon Sep 17 00:00:00 2001 From: historia Date: Wed, 9 Oct 2024 19:24:43 -0400 Subject: Initial commit --- LICENSE | 20 +- README.md | 41 ++- example/dst/.files | 11 + example/dst/404.html | 33 +++ .../an-interesting-article/assets/stamps.webp | Bin 0 -> 46960 bytes .../dst/Articles/an-interesting-article/index.html | 37 +++ .../assets/japanese-train.webp | Bin 0 -> 128168 bytes .../another-interesting-article/index.html | 37 +++ example/dst/Articles/article3.html | 33 +++ example/dst/Lists/board-games.html | 41 +++ example/dst/Lists/movies.html | 41 +++ example/dst/about.html | 33 +++ example/dst/favicon.png | Bin 0 -> 393 bytes example/dst/hed | 28 ++ example/dst/index.html | 41 +++ example/dst/sitemap.xml | 14 + example/dst/style.css | 54 ++++ example/src/404.md | 3 + .../an-interesting-article/assets/stamps.webp | Bin 0 -> 46960 bytes .../src/Articles/an-interesting-article/index.md | 12 + .../assets/japanese-train.webp | Bin 0 -> 128168 bytes .../Articles/another-interesting-article/index.md | 12 + example/src/Articles/article3.md | 8 + example/src/Lists/board-games.md | 14 + example/src/Lists/movies.md | 13 + example/src/_footer.html | 2 + example/src/_header.html | 28 ++ example/src/about.md | 3 + example/src/favicon.png | Bin 0 -> 393 bytes example/src/style.css | 54 ++++ ssg-blog | 288 +++++++++++++++++++++ 31 files changed, 892 insertions(+), 9 deletions(-) create mode 100644 example/dst/.files create mode 100644 example/dst/404.html create mode 100644 example/dst/Articles/an-interesting-article/assets/stamps.webp create mode 100644 example/dst/Articles/an-interesting-article/index.html create mode 100644 example/dst/Articles/another-interesting-article/assets/japanese-train.webp create mode 100644 example/dst/Articles/another-interesting-article/index.html create mode 100644 example/dst/Articles/article3.html create mode 100644 example/dst/Lists/board-games.html create mode 100644 example/dst/Lists/movies.html create mode 100644 example/dst/about.html create mode 100644 example/dst/favicon.png create mode 100644 example/dst/hed create mode 100644 example/dst/index.html create mode 100644 example/dst/sitemap.xml create mode 100644 example/dst/style.css create mode 100644 example/src/404.md create mode 100644 example/src/Articles/an-interesting-article/assets/stamps.webp create mode 100644 example/src/Articles/an-interesting-article/index.md create mode 100644 example/src/Articles/another-interesting-article/assets/japanese-train.webp create mode 100644 example/src/Articles/another-interesting-article/index.md create mode 100644 example/src/Articles/article3.md create mode 100644 example/src/Lists/board-games.md create mode 100644 example/src/Lists/movies.md create mode 100644 example/src/_footer.html create mode 100644 example/src/_header.html create mode 100644 example/src/about.md create mode 100644 example/src/favicon.png create mode 100644 example/src/style.css create mode 100755 ssg-blog diff --git a/LICENSE b/LICENSE index b9c199c..0f23fe1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,12 @@ -ISC License: - -Copyright (c) 2004-2010 by Internet Systems Consortium, Inc. ("ISC") -Copyright (c) 1995-2003 by Internet Software Consortium - -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 ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC 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. +# Copyright 2018-2019 Roman Zolotarev +# +# 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 diff --git a/README.md b/README.md index ef54896..1e48f8c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,42 @@ # ssg-blog -A minor modification to the 'ssg' bash script to generate a simple blog \ No newline at end of file +This is a modification to the simple static site generator '[ssg](https://romanzolotarev.com/bin/ssg)' by Roman Zolotarev. This generates a minimal blog index page with category headings. + +# Install / Usage + +See [https://romansolotarev.com/ssg.html](https://romanzolotarev.com/ssg.html) for documentation on ssg + +In short: +1. Install [lowdown](https://kristaps.bsd.lv/lowdown/) +2. Copy the `ssg` script somewhere in your path, e.g. `/usr/bin/` +3. `chmod +x /usr/bin/ssg` +4. `ssg src dst 'my-website-name' 'https://my-website.net'` + +ssg-blog checks for subdirectories in the src directory, each of which becomes a category heading (non-recursively). It will generate a sorted list of links to any .md file in those directory (including nested directories). Each .md file needs frontmatter including the title and a YYYY-MM-DD date like this to be included in the index page: + +```markdown +--- +title: My Blog Post +date: 2024-10-09 +--- +``` + +## Example + +There is an example directory in this repo to show you how to set up the files (src) and what the output looks like (dst). Note how articles can be nested in subdirectories or not and that the articles titled index.md get links created without .html appended. This was the command used to generate the example output: + +``` +./ssg-blog example/src example/dst 'example-site-name' 'https://example.org' +``` + +## Change how categories are sorted + +The category headings are sorted alphabetically. If you want to change this, you have to edit the `sort` on this line: + +``` +find "$src" -mindepth 1 -maxdepth 1 -type d ! -path "*/.*" | sort | +``` + +# Alternatives + +You might also be interested in the similar fork [fmash16/ssg5](https://github.com/fmash16/ssg5) which generates a more traditional blog with pagination, keywords, and post previews. diff --git a/example/dst/.files b/example/dst/.files new file mode 100644 index 0000000..1611884 --- /dev/null +++ b/example/dst/.files @@ -0,0 +1,11 @@ +./style.css +./Lists/board-games.md +./Lists/movies.md +./about.md +./Articles/an-interesting-article/index.md +./Articles/an-interesting-article/assets/stamps.webp +./Articles/another-interesting-article/index.md +./Articles/another-interesting-article/assets/japanese-train.webp +./Articles/article3.md +./404.md +./favicon.png diff --git a/example/dst/404.html b/example/dst/404.html new file mode 100644 index 0000000..b56836c --- /dev/null +++ b/example/dst/404.html @@ -0,0 +1,33 @@ + + + + + + + Example + + + +

404 Not Found

+ +

I couldn't find that page.

+ + diff --git a/example/dst/Articles/an-interesting-article/assets/stamps.webp b/example/dst/Articles/an-interesting-article/assets/stamps.webp new file mode 100644 index 0000000..9785ce7 Binary files /dev/null and b/example/dst/Articles/an-interesting-article/assets/stamps.webp differ diff --git a/example/dst/Articles/an-interesting-article/index.html b/example/dst/Articles/an-interesting-article/index.html new file mode 100644 index 0000000..412e359 --- /dev/null +++ b/example/dst/Articles/an-interesting-article/index.html @@ -0,0 +1,37 @@ + + + + + + + Example + + + +

This is a very interesting article about stamps

+ +

Here is a picture of some cool stamps

+ +

+ +

Thank you for reading my nice article.

+ + diff --git a/example/dst/Articles/another-interesting-article/assets/japanese-train.webp b/example/dst/Articles/another-interesting-article/assets/japanese-train.webp new file mode 100644 index 0000000..c4cab3e Binary files /dev/null and b/example/dst/Articles/another-interesting-article/assets/japanese-train.webp differ diff --git a/example/dst/Articles/another-interesting-article/index.html b/example/dst/Articles/another-interesting-article/index.html new file mode 100644 index 0000000..31ef880 --- /dev/null +++ b/example/dst/Articles/another-interesting-article/index.html @@ -0,0 +1,37 @@ + + + + + + + Example + + + +

I love trains

+ +

Aren't Japanese trains great? I particularly like the boxy ones. Here is a picture of a train:

+ +

+ +

Thank you for looking at this train

+ + diff --git a/example/dst/Articles/article3.html b/example/dst/Articles/article3.html new file mode 100644 index 0000000..e34e43a --- /dev/null +++ b/example/dst/Articles/article3.html @@ -0,0 +1,33 @@ + + + + + + + Example + + + +

Article 3

+ +

Wow another one

+ + diff --git a/example/dst/Lists/board-games.html b/example/dst/Lists/board-games.html new file mode 100644 index 0000000..1693d1b --- /dev/null +++ b/example/dst/Lists/board-games.html @@ -0,0 +1,41 @@ + + + + + + + Example + + + +

Board Games

+ +

Here are some board games I like:

+ +
    +
  1. Puerto Rico
  2. +
  3. Ascension: Chronicle of the Godslayer
  4. +
  5. Twilight Struggle
  6. +
+ +

Play them with me, thanks.

+ + diff --git a/example/dst/Lists/movies.html b/example/dst/Lists/movies.html new file mode 100644 index 0000000..a3499e5 --- /dev/null +++ b/example/dst/Lists/movies.html @@ -0,0 +1,41 @@ + + + + + + + Example + + + +

A List of Movies

+ +

Here are my favorite movies

+ +
    +
  1. Primer
  2. +
  3. The Lighthouse
  4. +
  5. Tetsuo: The Iron Man
  6. +
+ +

I hope you enjoyed this insightful article.

+ + diff --git a/example/dst/about.html b/example/dst/about.html new file mode 100644 index 0000000..51897a4 --- /dev/null +++ b/example/dst/about.html @@ -0,0 +1,33 @@ + + + + + + + Example + + + +

About

+ +

Here is an about page for my website

+ + diff --git a/example/dst/favicon.png b/example/dst/favicon.png new file mode 100644 index 0000000..4c22246 Binary files /dev/null and b/example/dst/favicon.png differ diff --git a/example/dst/hed b/example/dst/hed new file mode 100644 index 0000000..d90b226 --- /dev/null +++ b/example/dst/hed @@ -0,0 +1,28 @@ + + + + + + + Example + + + diff --git a/example/dst/index.html b/example/dst/index.html new file mode 100644 index 0000000..8deec2f --- /dev/null +++ b/example/dst/index.html @@ -0,0 +1,41 @@ + + + + + + + Example + + + +

Articles

+ +

Lists

+ + + diff --git a/example/dst/sitemap.xml b/example/dst/sitemap.xml new file mode 100644 index 0000000..6c057b3 --- /dev/null +++ b/example/dst/sitemap.xml @@ -0,0 +1,14 @@ + + +https://example.org/Lists/board-games.html2024-10-091.0 +https://example.org/Lists/movies.html2024-10-091.0 +https://example.org/about.html2024-10-091.0 +https://example.org/Articles/an-interesting-article/2024-10-091.0 +https://example.org/Articles/another-interesting-article/2024-10-091.0 +https://example.org/Articles/article3.html2024-10-091.0 +https://example.org/404.html2024-10-091.0 + diff --git a/example/dst/style.css b/example/dst/style.css new file mode 100644 index 0000000..4489ae8 --- /dev/null +++ b/example/dst/style.css @@ -0,0 +1,54 @@ +html { + font-size: 100%; + font-family:sans-serif; + /* font-family:sans-serif; */ + /* font:1.2em/1.62 sans-serif; */ +} + +body { + line-height: 1.6; + max-width:40em; + background-color: #ededed; + margin: auto; +} + +.container { + text-align: center; +} + +.container pre { + display: inline-block; + text-align: left; + line-height: 1.0; +} + +#header { + text-decoration: none; + color: inherit; + font-size:125%; +} + +#navigation { + font-family:monospace; + font-size:125%; +} + +h1 { font-size: 1.4rem; } +h2 { font-size: 1.2rem; } +h3 { font-size: 1.0rem;} + +a:link, a:visited { + color: #2626FF; +} + +a:hover, a:focus { + color: #4c4cFF; +} + +li + li { + margin-top:1em; +} + +ul img { + vertical-align:middle; +} diff --git a/example/src/404.md b/example/src/404.md new file mode 100644 index 0000000..a0aa728 --- /dev/null +++ b/example/src/404.md @@ -0,0 +1,3 @@ +# 404 Not Found + +I couldn't find that page. diff --git a/example/src/Articles/an-interesting-article/assets/stamps.webp b/example/src/Articles/an-interesting-article/assets/stamps.webp new file mode 100644 index 0000000..9785ce7 Binary files /dev/null and b/example/src/Articles/an-interesting-article/assets/stamps.webp differ diff --git a/example/src/Articles/an-interesting-article/index.md b/example/src/Articles/an-interesting-article/index.md new file mode 100644 index 0000000..779f4b6 --- /dev/null +++ b/example/src/Articles/an-interesting-article/index.md @@ -0,0 +1,12 @@ +--- +title: This is a very interesting article about stamps +date: 2024-10-04 +--- + +# This is a very interesting article about stamps + +Here is a picture of some cool stamps + +![](assets/stamps.webp) + +Thank you for reading my nice article. diff --git a/example/src/Articles/another-interesting-article/assets/japanese-train.webp b/example/src/Articles/another-interesting-article/assets/japanese-train.webp new file mode 100644 index 0000000..c4cab3e Binary files /dev/null and b/example/src/Articles/another-interesting-article/assets/japanese-train.webp differ diff --git a/example/src/Articles/another-interesting-article/index.md b/example/src/Articles/another-interesting-article/index.md new file mode 100644 index 0000000..4e5d9b7 --- /dev/null +++ b/example/src/Articles/another-interesting-article/index.md @@ -0,0 +1,12 @@ +--- +title: I love trains +date: 2024-09-10 +--- + +# I love trains + +Aren't Japanese trains great? I particularly like the boxy ones. Here is a picture of a train: + +![](assets/japanese-train.webp) + +Thank you for looking at this train diff --git a/example/src/Articles/article3.md b/example/src/Articles/article3.md new file mode 100644 index 0000000..c98ebba --- /dev/null +++ b/example/src/Articles/article3.md @@ -0,0 +1,8 @@ +--- +title: This is a third article! +date: 2023-10-08 +--- + +# Article 3 + +Wow another one diff --git a/example/src/Lists/board-games.md b/example/src/Lists/board-games.md new file mode 100644 index 0000000..6a40080 --- /dev/null +++ b/example/src/Lists/board-games.md @@ -0,0 +1,14 @@ +--- +title: Board games +date: 2024-07-12 +--- + +# Board Games + +Here are some board games I like: + +1. Puerto Rico +2. Ascension: Chronicle of the Godslayer +3. Twilight Struggle + +Play them with me, thanks. diff --git a/example/src/Lists/movies.md b/example/src/Lists/movies.md new file mode 100644 index 0000000..92d82e6 --- /dev/null +++ b/example/src/Lists/movies.md @@ -0,0 +1,13 @@ +--- +title: Movies +date: 2022-06-05 +--- +# A List of Movies + +Here are my favorite movies + +1. Primer +2. The Lighthouse +3. Tetsuo: The Iron Man + +I hope you enjoyed this insightful article. diff --git a/example/src/_footer.html b/example/src/_footer.html new file mode 100644 index 0000000..308b1d0 --- /dev/null +++ b/example/src/_footer.html @@ -0,0 +1,2 @@ + + diff --git a/example/src/_header.html b/example/src/_header.html new file mode 100644 index 0000000..d90b226 --- /dev/null +++ b/example/src/_header.html @@ -0,0 +1,28 @@ + + + + + + + Example + + + diff --git a/example/src/about.md b/example/src/about.md new file mode 100644 index 0000000..1b073d8 --- /dev/null +++ b/example/src/about.md @@ -0,0 +1,3 @@ +# About + +Here is an about page for my website diff --git a/example/src/favicon.png b/example/src/favicon.png new file mode 100644 index 0000000..4c22246 Binary files /dev/null and b/example/src/favicon.png differ diff --git a/example/src/style.css b/example/src/style.css new file mode 100644 index 0000000..4489ae8 --- /dev/null +++ b/example/src/style.css @@ -0,0 +1,54 @@ +html { + font-size: 100%; + font-family:sans-serif; + /* font-family:sans-serif; */ + /* font:1.2em/1.62 sans-serif; */ +} + +body { + line-height: 1.6; + max-width:40em; + background-color: #ededed; + margin: auto; +} + +.container { + text-align: center; +} + +.container pre { + display: inline-block; + text-align: left; + line-height: 1.0; +} + +#header { + text-decoration: none; + color: inherit; + font-size:125%; +} + +#navigation { + font-family:monospace; + font-size:125%; +} + +h1 { font-size: 1.4rem; } +h2 { font-size: 1.2rem; } +h3 { font-size: 1.0rem;} + +a:link, a:visited { + color: #2626FF; +} + +a:hover, a:focus { + color: #4c4cFF; +} + +li + li { + margin-top:1em; +} + +ul img { + vertical-align:middle; +} diff --git a/ssg-blog b/ssg-blog new file mode 100755 index 0000000..6eb7ed5 --- /dev/null +++ b/ssg-blog @@ -0,0 +1,288 @@ +#!/bin/sh -e +# +# https://rgz.ee/bin/ssg6 +# Copyright 2018-2019 Roman Zolotarev +# +# 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") + + 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" + f_file="$src/_footer.html" + test -f "$f_file" && FOOTER=$(cat "$f_file") && export FOOTER + 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) + urls=$(list_pages "$src") + + test -n "$urls" && + render_sitemap "$urls" "$base_url" "$date" >"$dst/sitemap.xml" + + render_index + + 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" >&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 + sed '1 { /^---/ { :a N; /\n---/! ba; d} }' "$1/$f" | + lowdown \ + --html-no-escapehtml \ + --html-no-skiphtml \ + --parse-no-metadata \ + --parse-no-autolink | + render_html_file "$3" \ + >"$2/${f%\.md}.html" + done +} + +render_md_files_Markdown_pl() { + while read -r f; do + sed '1 { /^---/ { :a N; /\n---/! ba; d} }' "$1/$f" | + Markdown.pl | + 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]), "")) { + head = substr(header[i], 1, RSTART - 1) + tail = substr(header[i], RSTART + RLENGTH) + print head "" 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_index() { + output="$dst/index.html" + echo "$HEADER" > "$output" + + find "$src" -mindepth 1 -maxdepth 1 -type d ! -path "*/.*" | sort | + while read -r category_dir; do + category=$(basename "$category_dir") + + find "$category_dir" -type f \( -name "*.md" -o -name "index.md" \) ! -path "*/.*" | + while read -r article; do + title=$(sed -n '/^title: /s/title: //p' "$article" | head -n 1) + date=$(sed -n '/^date: /s/date: //p' "$article" | head -n 1) + + article_url="${article#"$src"}" + article_url="${article_url%.md}.html" + if [ "${article_url##*/}" = "index.html" ]; then + article_url="${article_url%/index.html}/" + fi + article_url="${article_url#/}" + + echo "$date|$title|$article_url" >> "/tmp/articles_$category.txt" + done + + if [ -f "/tmp/articles_$category.txt" ]; then + echo "

$category

" >> "$output" + echo "
    " >> "$output" + sort -r "/tmp/articles_$category.txt" | + while IFS='|' read -r date title url; do + echo "
  • $date: $title
  • " >> "$output" + done + echo "
" >> "$output" + rm "/tmp/articles_$category.txt" + fi + done + + echo "$FOOTER" >> "$output" +} + + +render_sitemap() { + urls="$1" + base_url="$2" + date="$3" + + echo '' + echo '' + echo "$urls" | + sed -E 's#^(.*)$#'"$base_url"'/\1'"$date"'1.0#' + echo '' +} + +main "$@" -- cgit v1.2.3