code: def truncate_html_words(s, num, end_text="…"):
      """Truncates HTML to a certain number of words.
  
      (not counting tags and comments). Closes opened tags if they were correctly
      closed in the given html. Takes an optional argument of what should be used
      to notify that the string has been truncated, defaulting to ellipsis (…).
  
      Newlines in the HTML are preserved. (From the django framework).
      """
      length = int(num)
      if length <= 0:
          return ""
      truncator = _HTMLWordTruncator(length)
      truncator.feed(s)
      if truncator.truncate_at is None:
          return s
      out = s[: truncator.truncate_at]
      if end_text:
          out += " " + end_text
      # Close any tags still open
      for tag in truncator.open_tags:
          out += "</%s>" % tag
      # Return string
      return out
  
imports: import datetime
  import fnmatch
  import locale
  import logging
  import os
  import pathlib
  import re
  import shutil
  import sys
  import traceback
  import urllib
  from collections.abc import Hashable
  from contextlib import contextmanager
  from functools import partial
  from html import entities
  from html.parser import HTMLParser
  from itertools import groupby
  from operator import attrgetter
  import dateutil.parser
  from markupsafe import Markup
  import watchfiles
label_desc: Use image node_id 13 for calling a global function with example usage: truncate_html_words(s, num, end_text) and returns: out, str, s