code: def char_ngrams(s, n=3, token_fn=tokens.on_whitespace):
      
      tokens = token_fn(s)
      ngram_tuples = [__ngrams(t, n=min(len(t), n)) for t in tokens]
      def unpack(l):
          return sum(l, [])
      def untuple(l):
          return [''.join(t) for t in l]
      return untuple(unpack(ngram_tuples))
docs: Character-level n-grams from within the words in a string.
  
          By default, the word boundary is assumed to be whitespace.  n-grams are
          not taken across word boundaries, only within words.
  
          If a word's length is less than or equal to n, the n-grams are simply a
          list with the word itself.
  
          >>> ng.char_ngrams('This is not a test!')
          ['Thi', 'his', 'is', 'not', 'a', 'tes', 'est', 'st!']
  
          Therefore some n-grams may have a length less than n, like 'is' and 'a'
          in this example.
  
          Args:
              s: a string
              n: an int for the n in n-gram
              token_fn: a function that splits a string into a list of strings
  
          Returns:
              list: strings of char-level n-grams