function subtokenize(eventsArray) {
  /** @type {Record<string, number>} */
  const jumps = {}
  let index = -1
  /** @type {Event} */
  let event
  /** @type {number | undefined} */
  let lineIndex
  /** @type {number} */
  let otherIndex
  /** @type {Event} */
  let otherEvent
  /** @type {Array<Event>} */
  let parameters
  /** @type {Array<Event>} */
  let subevents
  /** @type {boolean | undefined} */
  let more
  const events = new SpliceBuffer(eventsArray)

  while (++index < events.length) {
    while (index in jumps) {
      index = jumps[index]
    }

    event = events.get(index)

    // Add a hook for the GFM tasklist extension, which needs to know if text
    // is in the first content of a list item.
    if (
      index &&
      event[1].type === types.chunkFlow &&
      events.get(index - 1)[1].type === types.listItemPrefix
    ) {
      assert(event[1]._tokenizer, 'expected `_tokenizer` on subtokens')
      subevents = event[1]._tokenizer.events
      otherIndex = 0

      if (
        otherIndex < subevents.length &&
        subevents[otherIndex][1].type === types.lineEndingBlank
      ) {
        otherIndex += 2
      }

      if (
        otherIndex < subevents.length &&
        subevents[otherIndex][1].type === types.content
      ) {
        while (++otherIndex < subevents.length) {
          if (subevents[otherIndex][1].type === types.content) {
            break
          }

          if (subevents[otherIndex][1].type === types.chunkText) {
            subevents[otherIndex][1]._isInFirstContentOfListItem = true
            otherIndex++
          }
        }
      }
    }

    // Enter.
    if (event[0] === 'enter') {
      if (event[1].contentType) {
        Object.assign(jumps, subcontent(events, index))
        index = jumps[index]
        more = true
      }
    }
    // Exit.
    else if (event[1]._container) {
      otherIndex = index
      lineIndex = undefined

      while (otherIndex--) {
        otherEvent = events.get(otherIndex)

        if (
          otherEvent[1].type === types.lineEnding ||
          otherEvent[1].type === types.lineEndingBlank
        ) {
          if (otherEvent[0] === 'enter') {
            if (lineIndex) {
              events.get(lineIndex)[1].type = types.lineEndingBlank
            }

            otherEvent[1].type = types.lineEnding
            lineIndex = otherIndex
          }
        } else if (
          otherEvent[1].type === types.linePrefix ||
          otherEvent[1].type === types.listItemIndent
        ) {
          // Move past.
        } else {
          break
        }
      }

      if (lineIndex) {
        // Fix position.
        event[1].end = {...events.get(lineIndex)[1].start}

        // Switch container exit w/ line endings.
        parameters = events.slice(lineIndex, index)
        parameters.unshift(event)
        events.splice(lineIndex, index - lineIndex + 1, parameters)
      }
    }
  }

  // The changes to the `events` buffer must be copied back into the eventsArray
  splice(eventsArray, 0, Number.POSITIVE_INFINITY, events.slice(0))
  return !more
}
Tokenize subcontent.

@param {Array<Event>} eventsArray
  List of events.
@returns {boolean}
  Whether subtokens were found.