Add initial files
This commit is contained in:
parent
2d0ca4ac82
commit
03bbc3816d
122
create-index-entry.awk
Executable file
122
create-index-entry.awk
Executable file
@ -0,0 +1,122 @@
|
|||||||
|
#! /usr/bin/awk -f
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
# create-post-entry.awk
|
||||||
|
#
|
||||||
|
# Create an index entry from a Gemtext file
|
||||||
|
#
|
||||||
|
# This program transforms information from a gemtext post into an index entry.
|
||||||
|
# The index entry needs to be a valid Gemini hyperlink. The hyperlink notation
|
||||||
|
# contains the following elements:
|
||||||
|
#
|
||||||
|
# * Hyperlink line marker. That is, the line must start with "=> ".
|
||||||
|
# * URL as the second element.
|
||||||
|
# * Desription as a optional third element.
|
||||||
|
#
|
||||||
|
# The program:
|
||||||
|
#
|
||||||
|
# * Forms the URL from the filename of the file that it is processing. Thus,
|
||||||
|
# it will not work correctly with text from standard input.
|
||||||
|
#
|
||||||
|
# * Constructs the desciption from the
|
||||||
|
# * Published date
|
||||||
|
# * Title
|
||||||
|
# * Revised date (if present)
|
||||||
|
#
|
||||||
|
# The AWK program expects the Gemtext file to:
|
||||||
|
#
|
||||||
|
# 1. Contain the title on the first line, without the heading level prefix.
|
||||||
|
#
|
||||||
|
# 2. Record the published date on a line that begins with "Published: " and
|
||||||
|
# then has an ISO formatted date, e.g., 2023-05-26.
|
||||||
|
#
|
||||||
|
# 3. Record revision history on lines that begin with "Revised: " and then
|
||||||
|
# have ISO formatted date. These are optional. The program takes the last
|
||||||
|
# revision date.
|
||||||
|
#
|
||||||
|
# The program will write a warning to standard error when there are empty
|
||||||
|
# values for the title or published date. If the program cannot determine the
|
||||||
|
# file name, then it exits with error code 1.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# USAGE
|
||||||
|
#
|
||||||
|
# awk -f create-post-entry.awk gemtext-file
|
||||||
|
#
|
||||||
|
# AUTHOR
|
||||||
|
#
|
||||||
|
# © Andrew Stryker <axs@sdf.org>
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
# Include colon and comma for record splitting
|
||||||
|
FS = "[:,[:space:]]+"
|
||||||
|
|
||||||
|
# Declare the variables that we will use and set them to empty
|
||||||
|
# strings. Note, AWK evaluates the empty string as false.
|
||||||
|
title = ""
|
||||||
|
published = ""
|
||||||
|
revised = ""
|
||||||
|
tags["---"] = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
FNR == 1 {
|
||||||
|
# if we cannot get a file name, then we cannot create a valid URL
|
||||||
|
# and need to fail
|
||||||
|
assert(FILENAME != "-", "Could not determine the filename")
|
||||||
|
|
||||||
|
title = gensub(/^#+ */, "", 1, $0) # remove heading marker, if present
|
||||||
|
if (!title) {
|
||||||
|
print "Missing title on the first line" > "/dev/stderr"
|
||||||
|
}
|
||||||
|
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
/^Published: +[[:digit:]]{4}(-[[:digit:]]{2}){2}/ {
|
||||||
|
published = $2
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
/^Revised: +[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}/ {
|
||||||
|
revised = sprintf(", revised on %s", $2)
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a set of tags
|
||||||
|
/^Tags:/ {
|
||||||
|
for (i = 2; i <= NF; ++i) {
|
||||||
|
tags[$i] = 1
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
if (_assert_exit) {
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!published) {
|
||||||
|
printf("Missing published date in %s\n", FILENAME) \
|
||||||
|
> "/dev/stderr"
|
||||||
|
}
|
||||||
|
|
||||||
|
for (t in tags) {
|
||||||
|
printf("%s\t=> %s %s -- %s%s\n", t, FILENAME, published,
|
||||||
|
title, revised)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# assert --- assert that a condition is true. Otherwise, exit.
|
||||||
|
# adapted from:
|
||||||
|
# https://www.gnu.org/software/gawk/manual/gawk.html#Assert-Function
|
||||||
|
|
||||||
|
function assert(condition, string) {
|
||||||
|
if (! condition) {
|
||||||
|
printf("%s:%d: assertion failed: %s\n",
|
||||||
|
FILENAME, FNR, string) > "/dev/stderr"
|
||||||
|
_assert_exit = 1
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
115
curate.mk
Normal file
115
curate.mk
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
#> content.makefile
|
||||||
|
#
|
||||||
|
#> Build
|
||||||
|
#>
|
||||||
|
#> This Makefile handles creating, building, and publishing posts for a Gemini
|
||||||
|
#> site.
|
||||||
|
#>
|
||||||
|
# The key challenge here is creating the index files.
|
||||||
|
# 1. Create a file with index entries
|
||||||
|
# 2. Extract a list of tags to file
|
||||||
|
# 3.
|
||||||
|
#
|
||||||
|
# © 2023 Andrew Stryker <axs@sdf.org>
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# Configuration
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Record the name of this Makefile
|
||||||
|
self ::= $(lastword ${MAKEFILE_LIST})
|
||||||
|
|
||||||
|
# Load environment variables if needed--not the case when this is called from
|
||||||
|
# the main Makefile
|
||||||
|
ifndef ENV_LOADED
|
||||||
|
|
||||||
|
# Assume the base directory is two levels up if not defined
|
||||||
|
MAKO_DIR ?= ../..
|
||||||
|
|
||||||
|
include ${MAKO_DIR}/environment.mk
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Use the current directory as the content section name
|
||||||
|
content_section ::= $(shell basename ${CURDIR})
|
||||||
|
staging_dir ::= ${STAGING}/${content_section}
|
||||||
|
|
||||||
|
# Gather file lists
|
||||||
|
templates ::= $(wildcard *.gmi.m4)
|
||||||
|
templates_expanded ::= $(addprefix ${staging_dir}/,${templates:.gmi.m4=.gmi})
|
||||||
|
|
||||||
|
gemtext ::= $(wildcard *.gmi)
|
||||||
|
gemtext_copied ::= $(addprefix ${staging_dir}/,${gemtext})
|
||||||
|
|
||||||
|
all ::= $(notdir $(filter-out _%,%.m4,%~,.%,$(wildcard *)))
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# User interface
|
||||||
|
#
|
||||||
|
#> This makefile supports the following targets:
|
||||||
|
#>
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
.PHONY: default build clean show help create
|
||||||
|
|
||||||
|
# Define the default target explicitly
|
||||||
|
default: create
|
||||||
|
|
||||||
|
create: #> Create a new post (default)
|
||||||
|
@if [ -z $${EDITOR} ]; then \
|
||||||
|
python3 create-post.py; \
|
||||||
|
else \
|
||||||
|
python3 create-post.py --edit; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
build: ${gemtext_copied} ${templates_expanded}
|
||||||
|
@echo "✓ Completed processing ${content_section}"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
|
||||||
|
show: #> Show enironment variables with values
|
||||||
|
@echo "Key variables defined in ${self}:"
|
||||||
|
@echo
|
||||||
|
@echo "Makefile list: ${MAKEFILE_LIST}"
|
||||||
|
@echo
|
||||||
|
@echo "Content section............................... ${content_section}"
|
||||||
|
@echo "Staging space................................. ${staging_dir}"
|
||||||
|
@echo
|
||||||
|
@echo "Templates found:"
|
||||||
|
@for x in ${templates}; do echo "\t$$x"; done
|
||||||
|
@echo
|
||||||
|
@echo "Gemtext files found:"
|
||||||
|
@for x in ${gemtext}; do echo "\t\t$$x"; done
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean: #> Delete generated files
|
||||||
|
@rm -rf ${staging_dir}
|
||||||
|
@echo "✓ Deleted ${staging_dir} and everything in it"
|
||||||
|
|
||||||
|
help: #> Display this help message
|
||||||
|
@awk -f ${AWKHELP} ${self}
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# File system interface
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
${staging_dir}:
|
||||||
|
@mkdir -p $@
|
||||||
|
@echo "\t✓ Created staging space: $@"
|
||||||
|
|
||||||
|
${templates_expanded}: ${staging_dir}/%: %.m4 ${staging_dir} ${FENCE} ${all}
|
||||||
|
@m4 --include=${MAKO_DIR} $< > $@
|
||||||
|
@echo "\t✓ Generated $@"
|
||||||
|
|
||||||
|
${gemtext_copied}: ${staging_dir}/%: % ${staging_dir}
|
||||||
|
@cat $< > $@
|
||||||
|
@echo "\t✓ Copied $@"
|
||||||
|
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
125
environment.mk
Normal file
125
environment.mk
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
#> environment.mk
|
||||||
|
#>
|
||||||
|
#> Define global environment variables
|
||||||
|
#>
|
||||||
|
#> This file is typically included from the main Makefile rather called
|
||||||
|
#> directly. Its purpose is to keep the responsbility of the main Mainfile
|
||||||
|
#> compact. The responsbility of this Makefile is to define global
|
||||||
|
#> environment variables, some of which it read from a user created file.
|
||||||
|
#>
|
||||||
|
#
|
||||||
|
# © 2023 Andrew Stryker <axs@sdf.org>
|
||||||
|
#
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
|
||||||
|
# Track file name of caller
|
||||||
|
ifdef self
|
||||||
|
caller ::= self
|
||||||
|
endif
|
||||||
|
|
||||||
|
self ::= $(notdir $(lastword ${MAKEFILE_LIST}))
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# Configuration
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
ifndef ENV_LOADED
|
||||||
|
|
||||||
|
# Track loading the environment
|
||||||
|
ENV_LOADED ::= 1
|
||||||
|
export ENV_LOADED
|
||||||
|
|
||||||
|
# Avoid an unexpected shell environment
|
||||||
|
SHELL = /bin/sh
|
||||||
|
export SHELL
|
||||||
|
|
||||||
|
# Base/root directory of the build system. Allows us to use absolute paths.
|
||||||
|
MAKO_DIR ?= ${CURDIR}
|
||||||
|
export MAKO_DIR
|
||||||
|
|
||||||
|
# Place for user content
|
||||||
|
CONTENT ?= ${MAKO_DIR}/content
|
||||||
|
CONTENT ::= $(strip ${CONTENT})
|
||||||
|
export CONTENT
|
||||||
|
|
||||||
|
# User-defined configuration file
|
||||||
|
site_env ?= ${CONTENT}/site-env
|
||||||
|
site_env ::= $(strip ${site_env})
|
||||||
|
|
||||||
|
ifeq ($(strip $(shell [ -r ${site_env} ] && echo ${site_env})),)
|
||||||
|
$(info Generate a site configuration file first via `make configure`)
|
||||||
|
$(error Configuration file ${site_env} not readable.)
|
||||||
|
else
|
||||||
|
include ${site_env}
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Place for intermediate files
|
||||||
|
WORKING ?= ${MAKO_DIR}/workspace
|
||||||
|
WORKING ::= $(strip ${WORKING})
|
||||||
|
export WORKING
|
||||||
|
|
||||||
|
# Place for site files ready to be transferred to the site
|
||||||
|
STAGING ?= ${MAKO_DIR}/staging
|
||||||
|
STAGING ::= $(strip ${STAGING})
|
||||||
|
export STAGING
|
||||||
|
|
||||||
|
# Makefiles
|
||||||
|
CURATE_MAKE ::= ${MAKO_DIR}/curate.mk
|
||||||
|
INDEX_MAKE ::= ${MAKO_DIR}/index.mk
|
||||||
|
|
||||||
|
# M4 fencing for raw text
|
||||||
|
FENCE ::= ${MAKO_DIR}/fence.m4
|
||||||
|
export FENCE
|
||||||
|
|
||||||
|
# Help generation
|
||||||
|
AWKHELP ::= ${MAKO_DIR}/generate-help.awk
|
||||||
|
export AWKHELP
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# User interface targets
|
||||||
|
#
|
||||||
|
#> User facing targets:
|
||||||
|
#>
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Only define targets if called directly
|
||||||
|
ifeq ($(firstword ${MAKEFILE_LIST}), ${self})
|
||||||
|
|
||||||
|
.PHONY: default show help
|
||||||
|
|
||||||
|
default: show
|
||||||
|
|
||||||
|
show: #> Show key variables
|
||||||
|
@echo "Key variables defined in ${self}:"
|
||||||
|
@echo
|
||||||
|
@echo "\tBase/root directory of the build system..... ${MAKO_DIR}"
|
||||||
|
@echo "\tUsef-defined configuration.................. ${site_env}"
|
||||||
|
@echo
|
||||||
|
# future location for templates
|
||||||
|
@echo "\tLocation of user content.................... ${CONTENT}"
|
||||||
|
@echo "\tWorking area for intermediate files......... ${WORKING}"
|
||||||
|
@echo "\tStaging area for site....................... ${STAGING}"
|
||||||
|
@echo
|
||||||
|
@echo "\tM4 macro for raw text....................... ${FENCE}"
|
||||||
|
@echo "\tHelp generation AWK file.................... ${AWKHELP}"
|
||||||
|
|
||||||
|
help: #> Show this help message
|
||||||
|
@awk -f ${AWKHELP} ${self}
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Restore value of self to the caller's file name if possible
|
||||||
|
ifdef caller
|
||||||
|
self ::= ${caller}
|
||||||
|
endif
|
||||||
|
|
||||||
|
#>
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
96
fence.m4
Normal file
96
fence.m4
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
dnl ---------------------------------------------------------------------------#
|
||||||
|
dnl fence.m4
|
||||||
|
dnl
|
||||||
|
dnl Fence pre-formated text or code into Markdown and Gemtext documents
|
||||||
|
dnl
|
||||||
|
dnl Both Markdown extensions and Gemini use backticks to fence 'raw' text
|
||||||
|
dnl blocks. m4 uses backticks to quote text. This file simplifies managing
|
||||||
|
dnl text that would otherwise be subject to macro quoting rules.
|
||||||
|
dnl
|
||||||
|
dnl This file provides four macros to resolve this conflict:
|
||||||
|
dnl
|
||||||
|
dnl * DELIMITER -- insert three backticks delimiter
|
||||||
|
dnl * FENCE -- wraps its argument inside a backtick fence
|
||||||
|
dnl * CODE -- wraps its arguement with backticks for inline code
|
||||||
|
dnl * CODEBLOCK -- forms a code block where the first argument is placed
|
||||||
|
dnl after the leading backticks and the second argument is
|
||||||
|
dnl the code
|
||||||
|
dnl
|
||||||
|
dnl In some circumstances, changing m4's quote characters will make for
|
||||||
|
dnl a better solution.
|
||||||
|
dnl
|
||||||
|
dnl Note, the implementation uses "-<-<" and ">->-" as temporary m4 quote
|
||||||
|
dnl characters.
|
||||||
|
dnl
|
||||||
|
dnl Examples:
|
||||||
|
dnl
|
||||||
|
dnl FENCE(foo) =>
|
||||||
|
dnl ```
|
||||||
|
dnl foo
|
||||||
|
dnl ```
|
||||||
|
dnl
|
||||||
|
dnl CODEBLOCK(sh, `echo foo') =>
|
||||||
|
dnl ```sh
|
||||||
|
dnl echo foo
|
||||||
|
dnl ```
|
||||||
|
dnl
|
||||||
|
dnl CODE(`x = 3') =>
|
||||||
|
dnl `x = 3`
|
||||||
|
dnl ''
|
||||||
|
dnl
|
||||||
|
dnl Use in combination `undivert' to include code files:
|
||||||
|
dnl
|
||||||
|
dnl CODEBLOCK(c, `undivert(`hellow-world.c')')
|
||||||
|
dnl
|
||||||
|
dnl Use in combination with `syscmd`:
|
||||||
|
dnl
|
||||||
|
dnl FENCE(`syscmd(`ls')')
|
||||||
|
dnl
|
||||||
|
dnl
|
||||||
|
dnl Usage:
|
||||||
|
dnl
|
||||||
|
dnl Use the 'include()' macro to import this macros into your m4 file.
|
||||||
|
dnl
|
||||||
|
dnl Author: axs@sdf.org
|
||||||
|
dnl
|
||||||
|
dnl ---------------------------------------------------------------------------#
|
||||||
|
dnl
|
||||||
|
dnl Write backticks, handling the conflict with m4 quoting
|
||||||
|
dnl
|
||||||
|
dnl Following advice from Michael Breen, we:
|
||||||
|
dnl * Redefine the quote characters
|
||||||
|
dnl * Write the backticks
|
||||||
|
dnl * Surpress the apostrophies
|
||||||
|
dnl * Revert the quote characters to the orginal state
|
||||||
|
dnl
|
||||||
|
dnl see: https://mbreen.com/m4.html
|
||||||
|
dnl
|
||||||
|
define(`DELIMITER', `changequote(`-<-<',`>->-')```dnl'''
|
||||||
|
changequote`'')dnl
|
||||||
|
dnl
|
||||||
|
dnl ---------------------------------------------------------------------------#
|
||||||
|
dnl
|
||||||
|
dnl Create a pre-formatted text block
|
||||||
|
dnl
|
||||||
|
define(`FENCE', `dnl
|
||||||
|
DELIMITER()
|
||||||
|
$1`'dnl
|
||||||
|
DELIMITER()
|
||||||
|
')dnl
|
||||||
|
dnl ---------------------------------------------------------------------------#
|
||||||
|
dnl
|
||||||
|
dnl Create a code block
|
||||||
|
dnl
|
||||||
|
define(`CODEBLOCK', `dnl
|
||||||
|
DELIMITER()$1
|
||||||
|
$2
|
||||||
|
DELIMITER()
|
||||||
|
')dnl
|
||||||
|
dnl ---------------------------------------------------------------------------#
|
||||||
|
dnl
|
||||||
|
dnl Inline code
|
||||||
|
dnl
|
||||||
|
define(`CODE', `changequote(`-<-<',`>->-')`$1`dnl''
|
||||||
|
changequote`'')dnl
|
||||||
|
dnl
|
||||||
|
dnl ---------------------------------------------------------------------------#
|
225
index.mk
Normal file
225
index.mk
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
# index.mk
|
||||||
|
#
|
||||||
|
#> Index Gemini site content
|
||||||
|
#>
|
||||||
|
#> This Makefile builds content indicies for a Gemini site.
|
||||||
|
#>
|
||||||
|
#
|
||||||
|
# Allowing posts to be m4 files introduces complexity without clear benefit.
|
||||||
|
# Thus we are
|
||||||
|
#
|
||||||
|
# Strategy:
|
||||||
|
# 1. Mark all *.gmi files as posts.
|
||||||
|
# 2. Limit macros to:
|
||||||
|
# a. Section index
|
||||||
|
# b. Tagged index
|
||||||
|
# c. Header
|
||||||
|
# d. Footer
|
||||||
|
# 4. Create index entries for each *.gmi file.
|
||||||
|
# 5. Build the full list of tags.
|
||||||
|
# 6. Generate the post as `cat footer.gmi post.gmi footer.gmi`.
|
||||||
|
# 7. Build the tagged index files from the list of tags.
|
||||||
|
# 8. Build index.gmi from tag list.
|
||||||
|
#
|
||||||
|
# The key challenge is step 7. We do not know how to build this until we
|
||||||
|
# completed step 5. Two possible approaches:
|
||||||
|
# 1. Create a macro
|
||||||
|
# 2. Recurse into another Makefile.
|
||||||
|
#
|
||||||
|
# © 2023 Andrew Stryker <axs@sdf.org>
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# Configuration
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
# Record the name of this Makefile
|
||||||
|
self ::= $(lastword ${MAKEFILE_LIST})
|
||||||
|
|
||||||
|
# Load environment variables if needed--not the case when this is called from
|
||||||
|
# the main Makefile
|
||||||
|
ifndef ENV_LOADED
|
||||||
|
|
||||||
|
# Assume the base directory is two levels up if not defined
|
||||||
|
MAKO_DIR ?= ../..
|
||||||
|
|
||||||
|
include ${MAKO_DIR}/environment.mk
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Use the current directory as the content section name
|
||||||
|
content_section ::= $(shell basename ${CURDIR})
|
||||||
|
working_dir ::= ${WORKING}/${content_section}
|
||||||
|
staging_dir ::= ${STAGING}/${content_section}
|
||||||
|
|
||||||
|
# Define using the same definition as in the main Makefile
|
||||||
|
build_date_msg ?= This page was built on $$(date).
|
||||||
|
|
||||||
|
# Define special files
|
||||||
|
index_template ::= index.gmi.m4
|
||||||
|
index ::= ${staging_dir}/index.gmi
|
||||||
|
|
||||||
|
header_template ::= header.gmi.m4
|
||||||
|
header ::= ${working_dir}/header.gmi
|
||||||
|
|
||||||
|
footer_template ::= footer.gmi.m4
|
||||||
|
footer ::= ${working_dir}/footer.gmi
|
||||||
|
|
||||||
|
# Capture potential dependencies
|
||||||
|
all ::= $(notdir $(filter-out _%,%~,.%,$(wildcard *)))
|
||||||
|
|
||||||
|
# all good above this line
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# Configuration
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tagged_index_template ?= tagged-index.gmi.m4
|
||||||
|
|
||||||
|
posts ::= $(wildcard *.gmi)
|
||||||
|
targets ::= $(addprefix ${STAGING}/, ${posts})
|
||||||
|
|
||||||
|
# support indexing
|
||||||
|
entries ::= $(addprefix ${WORKSPACE}/, $(patsubst %.gmi, %.lnk, ${posts}))
|
||||||
|
tag_list ::= ${WORKSPACE}/tag-list
|
||||||
|
|
||||||
|
|
||||||
|
#tags = $(shell cut --delimiter ' ' --fields 3 ${tag_list} | sort)
|
||||||
|
#tagged_indicies = $(addprefix ${STAGING}/, $(addsuffix .gmi, ${tags}))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: is there a name for elements header and footer? How can this work with
|
||||||
|
# templates?
|
||||||
|
# header and footer
|
||||||
|
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# User interface
|
||||||
|
#
|
||||||
|
#> This makefile supports the following targets:
|
||||||
|
#>
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
.PHONY: default build clean show help create
|
||||||
|
|
||||||
|
# define the default target explicitly
|
||||||
|
default: create
|
||||||
|
|
||||||
|
create: #> Create a new post (default)
|
||||||
|
@if [ -z $${EDITOR} ]; then \
|
||||||
|
python3 create-post.py; \
|
||||||
|
else \
|
||||||
|
python3 create-post.py --edit; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
build: ${index}
|
||||||
|
@echo "✓ Completed processing ${content_section}"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
|
||||||
|
show: #> Show enironment variables with values
|
||||||
|
@echo staging area: ${STAGING}
|
||||||
|
@echo workspace: ${WORKSPACE}
|
||||||
|
@echo post_index: ${post_index}
|
||||||
|
@echo ${build_date_msg}
|
||||||
|
@echo targets: ${post_targets}
|
||||||
|
@echo header: ${header}
|
||||||
|
@echo footer: ${footer}
|
||||||
|
@echo tag list: ${tag_list}
|
||||||
|
|
||||||
|
clean: #> Delete generated files
|
||||||
|
@rm -rf ${STAGING} ${WORKSPACE}
|
||||||
|
@echo "\t✓ Deleted intermediate files"
|
||||||
|
@echo "\t✓ Deleted all posts in ${STAGING}"
|
||||||
|
|
||||||
|
help: #> Display this help message
|
||||||
|
@awk -f ../generate-help.awk ${MAKEFILE_LIST}
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
#
|
||||||
|
# File system interface
|
||||||
|
#
|
||||||
|
#-----------------------------------------------------------------------------#
|
||||||
|
|
||||||
|
${working_dir} ${staging_dir}: %:
|
||||||
|
@mkdir -p $@
|
||||||
|
@echo "\t✓ Created space: $@"
|
||||||
|
|
||||||
|
${header} ${footer}: ${working_dir}/%: % ${working_dir} ${all}
|
||||||
|
@mkdir -p $@
|
||||||
|
@echo "\t✓ Created: $@"
|
||||||
|
|
||||||
|
${index}: ${index_template} ${header} ${footer} ${posts}
|
||||||
|
|
||||||
|
# Build posts
|
||||||
|
#
|
||||||
|
# 1. Expand header and footer macros
|
||||||
|
# 2. Concatenate header, post, footer into the staging area
|
||||||
|
${header} ${footer}: ${WORKSPACE}/%: %.m4
|
||||||
|
@echo building $@
|
||||||
|
@m4 --include=${MAKO_DIR}/fence.m4 $< > $@
|
||||||
|
@echo "\t✓ Created $@"
|
||||||
|
|
||||||
|
${targets}: ${STAGING}/%: % ${header} ${footer}
|
||||||
|
@cat ${header} $< ${footer} > $@
|
||||||
|
@echo ${build_date_msg} >> $@
|
||||||
|
@echo "\t✓ Generated $@"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the tag list (indexing data)
|
||||||
|
#
|
||||||
|
# 1. Extract indexing data from each post
|
||||||
|
# 2. Combine into one list of tags
|
||||||
|
${entries}: ${WORKSPACE}/%.lnk: ${MAKO_DIR}/create-index-entry.awk %.gmi
|
||||||
|
@awk -f $^ > $@
|
||||||
|
@echo "\t✓ Created $@"
|
||||||
|
|
||||||
|
# build the tag list
|
||||||
|
${tag_list}: ${entries}
|
||||||
|
@cat $^ | sort --unique | \
|
||||||
|
sed -e '/^---/ d; s/^\([a-zA-Z0-09]\+\).*/=> \1.gmi \1/' > $@
|
||||||
|
@echo "\t✓ Created the tags list"
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the index files
|
||||||
|
#
|
||||||
|
#
|
||||||
|
${index}: ${index_template} ${tag_list}
|
||||||
|
# build the index files
|
||||||
|
# recurse into another Makefile?
|
||||||
|
@m4 --include=${MAKO_DIR} $< > $@
|
||||||
|
|
||||||
|
|
||||||
|
#${tagged_indicies}: ${STAGING}/%.gmi: tag-index-template.gmi.m4 ${tag_list}
|
||||||
|
# @m4 --include=.. \
|
||||||
|
# --define=TAG=% \
|
||||||
|
# --define=ENTRIES=${entries} \
|
||||||
|
# --define=HEADER=${header} \
|
||||||
|
# --define=FOOTER=${footer} \
|
||||||
|
# tag-index-template.gmi.m4 $< > $@
|
||||||
|
# @echo ✓ Created index $@
|
||||||
|
|
||||||
|
# generate the index entries across all posts
|
||||||
|
${index_entries}: ${tag_list}
|
||||||
|
@grep "^---" $^ | cut --delimiter=' ' --fields=2 | sort --reverse --key=3 > $@
|
||||||
|
@echo ✓ Created $@
|
||||||
|
|
||||||
|
${index}: content-index.gmi.m4 ${STAGING} ${tag_list} ${header} ${footer} ${post_entry}
|
||||||
|
@m4 --include=.. \
|
||||||
|
--define=TAGS=${tags_list} \
|
||||||
|
--define=POSTS=${post_entry} \
|
||||||
|
--define=HEADER=${header} \
|
||||||
|
--define=FOOTER=${footer} \
|
||||||
|
$< > $@
|
||||||
|
@echo ✓ Created $@
|
||||||
|
|
||||||
|
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
|
Loading…
x
Reference in New Issue
Block a user