could this be refactored so there's less duplicated logic between `_html_chars` and `_html_words`, please?