code: def slugify(s):
      
      slug = s.lower()  # force to lower case
      slug = re.sub('[^a-z0-9 -]', '', slug)  # remove invalid chars
      slug = re.sub(r'\s+', '-', slug)  # collapse whitespace and replace by -
      slug = re.sub('-+', '-', slug)  # collapse dashes
      if not slug:
          slug = 'untitled'
      return slug
docs: Convert any string to a "slug", a simplified form suitable for filename and URL part.
       EXAMPLE: "Trees about bees" => 'trees-about-bees'
       EXAMPLE: "My favorites!" => 'my-favorites'
      N.B. that its behavior should match this client-side slugify function, so
      we can accurately "preview" slugs in the browser:
       https://github.com/OpenTreeOfLife/opentree/blob/553546942388d78545cc8dcc4f84db78a2dd79ac/curator/static/js/curation-helpers.js#L391-L397
      TODO: Should we also trim leading and trailing spaces (or dashes in the final slug)?