1 module hunt.markdown.ext.table.internal.TableHtmlNodeRenderer;
2 
3 import hunt.collection.Collections;
4 import hunt.collection.Map;
5 import hunt.collection.HashMap;
6 
7 import hunt.markdown.ext.table.TableBlock;
8 import hunt.markdown.ext.table.TableBody;
9 import hunt.markdown.ext.table.TableCell;
10 import hunt.markdown.ext.table.TableHead;
11 import hunt.markdown.ext.table.TableRow;
12 import hunt.markdown.ext.table.internal.TableNodeRenderer;
13 import hunt.markdown.node.Node;
14 import hunt.markdown.renderer.html.HtmlNodeRendererContext;
15 import hunt.markdown.renderer.html.HtmlWriter;
16 
17 import std.conv : to;
18 
19 class TableHtmlNodeRenderer : TableNodeRenderer {
20 
21     private HtmlWriter htmlWriter;
22     private HtmlNodeRendererContext context;
23 
24     public this(HtmlNodeRendererContext context) {
25         this.htmlWriter = context.getWriter();
26         this.context = context;
27     }
28 
29     override protected void renderBlock(TableBlock tableBlock) {
30         htmlWriter.line();
31         htmlWriter.tag("table", getAttributes(tableBlock, "table"));
32         renderChildren(tableBlock);
33         htmlWriter.tag("/table");
34         htmlWriter.line();
35     }
36 
37     override protected void renderHead(TableHead tableHead) {
38         htmlWriter.line();
39         htmlWriter.tag("thead", getAttributes(tableHead, "thead"));
40         renderChildren(tableHead);
41         htmlWriter.tag("/thead");
42         htmlWriter.line();
43     }
44 
45     override protected void renderBody(TableBody tableBody) {
46         htmlWriter.line();
47         htmlWriter.tag("tbody", getAttributes(tableBody, "tbody"));
48         renderChildren(tableBody);
49         htmlWriter.tag("/tbody");
50         htmlWriter.line();
51     }
52 
53     override protected void renderRow(TableRow tableRow) {
54         htmlWriter.line();
55         htmlWriter.tag("tr", getAttributes(tableRow, "tr"));
56         renderChildren(tableRow);
57         htmlWriter.tag("/tr");
58         htmlWriter.line();
59     }
60 
61     override protected void renderCell(TableCell tableCell) {
62         string tagName = tableCell.isHeader() ? "th" : "td";
63         htmlWriter.tag(tagName, getCellAttributes(tableCell, tagName));
64         renderChildren(tableCell);
65         htmlWriter.tag("/" ~ tagName);
66     }
67 
68     private Map!(string, string) getAttributes(Node node, string tagName) {
69         return context.extendAttributes(node, tagName, Collections.emptyMap!(string, string)());
70     }
71 
72     private Map!(string, string) getCellAttributes(TableCell tableCell, string tagName)
73     {
74         auto attributes = new HashMap!(string, string);
75 
76         if (tableCell.getAlignment() != TableCell.Alignment.NONE) {
77             attributes.put("align", getAlignValue(tableCell.getAlignment()));
78         }
79 
80         return context.extendAttributes(tableCell, tagName, attributes);
81     }
82 
83     private static string getAlignValue(TableCell.Alignment alignment) {
84         switch (alignment) {
85             case TableCell.Alignment.LEFT:
86                 return "left";
87             case TableCell.Alignment.CENTER:
88                 return "center";
89             case TableCell.Alignment.RIGHT:
90                 return "right";
91             default:
92                 return null;
93         }
94     }
95 
96     private void renderChildren(Node parent) {
97         Node node = parent.getFirstChild();
98         while (node !is null) {
99             Node next = node.getNext();
100             context.render(node);
101             node = next;
102         }
103     }
104 }