Use a string scanner to parse the templates

This should be easier to work with and more secure than the current `gsub` based method.