docs: def _subspan(self, s, span, nextspan):
          """Recursively subdivide spans based on a series of rules."""
          text = s[span[0]:span[1]]
          lowertext = text.lower()
  
          # Skip if only a single character or a split sequence
          if span[1] - span[0] < 2 or text in self.SPLIT or text in self.SPLIT_END_WORD or text in self.SPLIT_START_WORD or lowertext in self.NO_SPLIT:
              return [span]
  
          # Skip if it looks like URL
          if text.startswith('http://') or text.startswith('ftp://') or text.startswith('www.'):
              return [span]
  
          # Split full stop at end of final token (allow certain characters to follow) unless ellipsis
          if self.split_last_stop and nextspan is None and text not in self.NO_SPLIT_STOP and not text[-3:] == '...':
              if text[-1] == '.':
                  return self._split_span(span, -1)
              ind = text.rfind('.')
              if ind > -1 and all(t in '\'‘’"“”)]}' for t in text[ind + 1:]):
                  return self._split_span(span, ind, 1)
  
          # Split off certain sequences at the end of a word
          for spl in self.SPLIT_END_WORD:
              if text.endswith(spl) and len(text) > len(spl) and text[-len(spl) - 1].isalpha():
                  return self._split_span(span, -len(spl), 0)
  
          # Split off certain sequences at the start of a word
          for spl in self.SPLIT_START_WORD:
              if text.startswith(spl) and len(text) > len(spl) and text[-len(spl) - 1].isalpha():
                  return self._split_span(span, len(spl), 0)
  
          # Split around certain sequences
          for spl in self.SPLIT:
              ind = text.find(spl)
              if ind > -1:
                  return self._split_span(span, ind, len(spl))
  
          # Split around certain sequences unless followed by a digit
          for spl in self.SPLIT_NO_DIGIT:
              ind = text.rfind(spl)
              if ind > -1 and (len(text) <= ind + len(spl) or not text[ind + len(spl)].isdigit()):
                  return self._split_span(span, ind, len(spl))
  
          # Characters to split around, but with exceptions
          for i, char in enumerate(text):
              if char == '-':
                  before = lowertext[:i]
                  after = lowertext[i+1:]
                  # By default we split on hyphens
                  split = True
                  if before in self.NO_SPLIT_PREFIX or after in self.NO_SPLIT_SUFFIX:
                      split = False  # Don't split if prefix or suffix in list
                  elif not before.strip(self.NO_SPLIT_CHARS) or not after.strip(self.NO_SPLIT_CHARS):
                      split = False  # Don't split if prefix or suffix entirely consist of certain characters
                  if split:
                      return self._split_span(span, i, 1)
  
          # Split contraction words
          for contraction in self.CONTRACTIONS:
              if lowertext == contraction[0]:
                  return self._split_span(span, contraction[1])
          return [span]