diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 389891f..b4b7a51 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -5,7 +5,8 @@
(`-`). Not underscores, and definitely not spaces.
- Recipe must be based, i.e. good traditional and substantial food. Nothing
ironic, meme-tier hyper-sugary, meat-substitute, etc.
-- **ADD YOUR RECIPE TO THE LIST ON `index.md` OR NO ONE WILL EVER SEE IT.**
+- Be sure to add a small number of relevant tags to your recipe (and remove
+ the dummy tags). Try to use already existing tags.
- Don't include salt and pepper and other ubiquitous things in the ingredients
list.
-->
diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml
index c3f9547..5c736cc 100644
--- a/.github/workflows/upload.yml
+++ b/.github/workflows/upload.yml
@@ -29,5 +29,4 @@ jobs:
script: |
cd repo
git pull --force origin master
- mkdir -p dest
- ./ssg5 src dest "Based Cooking (https://based.cooking)" "https://based.cooking"
+ make clean deploy
diff --git a/.gitignore b/.gitignore
index 89ea643..5ae25cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
-dest
+rss.xml
+atom.xml
+blog
+tags
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f632891
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,198 @@
+#!/usr/bin/make -f
+
+BLOG := $(MAKE) -f $(lastword $(MAKEFILE_LIST)) --no-print-directory
+ifneq ($(filter-out help,$(MAKECMDGOALS)),)
+include config
+endif
+
+# The following can be configured in config
+BLOG_DATE_FORMAT_INDEX ?= %x
+BLOG_DATE_FORMAT ?= %x %X
+BLOG_TITLE ?= blog
+BLOG_DESCRIPTION ?= blog
+BLOG_URL_ROOT ?= http://localhost/blog
+BLOG_FEED_MAX ?= 20
+BLOG_FEEDS ?= rss atom
+BLOG_SRC ?= articles
+
+
+.PHONY: help init build deploy clean taglist
+
+ARTICLES = $(shell git ls-tree HEAD --name-only -- $(BLOG_SRC)/ 2>/dev/null)
+TAGFILES = $(patsubst $(BLOG_SRC)/%.md,tags/%,$(ARTICLES))
+
+help:
+ $(info make init|build|deploy|clean|taglist)
+
+init:
+ mkdir -p $(BLOG_SRC) data templates
+ printf '
' > templates/article_list_footer.html
+ printf '' > templates/index_footer.html
+ printf '' > templates/tag_index_header.html
+ printf '' > templates/tag_index_footer.html
+ printf '' > templates/article_header.html
+ printf '' > templates/article_footer.html
+ printf 'blog\n' > .git/info/exclude
+
+build: blog/index.html tagpages $(patsubst $(BLOG_SRC)/%.md,blog/%.html,$(ARTICLES)) $(patsubst %,blog/%.xml,$(BLOG_FEEDS))
+
+deploy: build
+ rsync -rLtvz $(BLOG_RSYNC_OPTS) blog/ data/ $(BLOG_REMOTE)
+
+clean:
+ rm -rf blog tags
+
+config:
+ printf 'BLOG_REMOTE:=%s\n' \
+ '$(shell printf "Blog remote (eg: host:/var/www/html): ">/dev/tty; head -n1)' \
+ > $@
+
+tags/%: $(BLOG_SRC)/%.md
+ mkdir -p tags
+ grep -i '^; *tags:' "$<" | cut -d: -f2- | sed 's/ */\n/g' | sed '/^$$/d' | sort -u > $@
+
+blog/index.html: index.md $(ARTICLES) $(TAGFILES) $(addprefix templates/,$(addsuffix .html,header index_header tag_list_header tag_entry tag_separator tag_list_footer article_list_header article_entry article_separator article_list_footer index_footer footer))
+ mkdir -p blog
+ TITLE="$(BLOG_TITLE)"; \
+ PAGE_TITLE="$(BLOG_TITLE)"; \
+ export TITLE; \
+ export PAGE_TITLE; \
+ envsubst < templates/header.html > $@; \
+ envsubst < templates/index_header.html >> $@; \
+ envsubst < templates/tag_list_header.html >> $@; \
+ first=true; \
+ for t in $(shell cat $(TAGFILES) | sort -u); do \
+ "$$first" || envsubst < templates/tag_separator.html; \
+ NAME="$$t" \
+ URL="@$$t.html" \
+ envsubst < templates/tag_entry.html; \
+ first=false; \
+ done >> $@; \
+ envsubst < templates/tag_list_footer.html >> $@; \
+ envsubst < templates/article_list_header.html >> $@; \
+ first=true; \
+ echo $(ARTICLES); \
+ for f in $(ARTICLES); do \
+ printf '%s ' "$$f"; \
+ git log -n 1 --diff-filter=A --date="format:%s $(BLOG_DATE_FORMAT_INDEX)" --pretty=format:'%ad%n' -- "$$f"; \
+ done | sort | cut -d" " -f1,3- | while IFS=" " read -r FILE DATE; do \
+ "$$first" || envsubst < templates/article_separator.html; \
+ URL="`printf '%s' "\$$FILE" | sed 's,^$(BLOG_SRC)/\(.*\).md,\1,'`.html" \
+ DATE="$$DATE" \
+ TITLE="`head -n1 "\$$FILE" | sed -e 's/^# //g'`" \
+ envsubst < templates/article_entry.html; \
+ first=false; \
+ done >> $@; \
+ envsubst < templates/article_list_footer.html >> $@; \
+ markdown < index.md >> $@; \
+ envsubst < templates/index_footer.html >> $@; \
+ envsubst < templates/footer.html >> $@; \
+
+
+blog/tag/%.html: $(ARTICLES) $(addprefix templates/,$(addsuffix .html,header tag_header index_entry tag_footer footer))
+
+.PHONY: tagpages
+tagpages: $(TAGFILES)
+ +$(BLOG) $(patsubst %,blog/@%.html,$(shell cat $(TAGFILES) | sort -u))
+
+blog/@%.html: $(TAGFILES) $(addprefix templates/,$(addsuffix .html,header tag_index_header tag_list_header tag_entry tag_separator tag_list_footer article_list_header article_entry article_separator article_list_footer tag_index_footer footer))
+ mkdir -p blog
+ PAGE_TITLE="Articles tagged $* — $(BLOG_TITLE)"; \
+ TAGS="$*"; \
+ TITLE="$(BLOG_TITLE)"; \
+ export PAGE_TITLE; \
+ export TAGS; \
+ export TITLE; \
+ envsubst < templates/header.html > $@; \
+ envsubst < templates/tag_index_header.html >> $@; \
+ envsubst < templates/article_list_header.html >> $@; \
+ first=true; \
+ for f in $(shell grep -FH '$*' $(TAGFILES) | sed 's,^tags/\([^:]*\):.*,$(BLOG_SRC)/\1.md,'); do \
+ printf '%s ' "$$f"; \
+ git log -n 1 --diff-filter=A --date="format:%s $(BLOG_DATE_FORMAT_INDEX)" --pretty=format:'%ad%n' -- "$$f"; \
+ done | sort | cut -d" " -f1,3- | while IFS=" " read -r FILE DATE; do \
+ "$$first" || envsubst < templates/article_separator.html; \
+ URL="`printf '%s' "\$$FILE" | sed 's,^$(BLOG_SRC)/\(.*\).md,\1,'`.html" \
+ DATE="$$DATE" \
+ TITLE="`head -n1 "\$$FILE" | sed -e 's/^# //g'`" \
+ envsubst < templates/article_entry.html; \
+ first=false; \
+ done >> $@; \
+ envsubst < templates/article_list_footer.html >> $@; \
+ envsubst < templates/tag_index_footer.html >> $@; \
+ envsubst < templates/footer.html >> $@; \
+
+
+blog/%.html: $(BLOG_SRC)/%.md $(addprefix templates/,$(addsuffix .html,header article_header tag_link_header tag_link tag_link_footer article_footer footer))
+ mkdir -p blog
+ TITLE="$(shell head -n1 $< | sed 's/^# \+//')"; \
+ export TITLE; \
+ PAGE_TITLE="$${TITLE} — $(BLOG_TITLE)"; \
+ export PAGE_TITLE; \
+ AUTHOR="$(shell git log --format="%an" -- "$<" | tail -n 1)"; \
+ export AUTHOR; \
+ DATE_POSTED="$(shell git log -n 1 --diff-filter=A --date="format:$(BLOG_DATE_FORMAT)" --pretty=format:'%ad' -- "$<")"; \
+ export DATE_POSTED; \
+ DATE_EDITED="$(shell git log -n 1 --date="format:$(BLOG_DATE_FORMAT)" --pretty=format:'%ad' -- "$<")"; \
+ export DATE_EDITED; \
+ TAGS="$(shell grep -i '^; *tags:' "$<" | cut -d: -f2- | paste -sd ',')"; \
+ export TAGS; \
+ envsubst < templates/header.html > $@; \
+ envsubst < templates/article_header.html >> $@; \
+ sed -e '/^;/d' < $< | markdown -f fencedcode >> $@; \
+ envsubst < templates/tag_link_header.html >> $@; \
+ for i in $${TAGS} ; do \
+ TAG_NAME="$$i" \
+ TAG_LINK="./@$$i.html" \
+ envsubst < templates/tag_link.html >> $@; \
+ done; \
+ envsubst < templates/tag_link_footer.html >> $@; \
+ envsubst < templates/article_footer.html >> $@; \
+ envsubst < templates/footer.html >> $@; \
+
+blog/rss.xml: $(ARTICLES)
+ printf '\n\n\n%s\n%s\n%s\n' \
+ "$(BLOG_TITLE)" "$(BLOG_URL_ROOT)" "$(BLOG_DESCRIPTION)" > $@
+ for f in $(ARTICLES); do \
+ printf '%s ' "$$f"; \
+ git log -n 1 --diff-filter=A --date="format:%s %a, %d %b %Y %H:%M:%S %z" --pretty=format:'%ad%n' -- "$$f"; \
+ done | sort -k2nr | head -n $(BLOG_FEED_MAX) | cut -d" " -f1,3- | while IFS=" " read -r FILE DATE; do \
+ printf '\n%s\n%s\n%s\n%s\n%s\n\n' \
+ "`head -n 1 $$FILE`" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE`.html" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE`.html" \
+ "$$DATE" \
+ "`sed -n '1d;/^$$/{2{d;b};q};p' < $$FILE`"; \
+ done >> $@
+ printf '\n\n' >> $@
+
+blog/atom.xml: $(ARTICLES)
+ printf '\n\n%s\n%s\n%s\n\n%s\n\n' \
+ "$(BLOG_TITLE)" "$(BLOG_DESCRIPTION)" "$(shell date +%Y-%m-%dT%H:%M:%SZ)" "$(BLOG_URL_ROOT)" "$(BLOG_URL_ROOT)/atom.xml" "$(BLOG_URL_ROOT)/atom.xml" > $@
+ for f in $(ARTICLES); do \
+ printf '%s ' "$$f"; \
+ git log -n 1 --diff-filter=A --date="format:%s %Y-%m-%dT%H:%M:%SZ" --pretty=format:'%ad %aN%n' -- "$$f"; \
+ done | sort -k2nr | head -n $(BLOG_FEED_MAX) | cut -d" " -f1,3- | while IFS=" " read -r FILE DATE AUTHOR; do \
+ printf '\n%s\n\n%s\n%s\n%s\n%s\n%s\n\n' \
+ "`head -n 1 $$FILE`" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE`.html" \
+ "$(BLOG_URL_ROOT)/`basename $$FILE`.html" \
+ "$$DATE" \
+ "`git log -n 1 --date="format:%Y-%m-%dT%H:%M:%SZ" --pretty=format:'%ad' -- "$$FILE"`" \
+ "$$AUTHOR" \
+ "`sed -n '1d;/^$$/{2{d;b};q};p' < $$FILE`"; \
+ done >> $@
+ printf '\n' >> $@
+
+taglist:
+ grep -RIh '^;tags:' src | cut -d' ' -f2- | tr ' ' '\n' | sort | uniq
diff --git a/README.md b/README.md
index 95c4ab9..b0821cb 100644
--- a/README.md
+++ b/README.md
@@ -12,20 +12,51 @@
## Rules for submission
+- Recipes should start with a title, with a single `#`, *on the first line*. No
+ empty line at the top, not trailing line at the end. The file needs to be `\n`
+ terminated in linux-fashion (if you're on linux you don't need to care, it
+ should be automatic).
- Recipes should be `.md` files in the `src/` directory. Look at already
existing `.md` files for examples or see [example](example.md).
- File names should be the name of the dish with words separated by hypens
(`-`). Not underscores, and definitely not spaces.
- Recipe must be based, i.e. good traditional and substantial food. Nothing
ironic, meme-tier hyper-sugary, meat-substitute, etc.
-- **ADD YOUR RECIPE TO THE LIST ON `index.md` OR NO ONE WILL EVER SEE IT.**
- Don't include salt and pepper and other ubiquitous things in the ingredients
list.
**If you fail to do these things, I will close your submission and you will have to resubmit. I am tired of having to fix more than 50% of submissions.**
+### Tags
+
+You can (and should) add tags at the end of your recipe. The syntax is:
+```
+;tags: tag1 tag2 tag3
+```
+
+The tag line should be a single line, at the end of the markdown file, preceded
+by a blank line.
+
+Add between 1 and 4 tags, **prioritize existing tags**. As a general guideline,
+add the country from which the recipe originates if the recipe is representative
+of said country, using the adjective form (eg. *mexican*, *italian*, etc). Tag
+the main ingredient if it's something slightly special.
+
+List of special, categorical tags to use if relevant:
+- `basic`: for basic recipes that aren't meant to be stand alone but are supposed
+ to be incorporated in another recipe.
+- `breakfast`
+- `desert`
+- `drink`
+- `quick`: for recipes that can be cooked in under ~20 minutes.
+- `side`: side dishes such as mash, fries, etc.
+- `snack`
+- `spread`
+
### Images
+Images are stored in `data/pix`.
+
Each recipe can have a title image at the top and perhaps
several instructional images as absolutely necessary.
@@ -43,8 +74,8 @@ they should be numbered with two digits like: `pix/chicken-parmesan-01.webp`, et
## About the site
-The front page, for now, will just be a list of recipes
-and when adding a `.md` page, please manually add a link to it in the list.
+The front page, for now, will just be a list of recipes automatically generated
+from the content of `src`.
As more articles are added, the site will be reorganized, categorized
or will implement server-side scripting or searches.
This is not necessary yet though.
@@ -52,10 +83,6 @@ This is not necessary yet though.
I don't really want images of recipes on the mainpage yet.
I'll think about how best to do it to minimize bandwidth if possible.
-This site is generated with [Roman Zolotarev](https://www.romanzolotarev.com/)'s
-[ssg5](https://www.romanzolotarev.com/ssg.html) which is also included in this
-repo for replicability.
-
## curl/Search function in the future
I eventually want a command-line/curl interface to this site.
diff --git a/config b/config
new file mode 100644
index 0000000..8f06a8e
--- /dev/null
+++ b/config
@@ -0,0 +1,6 @@
+BLOG_TITLE:=Based Cooking
+BLOG_REMOTE:=/var/www/based.cooking
+BLOG_DATE_FORMAT_INDEX:=%F
+BLOG_DATE_FORMAT:=%F
+BLOG_SRC:=src
+BLOG_URL_ROOT:=https://based.cooking/
diff --git a/src/pix/beef-goulash.webp b/data/pix/beef-goulash.webp
similarity index 100%
rename from src/pix/beef-goulash.webp
rename to data/pix/beef-goulash.webp
diff --git a/src/pix/bitcoin-based-cooking.webp b/data/pix/bitcoin-based-cooking.webp
similarity index 100%
rename from src/pix/bitcoin-based-cooking.webp
rename to data/pix/bitcoin-based-cooking.webp
diff --git a/src/pix/cacio-e-pepe.webp b/data/pix/cacio-e-pepe.webp
similarity index 100%
rename from src/pix/cacio-e-pepe.webp
rename to data/pix/cacio-e-pepe.webp
diff --git a/src/pix/carbonara.webp b/data/pix/carbonara.webp
similarity index 100%
rename from src/pix/carbonara.webp
rename to data/pix/carbonara.webp
diff --git a/src/pix/cheesy-meatballs.webp b/data/pix/cheesy-meatballs.webp
similarity index 100%
rename from src/pix/cheesy-meatballs.webp
rename to data/pix/cheesy-meatballs.webp
diff --git a/src/pix/country-skillet.webp b/data/pix/country-skillet.webp
similarity index 100%
rename from src/pix/country-skillet.webp
rename to data/pix/country-skillet.webp
diff --git a/src/pix/creamy-mashed-potatoes.webp b/data/pix/creamy-mashed-potatoes.webp
similarity index 100%
rename from src/pix/creamy-mashed-potatoes.webp
rename to data/pix/creamy-mashed-potatoes.webp
diff --git a/src/pix/croutons.webp b/data/pix/croutons.webp
similarity index 100%
rename from src/pix/croutons.webp
rename to data/pix/croutons.webp
diff --git a/src/pix/csalad.webp b/data/pix/csalad.webp
similarity index 100%
rename from src/pix/csalad.webp
rename to data/pix/csalad.webp
diff --git a/src/pix/fried-anglerfish-fillet-00.webp b/data/pix/fried-anglerfish-fillet-00.webp
similarity index 100%
rename from src/pix/fried-anglerfish-fillet-00.webp
rename to data/pix/fried-anglerfish-fillet-00.webp
diff --git a/src/pix/fried-anglerfish-fillet-01.webp b/data/pix/fried-anglerfish-fillet-01.webp
similarity index 100%
rename from src/pix/fried-anglerfish-fillet-01.webp
rename to data/pix/fried-anglerfish-fillet-01.webp
diff --git a/src/pix/guacamole.webp b/data/pix/guacamole.webp
similarity index 100%
rename from src/pix/guacamole.webp
rename to data/pix/guacamole.webp
diff --git a/src/pix/japanese-noodle-soup.webp b/data/pix/japanese-noodle-soup.webp
similarity index 100%
rename from src/pix/japanese-noodle-soup.webp
rename to data/pix/japanese-noodle-soup.webp
diff --git a/src/pix/merchants-buckwheat.webp b/data/pix/merchants-buckwheat.webp
similarity index 100%
rename from src/pix/merchants-buckwheat.webp
rename to data/pix/merchants-buckwheat.webp
diff --git a/src/pix/mortar-and-pestle.webp b/data/pix/mortar-and-pestle.webp
similarity index 100%
rename from src/pix/mortar-and-pestle.webp
rename to data/pix/mortar-and-pestle.webp
diff --git a/src/pix/pan-seared-chicken.webp b/data/pix/pan-seared-chicken.webp
similarity index 100%
rename from src/pix/pan-seared-chicken.webp
rename to data/pix/pan-seared-chicken.webp
diff --git a/src/pix/parmesan-potatoes.webp b/data/pix/parmesan-potatoes.webp
similarity index 100%
rename from src/pix/parmesan-potatoes.webp
rename to data/pix/parmesan-potatoes.webp
diff --git a/src/pix/pasta-navy-style.webp b/data/pix/pasta-navy-style.webp
similarity index 100%
rename from src/pix/pasta-navy-style.webp
rename to data/pix/pasta-navy-style.webp
diff --git a/src/pix/refried-beans.webp b/data/pix/refried-beans.webp
similarity index 100%
rename from src/pix/refried-beans.webp
rename to data/pix/refried-beans.webp
diff --git a/src/pix/sunday-milkshake.webp b/data/pix/sunday-milkshake.webp
similarity index 100%
rename from src/pix/sunday-milkshake.webp
rename to data/pix/sunday-milkshake.webp
diff --git a/src/pix/sweet-potato-fries.webp b/data/pix/sweet-potato-fries.webp
similarity index 100%
rename from src/pix/sweet-potato-fries.webp
rename to data/pix/sweet-potato-fries.webp
diff --git a/src/pix/tuscan-style-pork-roast.webp b/data/pix/tuscan-style-pork-roast.webp
similarity index 100%
rename from src/pix/tuscan-style-pork-roast.webp
rename to data/pix/tuscan-style-pork-roast.webp
diff --git a/src/style.css b/data/style.css
similarity index 79%
rename from src/style.css
rename to data/style.css
index 77a285c..2e6aa32 100644
--- a/src/style.css
+++ b/data/style.css
@@ -20,6 +20,17 @@ img {
display: block ;
}
+code {
+ overflow-wrap: break-word ;
+ color: lime ;
+}
+
+li img {
+ max-width: 1em ;
+ max-height: 1em ;
+ display: inline ;
+}
+
@media (prefers-color-scheme: dark) {
body {
background: #151515 ;
diff --git a/example.md b/example.md
index dfb3d05..a53988f 100644
--- a/example.md
+++ b/example.md
@@ -32,5 +32,11 @@ Here, just put your name and links to yourself (maybe a website or donation link
You may say "Anonymous" or a screenname if desired.
If you add something substantial to an already existing recipe (including and image) you may add your name below with the contribution in parens.
+Note that your commit name will be used to sign the recipe, so for full
+anonymity either commit with a name that can't be traced back to you, or ask
+someone else to commit for you.
+
- Luke Smith - [website](https://lukesmith.xyz), [donate](https://lukesmith.xyz/donate)
- Luke Smith (photo credit) - [website](https://lukesmith.xyz), [donate](https://lukesmith.xyz/donate)
+
+;tags: tag1 tag2 tag3 (see README for tag guidelines)
diff --git a/index.md b/index.md
new file mode 100644
index 0000000..d8a0a59
--- /dev/null
+++ b/index.md
@@ -0,0 +1,12 @@
+## About this site
+
+Founded to provide a simple online cookbook without ads and obese web design.
+
+### It's easy to contribute!
+
+- Submit new recipes via git via [Github](https://github.com/lukesmithxyz/based.cooking) or [Gitlab](https://gitlab.com/lukesmithxyz/based.cooking).
+- If a recipe has no image for it, make the recipe as presented and submit a picture above or to [luke@lukesmith.xyz](mailto:luke@lukesmith.xyz).
+- Donate to the individual people who contribute pages whose names are at the bottom of each page.
+- Donate to the site's long-term maintenance fund:
+ - ![BTC logo](https://lukesmith.xyz/pix/btc.svg) Bitcoin: `bc1q763s4ud0hgfa66ce64gyh6tsss49vyk5cqcm6w` ([QR code](pix/bitcoin-based-cooking.webp))
+ - ![XMR Logo](https://lukesmith.xyz/pix/xmr.svg) Monero: `48jewbtxe4jU3MnzJFjTs3gVFWh2nRrAMWdUuUd7Ubo375LL4SjLTnMRKBrXburvEh38QSNLrJy3EateykVCypnm6gcT9bh` ([QR code](https://lukesmith.xyz/pix/xmr.png))
diff --git a/src/.ssgignore b/src/.ssgignore
deleted file mode 100644
index febf952..0000000
--- a/src/.ssgignore
+++ /dev/null
@@ -1 +0,0 @@
-template.md
diff --git a/src/_footer.html b/src/_footer.html
deleted file mode 100644
index 452246e..0000000
--- a/src/_footer.html
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-