TextDocument: lazily convert substitution mapping to unicode

This way, the substitution mapping method can return a dynamic mapping,
the only requirement is to implement __getitem__
3 jobs for feat/lazy_substitute_content
in 0 seconds, using 0 compute credits, and was queued for 0 seconds