static List _collateLines()

in lib/src/highlighter.dart [128:185]


  static List<_Line> _collateLines(List<_Highlight> highlights) {
    // Assign spans without URLs opaque Objects as keys. Each such Object will
    // be different, but they can then be used later on to determine which lines
    // came from the same span even if they'd all otherwise have `null` URLs.
    final highlightsByUrl = groupBy<_Highlight, Object>(
        highlights, (highlight) => highlight.span.sourceUrl ?? Object());
    for (var list in highlightsByUrl.values) {
      list.sort((highlight1, highlight2) =>
          highlight1.span.compareTo(highlight2.span));
    }

    return highlightsByUrl.entries.expand((entry) {
      final url = entry.key;
      final highlightsForFile = entry.value;

      // First, create a list of all the lines in the current file that we have
      // context for along with their line numbers.
      final lines = <_Line>[];
      for (var highlight in highlightsForFile) {
        final context = highlight.span.context;
        // If [highlight.span.context] contains lines prior to the one
        // [highlight.span.text] appears on, write those first.
        final lineStart = findLineStart(
            context, highlight.span.text, highlight.span.start.column)!;

        final linesBeforeSpan =
            '\n'.allMatches(context.substring(0, lineStart)).length;

        var lineNumber = highlight.span.start.line - linesBeforeSpan;
        for (var line in context.split('\n')) {
          // Only add a line if it hasn't already been added for a previous span.
          if (lines.isEmpty || lineNumber > lines.last.number) {
            lines.add(_Line(line, lineNumber, url));
          }
          lineNumber++;
        }
      }

      // Next, associate each line with each highlights that covers it.
      final activeHighlights = <_Highlight>[];
      var highlightIndex = 0;
      for (var line in lines) {
        activeHighlights
            .removeWhere((highlight) => highlight.span.end.line < line.number);

        final oldHighlightLength = activeHighlights.length;
        for (var highlight in highlightsForFile.skip(highlightIndex)) {
          if (highlight.span.start.line > line.number) break;
          activeHighlights.add(highlight);
        }
        highlightIndex += activeHighlights.length - oldHighlightLength;

        line.highlights.addAll(activeHighlights);
      }

      return lines;
    }).toList();
  }