Iterable _getUpdatedCodeBlock()

in packages/code_excerpt_updater/lib/src/code_excerpt_updater.dart [185:269]


  Iterable<String> _getUpdatedCodeBlock(InstrInfo info) {
    final args = info.args;
    final infoPath = info.path;
    final currentCodeBlock = <String>[];
    if (_lines.isEmpty) {
      _reporter.error('reached end of input, expect code block - "$infoPath"');
      return currentCodeBlock;
    }
    var line = _lines.removeAt(0);
    final openingCodeBlockLine = line;
    final firstLineMatch = codeBlockStartMarker.firstMatch(line);
    if (firstLineMatch == null || firstLineMatch[2] == null) {
      _reporter.error('code block should immediately follow <?code-excerpt?> - '
          '"$infoPath"\n  not: $line');
      return <String>[openingCodeBlockLine];
    }

    final newCodeBlockCode = args['diff-with'] == null
        ? _getter.getExcerpt(
            infoPath,
            info.region,
            _excerptCodeTransformer(
                args, _codeLang(openingCodeBlockLine, info.path)),
          )
        : _differ.getDiff(infoPath, info.region, args,
            p.join(_getter.srcDirPath, _getter.pathBase));

    log.finer('>>> new code block code: $newCodeBlockCode');
    if (newCodeBlockCode == null) {
      // Error has been reported. Return while leaving existing code.
      // We could skip ahead to the end of the code block but that
      // will be handled by the outer loop.
      return <String>[openingCodeBlockLine];
    }

    final _codeBlockEndMarker = firstLineMatch[2]?.startsWith('`') == true
        ? codeBlockEndMarker
        : codeBlockEndPrettifyMarker;
    String? closingCodeBlockLine;
    while (_lines.isNotEmpty) {
      line = _lines[0];
      final match = _codeBlockEndMarker.firstMatch(line);
      if (match == null) {
        _reporter.error('unterminated markdown code block '
            'for <?code-excerpt "$infoPath"?>');
        return <String>[openingCodeBlockLine, ...currentCodeBlock];
      } else if (match[2] != null) {
        // We've found the closing code-block marker.
        closingCodeBlockLine = line;
        _lines.removeAt(0);
        break;
      }
      currentCodeBlock.add(line);
      _lines.removeAt(0);
    }
    if (closingCodeBlockLine == null) {
      _reporter.error('unterminated markdown code block '
          'for <?code-excerpt "$infoPath"?>');
      return <String>[openingCodeBlockLine, ...currentCodeBlock];
    }
    _numSrcDirectives++;
    final linePrefix = info.linePrefix;
    final indentBy =
        args['diff-with'] == null ? _getIndentBy(args['indent-by']) : 0;
    final indentation = ' ' * indentBy;
    final prefixedCodeExcerpt = newCodeBlockCode.map((line) {
      final _line =
          '$linePrefix$indentation$line'.replaceFirst(RegExp(r'\s+$'), '');
      return escapeNgInterpolation
          ? _line.replaceAllMapped(
              RegExp(r'({){|(})}'), (m) => '${m[1] ?? m[2]}!${m[1] ?? m[2]}')
          : _line;
    }).toList(growable: false);
    if (!const ListEquality<String>()
        .equals(currentCodeBlock, prefixedCodeExcerpt)) {
      _numUpdatedFrag++;
    }
    final result = <String>[
      openingCodeBlockLine,
      ...prefixedCodeExcerpt,
      closingCodeBlockLine
    ];
    log.finer('>>> result: $result');
    return result;
  }