docs: def hash_codeblocks(text, hashes):
      """Hashes codeblocks (<pre> elements).
  
      Codeblocks are strictly defined to be (non-list) lines that are
      indented at least 4 spaces from the newline. Exactly 4 spaces will
      be stripped from the beginning of the line -- any leading
      whitespace after that is preserved.
  
      Codeblock lines that are separated only by blank lines will be
      included in the same codeblock (as will the intermediate newlines).
  
      Certain HTML entities (&, <, >, ", ') will always be escaped inside
      code blocks.
  
      Markdown defines code blocks to be <pre><code>, not just <pre>.
      Certain highlighting packages (like highlight.js) are designed
      to accomodate (and even look) for this type of conversion.
      """
      def sub(match):
          block = match.group(1).rstrip('\n')
          block = re.sub(r'(?:(?<=\n)|(?<=\A)) {4}', '', block)
          block = escape(block)
          block = '<pre><code>{}</code></pre>'.format(block)
          hashed = hash_text(block, 'pre')
          hashes[hashed] = block
          return '\n\n' + hashed + '\n\n'
      return re_codeblock.sub(sub, text)