# Copyright 2018, 2021, 2023 Vladimir Sedach <vas@oneofus.la>

# SPDX-License-Identifier: GPL-3.0-or-later

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

# Notable prerequisites:
# GNU versions of date and stat
# tidy http://www.html-tidy.org/
# xmllint https://gnome.pages.gitlab.gnome.org/libxml2/xmllint.html
# ATOM schema https://cweiske.de/tagebuch/atom-validation.htm

parts = src/parts/
header = $(parts)header.html
footer = $(parts)footer.html
blog-header = $(parts)blog-header.html
blog-topics = have-emacs-will-hack/topics

pages := $(subst src/,htdocs/,$(wildcard src/*.html))
blogposts := $(shell (for x in $(sort $(wildcard have-emacs-will-hack/posts/*.html)); do echo $$x; done) | sed '1!G;h;$$!d')
blog-entries := $(subst have-emacs-will-hack/posts/,htdocs/have-emacs-will-hack/,$(blogposts))

all: $(pages) $(blog-entries) htdocs/have-emacs-will-hack/files/current/Makefile htdocs/have-emacs-will-hack/index.html htdocs/have-emacs-will-hack/feed.xml

deploy:
	rsync -azv --delete --exclude='.well-known/' --exclude='source-code-repositories/' --exclude='tmp/' --chmod=o=rX htdocs/ vas@oneofus.la:/var/www/htdocs/oneofus.la/

preview:
	cd htdocs && python3 -m http.server 8081

# common functions

add-header = @cat $(header) > $@
add-body = @cat $< >> $@
add-last-modified = @echo '<span class="last-modified">Last modified' `stat --printf=%y $(1) | cut -c-10`'</span>' >> $@
define add-footer =
	@cat $(footer) >> $@
	@tidy -q -e $@
endef

# site

htdocs/%.html: src/%.html $(header) $(footer)
	@echo Building $@
	$(add-header)
	$(add-body)
	$(call add-last-modified,$@)
	$(add-footer)

# blog

add-blog-header = @cat $(blog-header) >> $@
post-date = $(shell echo $(notdir $(1)) | cut -c-10)
post-title = "$(shell head -n1 $(1))"
post-category = $(shell sed -n 2p $(1))
post-category-anchor = $(shell echo $(1) | tr ' ' _)
post-category-unanchor = $(shell echo $(1) | tr _ ' ')
post-content = tail -n +3

htdocs/have-emacs-will-hack/%.html: have-emacs-will-hack/posts/%.html $(header) $(footer) $(blog-header)
	@echo Building $@
	$(add-header)
	$(add-blog-header)
	@date --date=$(call post-date,$<) +"%B %e, %Y" >> $@
	@echo '<h3>'$(call post-title,$<)'</h3>' >> $@
	@echo '<p>Topic: <a href="/have-emacs-will-hack/index.html#'$(call post-category-anchor,$(call post-category,$<))'">'$(call post-category,$<)'</a></p>' >> $@
	@$(post-content) $< >> $@
	@echo '<hr /><div class="blog-footer"><em>Comments? <a href="mailto:vsedach@oneofus.la?subject=Comment%20about%20blog%20post%20'$(basename $(@F))'">Email me</a> and I will add them here.</em>' >> $@
	$(call add-last-modified,$<)
	@echo '</div>' >> $@
	$(add-footer)

define add-blog-entry-list =
	@echo '<table class="blog-post-list">' >> $@
	@$(foreach post,$(1),echo '<tr><td><a href="/have-emacs-will-hack/'$(notdir $(post))'">'$(call post-date,$(post))'</a></td><td><a href="/have-emacs-will-hack/'$(notdir $(post))'">'$(call post-title,$(post))'</a></td></tr>' >> $@;)
endef

define make-blog-topic-list-files =
	@-rm $(wildcard $(blog-topics)/*)
	@$(foreach post,$(blogposts),echo $(post) >> '$(blog-topics)/$(call post-category-anchor,$(call post-category,$(post)))';)
endef

define output-topic-index =
	echo '<h4><a name="'$(notdir $(1))'" href="#'$(notdir $(1))'">'$(call post-category-unanchor,$(notdir $(1)))'</a></h4>' >> $@
	$(call add-blog-entry-list,$(shell cat $(1)))
	@echo '</table>' >> $@;
endef

define add-blog-topics =
	$(call make-blog-topic-list-files)
	@$(foreach topic-file,$(sort $(wildcard $(blog-topics)/*)),$(call output-topic-index,$(topic-file)))
endef

htdocs/have-emacs-will-hack/index.html: $(blogposts) $(header) $(footer) $(blog-header)
	@echo Building blog index page
	$(add-header)
	$(add-blog-header)
	@echo '<p><a href="/have-emacs-will-hack/feed.xml">ATOM feed</a></p>' >> $@
	@echo '<h3>All Posts</h3>' >> $@
	$(call add-blog-entry-list,$(blogposts))
	@echo '</table>' >> $@
	@echo '<h3>By Topic</h3>' >> $@
	$(call add-blog-topics)
	$(call add-last-modified,$@)
	$(add-footer)

# this Makefile as featured in the blog

htdocs/have-emacs-will-hack/files/current/Makefile: Makefile
	@cp $< $@

# blog feed, RFC 4287 Atom

recent-posts := $(wordlist 1,6,$(blogposts))
blog-base = https://oneofus.la/have-emacs-will-hack/

htdocs/have-emacs-will-hack/feed.xml: $(recent-posts) have-emacs-will-hack/feed-header.xml
	@echo Building blog ATOM feed
	@cat have-emacs-will-hack/feed-header.xml > $@
	@echo '<updated>'$(call post-date,$(firstword $(recent-posts)))'T12:00:00Z</updated>' >> $@
	@$(foreach post,$(recent-posts),echo '<entry><title>'$(call post-title,$(post))'</title><id>'$(blog-base)$(notdir $(post))'</id><updated>'$(call post-date,$(post))'T12:00:00Z</updated><link rel="alternate" type="text/html" href="'$(blog-base)$(notdir $(post))'"/><category term="'$(call post-category,$(post))'"/><content type="html" xml:lang="en" xml:base="'$(blog-base)'">' >> $@; $(post-content) $(post) | recode utf8..h0 >> $@; echo '</content></entry>' >> $@;)
	@echo '</feed>' >> $@
	@xmllint --noout --relaxng atom-schema.rng htdocs/have-emacs-will-hack/feed.xml

# front page

htdocs/index.html: src/index.html $(recent-posts) $(parts)index-other-things.html $(header) $(footer)
	@echo Building front page
	$(add-header)
	$(add-body)
	$(call add-blog-entry-list,$(recent-posts))
	@cat $(parts)index-other-things.html >> $@
	$(call add-last-modified,$@)
	$(add-footer)
