This commit is contained in:
2026-04-27 01:30:33 +02:00
parent 9e29b8b096
commit 49e7930541
80 changed files with 924 additions and 703 deletions

116
Makefile
View File

@@ -1,13 +1,16 @@
MAKEFLAGS += -j
MAKEFLAGS += -s
EDITOR ?= vi
FZF != command -v sk || command -v fzy || command -v fzf || \
{ echo install a fuzzy finder && exit 1 ;}
PAGER ?= less -Ri
READER != command -v mdless bat glow less more pg | head -1
FZF != command -v fzf sk | head -1
ifeq "$(FZF)" ""
$(info Install fzf)
endif
ifeq "$(FZF)" "/usr/bin/fzy"
FZF += -i
else
FZF += --print-query | tail -1
endif
spill_contents = sed -e '1,/---/d'
@@ -19,18 +22,9 @@ help: ## Print the help message
articles != find * -type f -name "*.md"
dirs != ls -d */
categories = $(patsubst %/, %, $(dirs))
databases = $(patsubst %, .dbs/%.rec, $(categories))
default += $(databases)
default += db.rec
default += .dbs/notes.rec
default += .dbs/map.fmt
$(foreach dir, $(categories), \
$(eval .dbs/$(dir).rec: $(wildcard $(dir)/*)) \
)
%/:
mkdir $@
@@ -38,34 +32,48 @@ $(foreach dir, $(categories), \
include cmd.mk
$(databases): .dbs/%.rec: %/ | .dbs/
$(info making $(@F))
for entry in $(shell find $< -type f -name "*.md") ; do \
printf "path: %s\n" "$$entry" ;\
sed -n '2,/^---$$/ {/^---$$/d; p}' "$$entry" |\
while read -r line; do if [ -z "$${line#*:}" ] ; then type="$$line"; else echo "$$line" | sed -r "s/- (.*)/$$type \1/" | sed s'/tags: /tag: /' ; fi ; done ;\
printf "wordcount: %s\n\n" "$$(wc -w < $$entry)" ;\
done > $@
# This two-variable read can only happen because of the quotes in the titles.
db.rec: $(databases)
$(info rebuilding from $? )
.dbs/head.rec: | .dbs/ $(lists)
printf '%s\n' '%rec: guide' > $@
printf '%s\n' '%key: title' >> $@
printf '%s\n' '%key: path' >> $@
printf '%s\n' '%type: requires rec guide' >> $@
printf '%s\n' '%type: provides rec guide' >> $@
printf '%s\n' '%type: wordcount int' >> $@
printf '%s\n\n' '%sort: wordcount' >> $@
cat $^ >> $@
recsel $@ -e "requires != ''" -CR title,requires |\
while read title requires; do \
for provider in "$$requires" ; do \
recset --verbose $@ -e "title = '$${provider}'" -f provides -a "$${title}" ;\
done ;\
done
sed -i 's/"//g' $@
recfix --sort $@
$(info Created main database: $@)
.dbs/new.rec: $(wildcard */*.md */*/*.md) | .dbs/head.rec
$(info Updating: $?)
grep -q guide $@ 2>/dev/null || cp $| $@
@-$(foreach entry, $?, \
recdel -t guide $@ -e "path = '$(entry)'" 2>/dev/null ;\
)
for entry in $? ; do \
echo '' ;\
printf "path: %s\n" "$$entry" ;\
sed -n '2,/^---$$/ {/^---$$/d; p}' "$$entry" |\
while read -r line; do if [ -z "$${line#*:}" ] ; then type="$$line"; else echo "$$line" | sed -r "s/- (.*)/$$type \1/" | sed s'/tags: /tag: /' ; fi ; done ;\
printf "wordcount: %s\n" "$$(wc -w < $$entry)" ;\
echo 'cmd: ' ;\
sed '1,/^---$$/d' $$entry | sed 's/^.*/+ &/' ;\
echo '' ;\
done >> $@
.dbs/requires.rec: .dbs/new.rec
recinf -d $< > $@
echo "" >> $@
recsel $< -t guide -j requires -G requires -p 'path,title,tag,wordcount,requires_path:requires,requires_requires:requires,cmd' >> $@
.dbs/notes.rec: .dbs/requires.rec .dbs/new.rec
recinf -d $< > $@
echo '' >> $@
sed '/^%/d' $^ | recsel -G path | recsel -U >> $@
default += db.rec
db.rec: command.rec .dbs/notes.rec
recinf -d $< > $@
echo '' >> $@
sed '/^%/d' $^ | recsel -U -p 'title:aim,aim,cmd,note,shell,tag,bin:tag' >> $@
$(info Making main database: $@)
.git/info/exclude: $(default)
@echo $^ | tr ' ' '\n' > $@
@@ -76,38 +84,40 @@ default += .git/info/exclude
database: $(default) ## Make a recfiles database
.dbs/map.fmt:| .dbs/
printf '%s\n' '[ {{requires[0]}} ] --> [ {{title}} ] {border-style: dashed;}' > $@
printf '%s\n' '[ {{requires[1]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[2]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[3]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[4]}} ] --> [ {{title}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[0]}} ] --> [ {{path}} ] {border-style: dashed;}' > $@
printf '%s\n' '[ {{requires[1]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[2]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[3]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
printf '%s\n' '[ {{requires[4]}} ] --> [ {{path}} ] {border-style: dashed;}' >> $@
.PHONY: map
map: db.rec .dbs/map.fmt ## Show knowledge dependency map
recsel -t guide $< -e 'requires != ""' -p title,requires | recfmt -f .dbs/map.fmt |\
grep -vF '[ ]' | graph-easy --boxart | $${PAGER}
map: .dbs/requires.rec .dbs/map.fmt ## Show knowledge dependency map
recsel -t guide $< -e 'requires != ""' -p path,requires | recfmt -f .dbs/map.fmt |\
grep -vF '[ ]' | graph-easy --boxart 2>/dev/null | ${PAGER} -S
.PHONY: clean
clean: ## Remove all generated files
$(RM) $(default)
$(RM) -r $(default) .dbs/
.PHONY: article
article: **/ **/**/ ## Write a new article
category=$(shell echo $^ | tr ' ' '\n' | $(FZF) ) \
article: */ */*/ ## Write a new article
category=$(shell echo $^ | tr ' ' '\n' | $(FZF) --print-query | tail -1 ) \
&& read -p "Article title? " name \
&& filename="$$(echo "$$name" \
| cut -d: -f1 \
| tr -cd '[:alpha:]' | tr '[A-Z ]' '[a-z_]' )" \
| tr '[A-Z ]' '[a-z_]' | tr -cd '[:alpha:]_' )" \
&& $(MAKE) -e TITLE="$$name" "$$category"/"$$filename.md"
.PHONY: all
all: $(default) ## All file targets
%.md:
[ -d "$(@D)" ] || mkdir $(@D)
printf '%s\n' '---' >> $@
printf 'title: %s\n' '$(TITLE)' >> $@
echo "tags: " >> $@
echo $(@D) | sed 's#\/#\n- #g' >> $@
printf "tags: " >> $@
echo $(@D) | sed 's#\b\w#\n- &#g; s/\///g' >> $@
printf '%s\n\n' '---' >> $@
$(EDITOR) +5 $@
git add $@
git commit -m"article: $(TITLE)"