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