Skip to content

Commit 2813138

Browse files
committed
Moved pretty-printing logic to the node itself so custom node implementations always get printed.
1 parent 02aea78 commit 2813138

File tree

7 files changed

+92
-125
lines changed

7 files changed

+92
-125
lines changed

src/Cubist.Helium/Comment.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ public override void WriteTo(TextWriter w)
3131
WriteCommentEnd(w);
3232
}
3333

34-
/// <inheritdoc cref="Node.WriteTo"/>
35-
public void WriteTo(IndentWriter w)
34+
/// <inheritdoc cref="Node.PrettyPrintTo"/>>
35+
public override void PrettyPrintTo(IndentWriter w)
3636
{
3737
WriteCommentStart(w);
3838
if (string.IsNullOrEmpty(Text))

src/Cubist.Helium/Css.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public override void WriteTo(TextWriter w)
2828
w.Write("} ");
2929
}
3030

31-
/// <inheritdoc cref="Node.WriteTo"/>
32-
public void WriteTo(IndentWriter w)
31+
/// <inheritdoc cref="Node.PrettyPrintTo"/>>
32+
public override void PrettyPrintTo(IndentWriter w)
3333
{
3434
w.Write(Selector);
3535
w.Write(@" {");

src/Cubist.Helium/He.cs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public He Attr(params (string name, object? value)[] attrs)
6262
{
6363
foreach (var (name, value) in attrs)
6464
Attr(name, value);
65-
65+
6666
return this;
6767
}
6868

@@ -109,6 +109,34 @@ public override void WriteTo(TextWriter w)
109109
Tag.WriteClose(w);
110110
}
111111

112+
/// <inheritdoc cref="Node.PrettyPrintTo"/>>
113+
public override void PrettyPrintTo(IndentWriter w)
114+
{
115+
var indent = !this.IsInline();
116+
117+
this.WriteStartTag(w);
118+
119+
var allChildrenInline = this.All(n => n.IsInline());
120+
using (w.Indent())
121+
{
122+
if (indent && !allChildrenInline)
123+
w.WriteLine();
124+
125+
foreach (var child in this)
126+
child.PrettyPrintTo(w);
127+
128+
if (indent && !allChildrenInline && this.Count > 0 && this.Last().IsInline())
129+
w.WriteLine();
130+
}
131+
132+
133+
if (!Tag.IsVoid())
134+
this.WriteCloseTag(w);
135+
136+
if (indent)
137+
w.WriteLine();
138+
}
139+
112140
/// <inheritdoc cref="IEnumerable{T}.GetEnumerator"/>
113141
public IEnumerator<Node> GetEnumerator()
114142
{
@@ -154,8 +182,8 @@ private He AddRange(IEnumerable content)
154182
}
155183

156184
private He AddOther(object content) =>
157-
content.GetType().IsPrimitive
158-
? Add(content.ToString()!)
185+
content.GetType().IsPrimitive
186+
? Add(content.ToString()!)
159187
: Add(new CData($"{content}"));
160188

161189
/// <summary> Adds the content to this element </summary>

src/Cubist.Helium/HtmlDocument.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,44 @@ public override void WriteTo(TextWriter w)
4141
DocType.WriteTo(w);
4242
Html.WriteTo(w);
4343
}
44+
45+
/// <inheritdoc cref="Node.PrettyPrintTo"/>>
46+
public override void PrettyPrintTo(IndentWriter w)
47+
{
48+
DocType.PrettyPrintTo(w);
49+
Html.WriteStartTag(w);
50+
51+
w.WriteLine();
52+
Head.WriteStartTag(w);
53+
w.WriteLine();
54+
55+
using (w.Indent())
56+
{
57+
foreach (var child in Head)
58+
{
59+
child.PrettyPrintTo(w);
60+
if (child is He e && e.Tag.IsVoid())
61+
w.WriteLine();
62+
}
63+
}
64+
65+
Head.WriteCloseTag(w);
66+
w.WriteLine();
67+
68+
Body.WriteStartTag(w);
69+
w.WriteLine();
70+
71+
using (w.Indent())
72+
{
73+
foreach (var child in Body)
74+
{
75+
child.PrettyPrintTo(w);
76+
}
77+
}
78+
79+
Body.WriteCloseTag(w);
80+
w.WriteLine();
81+
82+
Html.WriteCloseTag(w);
83+
}
4484
}

src/Cubist.Helium/Json.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@ public override void WriteTo(TextWriter w)
2929
var json = JsonSerializer.Serialize(Value, Options);
3030
w.Write(json);
3131
}
32+
33+
/// <inheritdoc cref="Node.PrettyPrintTo"/>>
34+
public override void PrettyPrintTo(IndentWriter w)
35+
{
36+
var options = new JsonSerializerOptions(Options) { WriteIndented = true };
37+
var str = JsonSerializer.Serialize(Value, options);
38+
w.WriteLine(str);
39+
}
3240
}

src/Cubist.Helium/Node.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace Cubist.Helium;
44

