mako/index.mk

226 lines
6.0 KiB
Makefile

#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
# 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 $@
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#