1 module feature.parser; 2 import std.stdio; 3 import std.array; 4 public class Parser{ 5 public Node parse(string source){ 6 Node root = new Node(); 7 root.name = "root"; 8 string val = ""; 9 string name = ""; 10 Node curnode = new Node(); 11 Node ParentNode = root; 12 uint mode = 0; // 0 - collect name, 1 - collect value 13 uint deep = 0; 14 char lastchar; 15 uint lastdeep = 0; 16 foreach(chr; source){ 17 lastchar = chr; 18 if(chr == '\t') 19 { 20 deep++; 21 continue; 22 } 23 if(chr == ' '){ 24 if(mode == 0){ 25 mode = 1; 26 continue; 27 } 28 } 29 if(lastchar == '\t' && chr != '\t'){ 30 if(this.nottag(name)){ 31 curnode.name = "raw_text_"; 32 val = name ~ ' ' ~ val; 33 } 34 else 35 curnode.name = name; 36 37 curnode.value = val; 38 mode = 0; 39 ParentNode.children ~= [curnode]; 40 ParentNode = curnode; 41 curnode = new Node(); 42 name = ""; 43 val = ""; 44 if(lastdeep > deep){ 45 curnode = getParent(ParentNode, lastdeep - deep); 46 } 47 lastdeep = deep; 48 deep = 0; 49 } 50 if(chr == '\r' || chr == '\n'){ 51 continue; 52 } 53 if(mode == 0) 54 name ~= chr; 55 if(mode == 1) 56 val ~= chr; 57 } 58 return root; 59 } 60 private Node getParent(Node node, uint deep){ 61 Node parent = node; 62 for(uint i = 0; i < deep; i++){ 63 parent = getParent(parent); 64 } 65 return parent; 66 } 67 private Node getParent(Node node){ 68 return node.parent; 69 } 70 private bool nottag(string tag){ 71 switch(tag) 72 { 73 case "html": 74 case "head": 75 case "body": 76 case "title": 77 case "p": 78 return false; 79 default: 80 return true; 81 } 82 } 83 } 84 public class HtmlGenerator{ 85 private string html; 86 public string Generate(Node root){ 87 this.html = ""; 88 visit(root, 0); 89 return this.html; 90 } 91 private void visit(Node node, uint deep){ 92 if(node.name != "raw_text_") 93 this.html ~= '<' ~ node.name ~ GetAttr(node) ~ '>'; 94 else 95 this.html ~= node.value; 96 foreach(n; node.children){ 97 visit(n, deep + 1); 98 } 99 if(node.name != "raw_text_") 100 this.html ~= "</" ~ node.name ~ '>'; 101 } 102 private string GetAttr(Node node){ 103 string attr = ""; 104 foreach(at; node.attr.byPair){ 105 attr ~= " " ~ at.key ~ "=\"" ~ at.value ~ "\" "; 106 } 107 return attr; 108 } 109 } 110 public class Node{ 111 Node parent; 112 Node[] children; 113 string value; 114 string name; 115 string[string] attr; 116 this(Node parent = null, Node[] children = new Node[0], string value = "", string name = ""){ 117 this.parent = parent; 118 this.children = children; 119 this.value = value; 120 this.name = name; 121 } 122 }