code: def word_ngrams_indices(s, n):
      """Splits a string into pairs of (ngram words, their start/end indices)"""
      tokens_with_indices = split_indices(s)
  
      # Generator of ngrams of (word, idx_pairs)
      # (
      #   [(word, (start,end)), (word, (start, end))...],
      #   [(word, (start, end)), ...],
      #   ...
      # )
      ngram_seqs_with_indices = form_ngrams(tokens_with_indices, n)
  
      # Generator of pairs of word and index ngrams
      # (
      #   ([word, word, ...], [(start,end), (start,end), ...]),
      #   ...
      # )
      ngram_indices_pairs = (
          zip(*ngram_with_indices)
          for ngram_with_indices in ngram_seqs_with_indices
      )
  
      # Generator of ( (word_ngram, (start, end)), (word_ngram, start, end)), ...)
      return (
          (" ".join(ngram_seq), (indices[0][0], indices[-1][1]))
          for ngram_seq, indices in ngram_indices_pairs
      )
  
imports: import re
  import string
  import timeit
  import pickle
  import traceback
  from pprint import pprint
label_desc: Use image node_id 4 for calling a global function with example usage: word_ngrams_indices(s, n) and returns: unknown