aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2020-04-12 17:03:05 +0200
committerKim Alvefur <zash@zash.se>2020-04-12 17:03:05 +0200
commitf0ac29acf0d1d6cd947ac2e20dc6bcbbbddf76f6 (patch)
tree2eea1e91bb889155b5f1efda5c82a5b75c0561d8
parent608d6dd75669b3b8bcc526b91dad865ae89af79a (diff)
downloadprosody-f0ac29acf0d1d6cd947ac2e20dc6bcbbbddf76f6.tar.gz
prosody-f0ac29acf0d1d6cd947ac2e20dc6bcbbbddf76f6.zip
util.stanza: Add method returning stanza with added indentation
Adds indentation and line breaks to stanzas, to make stanzas easier to read for humans.
-rw-r--r--spec/util_stanza_spec.lua8
-rw-r--r--util/stanza.lua30
2 files changed, 38 insertions, 0 deletions
diff --git a/spec/util_stanza_spec.lua b/spec/util_stanza_spec.lua
index d38a609f..efe3e47e 100644
--- a/spec/util_stanza_spec.lua
+++ b/spec/util_stanza_spec.lua
@@ -459,4 +459,12 @@ describe("util.stanza", function()
assert.equal("true", s2.attr["my-awesome-ns\1bar"]);
end);
end);
+
+ describe("indent", function ()
+ local s = st.stanza("foo"):text("\n"):tag("bar"):tag("baz"):up():text_tag("cow", "moo");
+ assert.equal("<foo>\n\t<bar>\n\t\t<baz/>\n\t\t<cow>moo</cow>\n\t</bar>\n</foo>", tostring(s:indent()));
+ assert.equal("<foo>\n <bar>\n <baz/>\n <cow>moo</cow>\n </bar>\n</foo>", tostring(s:indent(1, " ")));
+ assert.equal("<foo>\n\t\t<bar>\n\t\t\t<baz/>\n\t\t\t<cow>moo</cow>\n\t\t</bar>\n\t</foo>", tostring(s:indent(2, "\t")));
+ end);
+
end);
diff --git a/util/stanza.lua b/util/stanza.lua
index f5cd5668..a8a417ab 100644
--- a/util/stanza.lua
+++ b/util/stanza.lua
@@ -511,6 +511,36 @@ else
stanza_mt.pretty_top_tag = stanza_mt.top_tag;
end
+function stanza_mt.indent(t, level, indent)
+ if #t == 0 or (#t == 1 and type(t[1]) == "string") then
+ -- Empty nodes wouldn't have any indentation
+ -- Text-only nodes are preserved as to not alter the text content
+ -- Optimization: Skip clone of these since we don't alter them
+ return t;
+ end
+
+ indent = indent or "\t";
+ level = level or 1;
+ local tag = clone(t, true);
+
+ for child in t:children() do
+ if type(child) == "string" then
+ -- Already indented text would look weird but let's ignore that for now.
+ if child:find("%S") then
+ tag:text("\n" .. indent:rep(level));
+ tag:text(child);
+ end
+ elseif is_stanza(child) then
+ tag:text("\n" .. indent:rep(level));
+ tag:add_direct_child(child:indent(level+1, indent));
+ end
+ end
+ -- before the closing tag
+ tag:text("\n" .. indent:rep((level-1)));
+
+ return tag;
+end
+
return {
stanza_mt = stanza_mt;
stanza = new_stanza;