export DEPLOY_TARGET = vulpes@94.130.78.123:/srv/http/volpeon.ink/ export MODE = prod -include Env.mk # # FILE GROUPS # PANDOC_FILTERS := $(patsubst %,--lua-filter %,$(wildcard filters/*.lua)) GLOBAL_METADATA := $(patsubst %,--metadata-file %,$(wildcard metadata/*.yaml)) CONTENT_SRC := $(shell find content -type f -name "*.md") FEED_SRC := $(shell grep -l "^feed: *true$$" $(CONTENT_SRC)) CONTENT_TEMPLATES_SRC := $(shell find templates -type f -name "*.html") FEED_TEMPLATES_SRC := $(shell find templates -type f -name "*.xml") FONT_SRC := $(wildcard assets/fonts/*.ttf) CSS_SRC := $(shell find assets/css -type f -name "*.scss") ASSET_SRC := $(shell find content/assets -type f) STATIC_SRC := $(shell find content -type f ! -name "*.md") CONTENT_META := $(patsubst content/%.md,.cache/meta/%.json,$(CONTENT_SRC)) CONTENT_FILES := $(patsubst content/%.md,out/%.html,$(CONTENT_SRC)) FEED_FILES := $(patsubst content/%.md,out/%.xml,$(FEED_SRC)) FONT_FILES := $(patsubst assets/fonts/%.ttf,out/assets/%.woff2,$(FONT_SRC)) CSS_FILES := out/assets/style.css ICON_FILES := out/assets/icons.svg ASSET_FILES := $(FONT_FILES) $(CSS_FILES) $(ICON_FILES) $(patsubst content/assets/%,out/assets/%,$(ASSET_SRC)) STATIC_FILES := $(patsubst content/%,out/%,$(STATIC_SRC)) # # TARGETS # all: content_meta content_files feed_files font_files css_files static_files content_meta: $(CONTENT_META) content_files: $(CONTENT_FILES) feed_files: $(FEED_FILES) font_files: $(FONT_FILES) css_files: $(CSS_FILES) static_files: $(STATIC_FILES) # # RULES # .SECONDEXPANSION: namespace = $(patsubst %/index,%,$(basename $(patsubst $(2)%,%,$(1)))) subpages = $(patsubst content/%.md,.cache/meta/%.json, \ $(shell test -d $(patsubst .cache/meta%,content%,$(1)) && find $(patsubst .cache/meta%,content%,$(1)) -maxdepth 1 -type f -name "*.md" ! -name "index.md") \ $(shell test -d $(patsubst .cache/meta%,content%,$(1)) && find $(patsubst .cache/meta%,content%,$(1)) -mindepth 2 -maxdepth 2 -type f -name "index.md")) .cache/meta/%.json: content/%.md $$(call subpages,$$(call namespace,$$@,)) filters/*.lua scripts/content.lua scripts/subpages.jq scripts/metadata.json | .cache/meta $(info [META] $< -> $@) mkdir -p $(@D) $(eval PAGES_FILES = $(filter .cache/meta/%.json,$^)) $(eval NAMESPACE = $(call namespace,$@,.cache/meta)) $(if $(PAGES_FILES),jq -s --arg namespace "$(NAMESPACE)" -f scripts/subpages.jq $(PAGES_FILES) > "$@.pages",echo "{ \"pages\": [] }" > "$@.pages") pandoc \ -f markdown-citations-implicit_figures \ -t html5 \ --wrap preserve \ --no-highlight \ --metadata-file "$@.pages" \ --template scripts/metadata.json \ --metadata namespace="$(NAMESPACE)" \ --metadata file_out="$(patsubst .cache/meta/%.json,/%.html,$@)" \ $(PANDOC_FILTERS) \ -o "$@.meta" "$<" rm "$@.pages" pandoc \ -f markdown-citations-implicit_figures \ -t html5 \ --wrap preserve \ --lua-filter scripts/content.lua \ $(GLOBAL_METADATA) \ --metadata-file "$@.meta" \ $(PANDOC_FILTERS) \ -o "$@.content" "$<" jq '. + { content: $$content }' --rawfile content "$@.content" "$@.meta" > "$@" rm "$@.meta" rm "$@.content" .cache/meta.json: .cache/meta/index.json scripts/metadata.lua | .cache $(info [META] $@) mkdir -p $(@D) pandoc \ -f markdown-citations-implicit_figures \ -t html5 \ --wrap preserve \ --no-highlight \ --lua-filter scripts/metadata.lua \ $(GLOBAL_METADATA) \ --metadata-file "$<" \ --metadata build.mode="$(MODE)" \ --template scripts/metadata.json \ -o "$@.meta" "$<" jq '{ tree: . }' "$@.meta" > "$@" rm "$@.meta" .cache/assets.json: $(ASSET_FILES) | .cache $(info [ASET] $@) sha256sum $^ | sed -r 's/([0-9a-f]+) +out\/assets\/(.*)/{ "\2": "\/assets\/\2?\1" }/' | jq '{ assets: [inputs] | add | with_entries( .key |= gsub( "\\."; "_") ) }' > "$@" out/%.html: content/%.md .cache/meta.json .cache/assets.json $(CONTENT_TEMPLATES_SRC) metadata/*.yaml filters/*.lua scripts/page.lua | out $(info [MARK] $< -> $@) mkdir -p $(@D) $(eval NAMESPACE = $(call namespace,$@,out)) pandoc \ -f markdown-citations-implicit_figures \ -t html5 \ --wrap preserve \ --no-highlight \ --template templates/base.html \ --lua-filter scripts/page.lua \ $(GLOBAL_METADATA) \ --metadata-file .cache/assets.json \ --metadata-file .cache/meta.json \ --metadata build.namespace="$(NAMESPACE)" \ --metadata build.file_out="$(patsubst out/%,/%,$@)" \ $(PANDOC_FILTERS) \ -o "$@" "$<" out/%.xml: content/%.md .cache/meta.json $(FEED_TEMPLATES_SRC) metadata/*.yaml filters/*.lua scripts/page.lua | out $(info [FEED] $< -> $@) mkdir -p $(@D) $(eval NAMESPACE = $(call namespace,$@,out)) pandoc \ -f markdown-citations-implicit_figures \ -t html5 \ --wrap preserve \ --no-highlight \ --template templates/feed.xml \ --lua-filter scripts/page.lua \ $(GLOBAL_METADATA) \ --metadata-file .cache/meta.json \ --metadata build.namespace="$(NAMESPACE)" \ --metadata build.file_out="$(patsubst out/%,/%,$@)" \ $(PANDOC_FILTERS) \ -o "$@" "$<" out/%/thumbnail.png: content/%/thumbnail.png | out $(info [THMB] $< -> $@) mkdir -p $(@D) convert -thumbnail 550x280^ -gravity center -extent 550x280 "$<" png:- | pngquant - > "$@" out/%/thumbnail.jpg: content/%/thumbnail.jpg | out $(info [THMB] $< -> $@) mkdir -p $(@D) convert -thumbnail 550x280^ -gravity center -extent 550x280 "$<" ppm:- | cjpeg -quality 80 > "$@" out/assets/%.woff2: assets/fonts/%.ttf assets/fonts/glyphs.txt | out/assets $(info [FONT] $< -> $@) pyftsubset "$<" \ --text-file="assets/fonts/glyphs.txt" \ --layout-features+=ss02,ss09,dlig \ --flavor="woff2" \ --output-file="$@" out/assets/%.css: assets/css/%.scss $(CSS_SRC) | out/assets $(info [SCSS] $< -> $@) sass --load-path=node_modules "$<" | ./node_modules/.bin/postcss --use autoprefixer --use postcss-csso --no-map -o "$@" out/assets/icons.svg: | out/assets $(info [ICON] $@) node ./node_modules/iro-icons/scripts/create_sprite.js \ asterisk \ arrow-left \ arrow-right \ arrow-up-right \ shuffle \ envelope \ hash \ messages \ parallelogram \ globe \ image \ graph \ git-branch \ smile \ home \ link \ x \ chevron-left \ chevron-right \ "$@" out/%: content/% | out $(info [COPY] $< -> $@) mkdir -p $(@D) cp "$<" "$@" .cache/meta: | .cache mkdir -p .cache/meta .cache: mkdir -p .cache out/assets: | out mkdir -p out/assets out: mkdir -p out # # UTILITIES # watch: all while true; do \ inotifywait -qr -e modify -e create -e delete -e move assets content filters metadata scripts templates; \ $(MAKE); \ done serve: all python -m http.server --bind 127.0.0.1 --directory out 8080 dev: watch serve compress: all pigz -R -k -9 -- `find out -type f -iregex '.*\\.\\(css\\|js\\|json\\|html\\|xml\\|txt\\|svg\\|ico\\)'` brotli -k -- `find out -type f -iregex '.*\\.\\(css\\|js\\|json\\|html\\|xml\\|txt\\|svg\\|ico\\|woff\\)'` deploy: compress rsync --progress --stats -rvz --delete out/ "$(DEPLOY_TARGET)" clean: rm -rf out .PHONY: all watch serve dev deploy clean