55
/// <summary> the element tree base class </summary>
6-
public abstract class Node
6+
public abstract class Node
77
{
88
/// <summary> Attach user data to this node, You can use this field to find nodes in the element tree </summary>
99
public object? UserData { get; init; } = null;
@@ -18,4 +18,7 @@ public override string ToString()
1818
WriteTo(sw);
1919
return sw.ToString();
2020
}
21+
22+
/// <summary> Writes this node indented to the output </summary>
23+
public virtual void PrettyPrintTo(IndentWriter w) => WriteTo(w);
2124
}

src/Cubist.Helium/PrettyPrintExtensions.cs

Lines changed: 5 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,21 @@
11
using System.Buffers;
2-
using System.Text.Json;
32

43
namespace Cubist.Helium;
54

65
/// <summary> Extension methods to write formatted and indented html. </summary>
76
public static class PrettyPrintExtensions
87
{
9-
private record PrettyPrintContext(bool Indent);
10-
118
/// <summary> pretty-prints this node to a string </summary>
129
public static string PrettyPrint(this Node n)
1310
{
14-
var sw = new StringWriter();
15-
var indent = new IndentWriter(sw);
16-
PrettyPrintNode(n, indent);
11+
using var sw = new StringWriter();
12+
using var iw = new IndentWriter(sw);
13+
n.PrettyPrintTo(iw);
1714
return sw.ToString();
1815
}
1916

20-
/// <summary> pretty-prints this node to the indent writer </summary>
21-
public static void PrettyPrintTo(this Node n, IndentWriter w)
22-
=> PrettyPrintNode(n, w);
23-
24-
private static void PrettyPrintNode(Node n, IndentWriter w)
25-
{
26-
switch (n)
27-
{
28-
case He he:
29-
PrettyPrintElement(he, w);
30-
break;
31-
case Text text:
32-
text.WriteTo(w);
33-
break;
34-
case Json json:
35-
PrettyPrintJson(json, w);
36-
break;
37-
case CData cdata:
38-
cdata.WriteTo(w);
39-
break;
40-
case Comment comment:
41-
comment.WriteTo(w);
42-
break;
43-
case Css css:
44-
css.WriteTo(w);
45-
break;
46-
case HtmlDocument doc:
47-
PrettyPrintDocument(doc, w);
48-
break;
49-
}
50-
}
51-
52-
private static void PrettyPrintJson(Json json, IndentWriter w)
53-
{
54-
var options = new JsonSerializerOptions(json.Options) { WriteIndented = true };
55-
var str = JsonSerializer.Serialize(json.Value, options);
56-
w.WriteLine(str);
57-
}
58-
59-
60-
private static bool IsInline(this Node n)
17+
/// <summary> Returns true if this is an inline node, with only inline child nodes </summary>
18+
public static bool IsInline(this Node n)
6119
=> n is CData ||
6220
(n is Text t && !t.Value.Contains('\n')) ||
6321
(n is He he && he.Tag.IsInline() &&
@@ -102,76 +60,6 @@ public static bool SplitNewline(this ReadOnlySpan<char> s, out ReadOnlySpan<char
10260
return false;
10361
}
10462

105-
private static void PrettyPrintElement(He he, IndentWriter w)
106-
{
107-
var indent = !he.IsInline();
108-
109-
he.WriteStartTag(w);
110-
111-
var allChildrenInline = he.All(n => n.IsInline());
112-
using (w.Indent())
113-
{
114-
if (indent && !allChildrenInline)
115-
w.WriteLine();
116-
117-
foreach (var child in he)
118-
PrettyPrintNode(child, w);
119-
120-
if (indent && !allChildrenInline && he.Count > 0 && he.Last().IsInline())
121-
w.WriteLine();
122-
}
123-
124-
125-
if (!he.Tag.IsVoid())
126-
{
127-
he.WriteCloseTag(w);
128-
129-
}
130-
if (indent)
131-
w.WriteLine();
132-
133-
}
134-
135-
private static void PrettyPrintDocument(HtmlDocument doc, IndentWriter w)
136-
{
137-
doc.DocType.WriteTo(w);
138-
w.WriteLine();
139-
doc.Html.WriteStartTag(w);
140-
141-
w.WriteLine();
142-
doc.Head.WriteStartTag(w);
143-
w.WriteLine();
144-
145-
using (w.Indent())
146-
{
147-
foreach (var child in doc.Head)
148-
{
149-
PrettyPrintNode(child, w);
150-
if (child is He e && e.Tag.IsVoid())
151-
w.WriteLine();
152-
}
153-
}
154-
155-
doc.Head.WriteCloseTag(w);
156-
w.WriteLine();
157-
158-
doc.Body.WriteStartTag(w);
159-
w.WriteLine();
160-
161-
using (w.Indent())
162-
{
163-
foreach (var child in doc.Body)
164-
{
165-
PrettyPrintNode(child, w);
166-
}
167-
}
168-
169-
doc.Body.WriteCloseTag(w);
170-
w.WriteLine();
171-
172-
doc.Html.WriteCloseTag(w);
173-
}
174-
17563
private static readonly ArrayPool<char> _indents = ArrayPool<char>.Create();
17664

17765
/// <summary> Writes the indent whitespace for the given <paramref name="level"/> </summary>

0 commit comments

Comments
 (0)