anchor.diff:    @override
     bool _shallBreakBefore(String tag) => _isBlockTag(tag);
   }
  +
  +/// Translates a parsed AST to plain text.
  +/// 
  +/// When using [TextRenderrer], it is better not to use [UnorderedListSyntax]
  +/// or [OrderedListSyntax].
  +///
  +/// In fact, you can use just [EmptyBlockSyntax] and [ParagraphSyntax].
  +class TextRenderer extends HtmlRenderer {
  +  @override
  +  bool get _trimLeft => false; //preserve the spaces
  +  @override
  +  void _writeOpenTagStart(Element element) {
  +    if (_lastVisitedTag == 'p') buffer.writeln();
  +  }
  +  @override
  +  void _writeOpenTagEnd(Element element) {
  +  }
  +  @override
  +  void _writeCloseTag(Element element) {
  +  }
  +}
  
positive.code:     } else if (element.tag == 'blockquote') {
        buffer.writeln();
      }
      buffer.write('</${element.tag}>');
  
      _lastVisitedTag = _elementStack.removeLast().tag;
    }
  
negative.code:       buffer.writeln();
      }
  
      _writeOpenTagStart(element);
      _lastVisitedTag = element.tag;
  
      if (element.isEmpty) {
        // Empty element like <hr/>.
        _writeOpenTagEnd(element);
        return false;
      } else {
        _elementStack.add(element);
        _writeOpenTagEnd(element);
        return true;
      }
    }
  
    /// Whether to trim left if it is contained in `p` or `li`
    bool get _trimLeft => true;
  
    void _writeOpenTagStart(Element element) {
      buffer.write('<${element.tag}');
  
      for (var entry in element.attributes.entries) {
  