diff --git a/README.md b/README.md index 047da839..7584fef1 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ * List with checkbox * Add the data-line attribute to indicate which line the checkbox is in the markdown. +* Support the `preserveSpace` option to work with WYSIWYG editors easier. * `TableSyntax` - * `escapeFoward` introduced for skiping pipe characters (`|`) that shall not be considered as a column separator. * `processCellContent` introduced for pre-processing cell's content * Link enhancements: * `LinkMapper` introduced to allow app for mapping to *application-specific* links. diff --git a/lib/src/html_renderer.dart b/lib/src/html_renderer.dart index 3608d82b..a982320c 100644 --- a/lib/src/html_renderer.dart +++ b/lib/src/html_renderer.dart @@ -41,17 +41,23 @@ String markdownToHtml( preserveSpace: preserveSpace, ); - if (inlineOnly) return renderToHtml(document.parseInline(markdown)); + if (inlineOnly) { + return renderToHtml(document.parseInline(markdown), + preserveSpace: preserveSpace); + } final nodes = document.parse(markdown); - return '${renderToHtml(nodes, enableTagfilter: enableTagfilter)}\n'; + return '${renderToHtml(nodes, enableTagfilter: enableTagfilter, + preserveSpace: preserveSpace)}\n'; } /// Renders [nodes] to HTML. -String renderToHtml(List nodes, {bool enableTagfilter = false}) => +String renderToHtml(List nodes, {bool enableTagfilter = false, + bool preserveSpace = false}) => HtmlRenderer( enableTagfilter: enableTagfilter, + preserveSpace: preserveSpace, ).render(nodes); const _blockTags = { @@ -106,10 +112,13 @@ class CondensedHtmlRenderer implements NodeVisitor { final _elementStack = []; String? _lastVisitedTag; final bool _tagfilterEnabled; + final bool _spacePreserved; CondensedHtmlRenderer({ bool enableTagfilter = false, - }) : _tagfilterEnabled = enableTagfilter; + bool preserveSpace = false, + }) : _tagfilterEnabled = enableTagfilter, + _spacePreserved = preserveSpace; String render(List nodes) { buffer = StringBuffer(); @@ -131,7 +140,7 @@ class CondensedHtmlRenderer implements NodeVisitor { } if (const {'br', 'p', 'li'}.contains(_lastVisitedTag)) { final lines = LineSplitter.split(content); - content = !_trimLeft || content.contains('
')
+      content = _spacePreserved || content.contains('
')
           ? lines.join('\n')
           : lines.map((line) => line.trimLeft()).join('\n');
       if (text.textContent.endsWith('\n')) {
@@ -164,9 +173,6 @@ class CondensedHtmlRenderer implements NodeVisitor {
     }
   }
 
-  /// Whether to trim left if it is contained in `p` or `li`
-  bool get _trimLeft => true;
-
   void _writeOpenTagStart(Element element) {
     buffer.write('<${element.tag}');
 
@@ -254,7 +260,7 @@ class CondensedHtmlRenderer implements NodeVisitor {
 
 /// Translates a parsed AST to HTML.
 class HtmlRenderer extends CondensedHtmlRenderer {
-  HtmlRenderer({super.enableTagfilter = false});
+  HtmlRenderer({super.enableTagfilter = false, super.preserveSpace = false});
 
   @override
   bool _isBlockTag(String? tag)
@@ -268,8 +274,8 @@ class HtmlRenderer extends CondensedHtmlRenderer {
 ///
 /// For better, you can use just [EmptyBlockSyntax] and [ParagraphSyntax].
 class TextRenderer extends HtmlRenderer {
-  @override
-  bool get _trimLeft => false; //preserve the spaces
+  TextRenderer(): super(preserveSpace: true);
+
   @override
   void _writeOpenTagStart(Element element) {
     if (_lastVisitedTag == 'p' && buffer.isNotEmpty) buffer.writeln();
diff --git a/test/markdown_test.dart b/test/markdown_test.dart
index a7ddb810..d3a5e662 100644
--- a/test/markdown_test.dart
+++ b/test/markdown_test.dart
@@ -506,6 +506,27 @@ Line 2
 
 

Line 2

+'''); + + validate( + 'Space in front of line', + ''' + Line 1 + +* Item 1 +* Item 2 + + +Line 2 +''', ''' +

Line 1 +

+
    +
  • Item 1
  • +
  • Item 2
  • +
+

+Line 2

'''); });