import std.file, std.string; enum { WEBPUB_MENU = 1, WEBPUB_ITEM } class WebPubMenu { int m_type; char[] m_title; char[] m_url; WebPubMenu[] m_menuItems; WebPubMenu m_parent; this() {} this(char[] title, int type) { m_title = title.dup; m_type = type; } void add(char[] title, char[] url) { WebPubMenu mi = new WebPubMenu(title, WEBPUB_ITEM); mi.m_url = url.dup; m_menuItems ~= mi; } void add(WebPubMenu mi) { m_menuItems ~= mi; } } void printMenu(WebPubMenu menu, int idx=0) { foreach (WebPubMenu m; menu.m_menuItems) { printf("%.*s%.*s:", "".rjustify(idx*4), m.m_title); if (m.m_type == WEBPUB_MENU) { printf("\n"); printMenu(m, idx + 1); } else { printf(" %.*s\n", m.m_url); } } } int main(char[][] args) { char[] inputFileName = null, outputFileName = null; byte verbose = 0; for (int idx=1; idx < args.length; idx++) { if (args[idx] == "-v") { verbose = 1; } else if (inputFileName == null) { inputFileName = args[idx]; } else if (outputFileName == null) { outputFileName = args[idx]; } } if (inputFileName == null || outputFileName == null) { printf("webpub [-v] input output\n"); return -1; } char[] input = cast(char[])std.file.read(inputFileName); byte inBlockComment = 0; int lineNo = 0; WebPubMenu root = new WebPubMenu(); WebPubMenu curr = root; foreach (char[] line; input.splitlines()) { lineNo += 1; line = line.chomp().strip(); if (line.length == 0) { continue; } else if (inBlockComment && line.find("*/") != -1) { inBlockComment = 0; continue; } else if (inBlockComment == 1) { continue; } else if (line.find("/*") == 0) { inBlockComment = 1; continue; } else if (line.find("#") == 0) { continue; } else { if (line.find("{") != -1) { WebPubMenu n = new WebPubMenu(line.chomp("{").strip(), WEBPUB_MENU); n.m_parent = curr; curr.add(n); curr = n; } else if (line.find("}") == 0) { curr = curr.m_parent; } else if (line.find("=>") != -1) { char[][] items = line.split("=>"); curr.add(items[0].strip(), items[1].strip()); } else { printf("WARNING: parse error at line %i '%.*s'\n", lineNo, line); printf(" line ignored, continuing parsing.\n"); } } } printMenu(root); return 0; } /** Example input file: # Jeremy's Home Page Home => home.html About => about.html Computing { Programming { D => d.html C++ => cpp.html Io => io.html Python => python.html } OSes { Linux => linux.html NetBSD => netbsd.html /* Windoze => 404.html BeOS => beos.html V2OS => v2os.html */ } } Family => family.html */