【发布时间】:2019-08-04 13:03:15
【问题描述】:
我正在尝试使用 make 作为静态站点生成器(类似于 Jekyll)。源代码位于文件夹中,并运行 make 以将输出生成到单独的目录“build”中。
源码结构如下:
src
├── about.md
├── css
│ └── style.css
├── index.md
└─── posts
├── 2019-07-30-a-blog-post.md
├── 2019-07-08-another-post.md
└── 2019-08-01-something-else.md
我正在尝试得到这样的输出:
build
├── 2019
│ ├── 07
│ │ ├── a-blog-post
│ │ │ └── index.html
│ │ ├── another-post
│ │ │ └── index.html
│ └── 08
│ └── something-else
│ └── index.html
├── about
│ └── index.html
├── css
│ └── style.min.css
└── index.html
这是我当前的 makefile...
define generateHTML
mkdir -p $(dir $1)
pandoc -f markdown -t html5 -o $1 $2 -s
endef
SRC = src
DST = build
MARKDOWNFILES := $(filter-out $(SRC)/index.md, $(wildcard $(SRC)/*.md))
HTMLTARGETS := $(MARKDOWNFILES:src/%.md=build/%/index.html)
BLOG_MARKDOWNFILES := $(wildcard $(SRC)/posts/*.md)
### [WARNING] Hacky section here ###
# Replace '-' with ' ' for all parts of file basename
FINDREPLACE = $(subst -, ,$(basename $(notdir $(mdf))))
# Get the first 3 words of the space-separated list (YYYY MM DD)
# & format as YYYY/MM/DD-
# & replace all '/' characters with '-'
FINDREPLACE1A = $(subst /,-,$(word 1, $(FINDREPLACE))/$(word 2, $(FINDREPLACE))/$(word 3,$(FINDREPLACE)))-
# Replace the full path string, with the above.
# Get the filename, minus 'YYYY-MM-DD-' prefix.
FINDREPLACE1B = $(subst $(FINDREPLACE1A),$e,$(basename $(notdir $(mdf))))
# Build the full string required for HTMLTARGET variable
# & format into 'build/YY/MM/<string>/index.html'
findReplace2 = build/$(word 1, $(FINDREPLACE))/$(word 2, $(FINDREPLACE))/$(FINDREPLACE1B)/index.html
BLOG_HTMLTARGETS := $(foreach mdf, $(BLOG_MARKDOWNFILES),$(findReplace2))
all: build/index.html $(HTMLTARGETS) $(BLOG_HTMLTARGETS)
# This generates the root index.html
build/index.html: src/index.md
$(call generateHTML, $@, $<)
# This generates the about/index.html pages, etc.
build/%/index.html: src/%.md
$(call generateHTML, $@, $<)
### [WARNING] Hacky section here ###
build/%/index.html: $(BLOG_MARKDOWNFILES)
$(eval WORDLIST = $(filter-out build,$(subst /,$e ,$(subst -,$e ,$(@D)))))
$(eval QUERY = $(SRC)/posts/$(word 1,$(WORDLIST))-$(word 2,$(WORDLIST))%$(word $(words $(WORDLIST)),$(WORDLIST)).md)
$(eval FUZZY_FILE = $(filter $(QUERY),$(BLOG_MARKDOWNFILES)))
$(call generateHTML, $@, $(FUZZY_FILE))
# Tidy-up
.PHONY: clean
clean:
rm -Rf $(DST)
我已经设法一起破解了一些东西 - 使用内置函数 subst / word / words / filter 执行查找/替换和匹配 - 这确实成功生成了我想要的输出,但是每次更新一个文件时,它都会重新生成所有个文件,这似乎远非理想。
有没有一种直接的方法来操作 makefile 的目标/依赖字符串,来做这样的事情?
src/posts/YYYY-MM-DD-post.md => build/YYYY/MM/post/index.html
【问题讨论】:
标签: makefile