summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorringabout <43030857+ringabout@users.noreply.github.com>2023-01-24 20:35:19 +0800
committerGitHub <noreply@github.com>2023-01-24 13:35:19 +0100
commit5e7f7109e19b33bc142aa7b06e9044420232a578 (patch)
tree8c6b7895fe2142649bb49c92cd51d0af64f72b1d
parent36e489e69b08ac6a34dfd5c22abc3873c7d86838 (diff)
downloadNim-5e7f7109e19b33bc142aa7b06e9044420232a578.tar.gz
fixes #21290; deindent if the last same level is a text node (#21293)
* fixes #21290; deindent if the last same level is a text node

* add one more test
-rw-r--r--lib/pure/xmltree.nim37
-rw-r--r--tests/stdlib/txmltree.nim18
2 files changed, 38 insertions, 17 deletions
diff --git a/lib/pure/xmltree.nim b/lib/pure/xmltree.nim
index 7a2cebe87..c3923ca50 100644
--- a/lib/pure/xmltree.nim
+++ b/lib/pure/xmltree.nim
@@ -723,20 +723,8 @@ proc addIndent(result: var string, indent: int, addNewLines: bool) =
   for i in 1 .. indent:
     result.add(' ')
 
-proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2,
-          addNewLines = true) =
-  ## Adds the textual representation of `n` to string `result`.
-  runnableExamples:
-    var
-      a = newElement("firstTag")
-      b = newText("my text")
-      c = newComment("my comment")
-      s = ""
-    s.add(c)
-    s.add(a)
-    s.add(b)
-    assert s == "<!-- my comment --><firstTag />my text"
-
+proc addImpl(result: var string, n: XmlNode, indent = 0, indWidth = 2,
+          addNewLines = true, lastNodeIsText = false) =
   proc noWhitespace(n: XmlNode): bool =
     for i in 0 ..< n.len:
       if n[i].kind in {xnText, xnEntity}: return true
@@ -756,7 +744,7 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2,
 
   case n.k
   of xnElement:
-    if indent > 0:
+    if indent > 0 and not lastNodeIsText:
       result.addIndent(indent, addNewLines)
 
     let
@@ -785,8 +773,10 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2,
                    else:
                      indent+indWidth
     result.add('>')
+    var lastNodeIsText = false
     for i in 0 ..< n.len:
-      result.add(n[i], indentNext, indWidth, addNewLines)
+      result.addImpl(n[i], indentNext, indWidth, addNewLines, lastNodeIsText)
+      lastNodeIsText = n[i].kind == xnText
 
     if not n.noWhitespace():
       result.addIndent(indent, addNewLines)
@@ -811,6 +801,21 @@ proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2,
     result.add(n.fText)
     result.add(';')
 
+proc add*(result: var string, n: XmlNode, indent = 0, indWidth = 2,
+          addNewLines = true) {.inline.} =
+  ## Adds the textual representation of `n` to string `result`.
+  runnableExamples:
+    var
+      a = newElement("firstTag")
+      b = newText("my text")
+      c = newComment("my comment")
+      s = ""
+    s.add(c)
+    s.add(a)
+    s.add(b)
+    assert s == "<!-- my comment --><firstTag />my text"
+  result.addImpl(n, indent, indWidth, addNewLines)
+
 proc `$`*(n: XmlNode): string =
   ## Converts `n` into its string representation.
   ##
diff --git a/tests/stdlib/txmltree.nim b/tests/stdlib/txmltree.nim
index f6b7c62e8..4362f5ec3 100644
--- a/tests/stdlib/txmltree.nim
+++ b/tests/stdlib/txmltree.nim
@@ -1,4 +1,4 @@
-import std/[xmltree, assertions]
+import std/[xmltree, assertions, xmlparser]
 
 
 block:
@@ -83,3 +83,19 @@ block:
   x.add newElement("sonTag")
   x.add newEntity("my entity")
   doAssert $x == "<myTag>my text<sonTag />&my entity;</myTag>"
+
+block: # bug #21290
+  let x = newXmlTree("foo",[
+    newXmlTree("bar",[
+      newText("Hola"),
+      newXmlTree("qux",[
+        newXmlTree("plugh",[])
+      ])
+    ])
+  ])
+
+  let s = $x
+  doAssert $parseXml(s) == s
+  doAssert s == """<foo>
+  <bar>Hola<qux>    <plugh />  </qux></bar>
+</foo>"""