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 }