Reputation: 61
I have a folder for notes called md
which can have nested folders inside. I have written a python script to convert a markdown file into a html file and fix links etc. It can be invoked by running the command python3 md2html <markdown_file> <output
*file>
. I also made a python script which basically does a tree traversal on the md
directory, and invokes this md2html
program on each markdown file in this directory (ignoring other filetypes), and builds a corresponding html directory like so.
.
|-- html
| |-- mydir
| | |-- one.html
| |-- apps.html
| |-- c_assignment.html
| |-- ewd35.html
|-- md
| |-- Makefile
| |-- mydir
| | |-- lorem.html
| | |-- lorem.ms
| | |-- lorem.ps
| | `-- one.md
| |-- apps.md
| |-- c_assignment.md
| |-- ewd35.md
| |-- ewd35.pdf
I recently learned about Makefile, and to my understanding I can make it so that the md2html
program is only run on md
files that have been modified since the last time their corresponding html
file was created. I am struggling to understand how I can write a Makefile to replicate the structure of the md
directory, as it is fixed. I searched and I saw that recursive Makefiles are not a good idea so I am asking here. Thank you.
Upvotes: 0
Views: 110
Reputation: 100856
To begin, you don't specify which variant of make
you are using. You'll need GNU Make to be able to do this. Standard POSIX make
cannot do it.
First, you need to find all the .md
files. You can either list them explicitly, which means you'll need to update your makefile when you create (or delete) .md
files:
MD_FILES := ./mydir/one.md ./apps.md ./c_assignment.md ./ewd35.md
Or, you can have make find them itself. If you don't want to assume anything about the data structure you can have it invoke find
to do it for you:
MD_FILES := $(shell find . -name \*.md)
Next you convert those pathnames to be the ones you want to create:
HTML_ROOT := ../html
HTML_FILES := $(patsubst ./%.md,$(HTML_ROOT)/%.html,$(MD_FILES))
Now you write a target that depends on the HTML files that need to be created:
all: $(HTML_FILES)
.PHONY: all
(you can use any target you want, it doesn't have to be all
... just make sure it comes as the first explicit target in the makefile).
Finally, write a pattern rule that tells make how to build one .html
file from one .md
file:
$(HTML_ROOT)/%.html : %.md
mkdir -p $(@D)
python3 md2html $< $@
See the GNU Make manual to understand what these special variables mean.
And you're done! GNU Make will figure out which .html
files are outdated and run the recipe here for each one.
Upvotes: 1