# BENZIN Makefile include config.mk # Directories SRC ?= src TEMPLATES ?= templates OUT ?= out # User supplied variables WEBSITE_URL ?= https://example.com WEBSITE_TITLE ?= Example Website CONVERT ?= pandoc --from=gfm+emoji --to=html --section-divs --shift-heading-level-by=1 EMOJI_SIZE ?= 20 EMOJI_STYLE ?= margin-bottom: -4px; BLOG_PREVIEW_MARKER ?= Recent blog posts # File locations PAGE_TEMPLATE ?= templates/page.html OPENRING_TEMPLATE ?= templates/openring.html RSS_TEMPLATE ?= templates/rss.xml RSS_ITEM_TEMPLATE ?= templates/rss_item.xml OPENRING_URLS ?= src/urls RSS ?= out/blog/index.xml # Sources BLOG_SOURCES=$(wildcard src/blog/*.md) EMOJI_SOURCES=$(wildcard src/public/emoji/*) PUBLIC_SOURCES=$(shell find src/public -type f) SOURCES=$(shell find src -type f -name "*.md") # Outputs TMP_HTML=$(patsubst src/%.md, tmp/%.content.html, $(SOURCES)) HTML=$(patsubst src/%.md, out/%.html, $(SOURCES)) OPENRING_FOOTER=$(patsubst templates/%, tmp/%, $(OPENRING_TEMPLATE)) BLOG_XML=$(patsubst src/%.md, tmp/%.xml, $(filter-out src/blog/index.md, $(BLOG_SOURCES))) PUBLIC=$(patsubst src/%, out/%, $(PUBLIC_SOURCES)) .PHONY: clean all serve .SECONDARY: $(TMP_HTML) $(BLOG_XML) all: $(HTML) $(RSS) $(PUBLIC) # Standalone HTML out/%.html: tmp/%.content.html tmp/%.meta.title tmp/%.meta.description $(PAGE_TEMPLATE) $(OPENRING_FOOTER) @mkdir -p $(@D) sed "/<\/main>/e cat $< $(OPENRING_FOOTER)" $(PAGE_TEMPLATE) > $@ sed -i \ -e '//{' \ -e 'a ' -e "r tmp/$*.meta.title" -e "a | $(WEBSITE_TITLE) <\/title>" \ -e 'a <meta name="description" content="' -e "r tmp/$*.meta.description" -e 'a "/>' \ -e '}' $@ out/index.html: tmp/index.content.html $(PAGE_TEMPLATE) @mkdir -p $(@D) sed "/<\/main>/e cat $<" $(PAGE_TEMPLATE) > $@ sed -i \ -e '/<head>/{' \ -e "a <title>$(WEBSITE_TITLE)<\/title>" \ -e '}' $@ # Embeddable HTML tmp/%.content.html: src/%.md tmp/emoji.sed @mkdir -p $(@D) sed -e "s/.md)/.html)/g" -f tmp/emoji.sed $< | $(CONVERT) > $@ tmp/index.content.html: src/index.md tmp/emoji.sed tmp/blog/preview.md @mkdir -p $(@D) sed -e "/$(BLOG_PREVIEW_MARKER)/r tmp/blog/preview.md" $< \ | sed -e "s/.md)/.html)/g" -f tmp/emoji.sed \ | $(CONVERT) > $@ # Metadata (TODO: parse YAML front matter) tmp/%.meta.title: src/%.md @mkdir -p $(@D) sed '/^#/q' $< | sed 's/#* //; s/:.*://;' > $@ tmp/%.meta.description: src/%.md @mkdir -p $(@D) sed '2,/^$$/!d' $< > $@ tmp/blog/%.meta.date: src/blog/%.md @mkdir -p $(@D) @date --rfc-email -d $* > $@ # Emoji sed script tmp/emoji.sed: $(EMOJI_SOURCES) @mkdir -p $(@D) for emoji in $^; do\ basename=$$(basename $$emoji); \ name=$${basename%.*}; \ echo "s|:$${name}:|<img src=\"/public/emoji/$${basename}\" alt=\"$${name}-emoji\" height=\"$(EMOJI_SIZE)\" width=\"$(EMOJI_SIZE)\" style=\"$(EMOJI_STYLE)\">|g;" >> $@; \ done # Blog preview tmp/blog/preview.md: src/blog/index.md @mkdir -p $(@D) sed -n "s/^-/ -/; s|(|(blog/| ; /^ -/p" $< | head -n 4 > $@ # RSS $(RSS): $(BLOG_XML) $(RSS_TEMPLATE) @mkdir -p $(@D) sed "/<\/channel>/e cat $(BLOG_XML)" $(RSS_TEMPLATE) > $@ sed -i \ -e '/<channel>/{' \ -e "a <title>$(WEBSITE_TITLE)<\/title>" \ -e "a <link>$(WEBSITE_URL)<\/link>" \ -e "a <lastPubDate>$$(date --rfc-email)<\/lastPubDate>" \ -e '}' $@ tmp/%.xml: tmp/%.content.html tmp/%.meta.title tmp/%.meta.date $(RSS_ITEM_TEMPLATE) @mkdir -p $(@D) sed "/CDATA/r $<" $(RSS_ITEM_TEMPLATE) > $@ sed -i \ -e '/<item>/{' \ -e 'a <title>' -e "r tmp/$*.meta.title" -e 'a <\/title>' \ -e 'a <pubDate>' -e "r tmp/$*.meta.date" -e 'a <\/pubDate>' \ -e "a <link>$(WEBSITE_URL)/$*.html<\/link>" \ -e '}' $@ # Openring $(OPENRING_FOOTER): $(OPENRING_TEMPLATE) $(OPENRING_URLS) @mkdir -p $(@D) openring $$(sed '/^#/d; s/^/-s /' $(OPENRING_URLS)) < $< > $@ # Assets out/public/%: src/public/% @mkdir -p $(@D) @cp $^ $@ out/public/emoji/%.png: src/public/emoji/%.png @mkdir -p $(@D) convert $< -resize $(EMOJI_SIZE)x$(EMOJI_SIZE) $@ # Management serve: $(HTML) quark -h 127.0.0.1 -p 8000 -d out -l clean: rm -rf tmp out/*