substitute-all: add recursive directory substitution support