prettify method

  1. @override
String prettify()
inherited

The method will turn a BeautifulSoup parse tree into a nicely formatted String, with a separate line for each tag and each string.

You can call prettify on the top-level BeautifulSoup object, or on any of its element objects.

Since it adds whitespace (in the form of newlines), prettify changes the meaning of an HTML document and should not be used to reformat one.

The goal of prettify is to help you visually understand the structure of the documents you work with.

Implementation

@override
String prettify() {
  final topElement = findFirstAny()?.clone(true);
  if (topElement == null ||
      topElement.element == null ||
      topElement.nextParsed == null) {
    return _bs4.outerHtml;
  }

  final strBuffer = StringBuffer();
  void indent(int? indentation) {
    for (int i = 0; i < (indentation ?? 1); i++) {
      strBuffer.write(' ');
    }
  }

  final topElementData = _TagDataExtractor.parseElement(topElement.element!);
  final topClosingTag = topElementData.closingTag;
  strBuffer
    ..write(topElementData.startingTag)
    ..write('\n');

  final lists = <_TagDataExtractor>[];
  if (topElement.element!.hasChildNodes()) {
    final children = topElement.element!.nodes;

    var spaces = 1;
    for (final child in children) {
      spaces = 1;
      final current = _TagDataExtractor.parseNode(child, indentation: spaces);
      lists.add(current);

      final descendants = child.nodes
          .map((node) {
            spaces++;
            return _recursiveNodeExtractorSearch(node, indentation: spaces);
          })
          .expand((e) => e)
          .toList();
      lists.addAll(descendants);
    }
  }

  _TagDataExtractor? prevNode;
  for (final item in lists) {
    indent(item.indentation);
    strBuffer
      ..write(item.isElement ? item.startingTag : item.node.data)
      ..write('\n');

    if (prevNode != null && prevNode.isElement && prevNode != item) {
      indent(prevNode.indentation);
      strBuffer
        ..write(prevNode.closingTag)
        ..write('\n');
    }

    prevNode = item;
  }

  strBuffer.write(topClosingTag);
  return strBuffer.toString();
}