1 // Copyright Brian Schott (Hackerpilot) 2012. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 module dscanner.highlighter; 7 8 import std.stdio; 9 import std.array; 10 import dparse.lexer; 11 12 // http://ethanschoonover.com/solarized 13 void highlight(R)(ref R tokens, string fileName) 14 { 15 stdout.writeln(q"[ 16 <!DOCTYPE html> 17 <html> 18 <head> 19 <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>]"); 20 stdout.writeln("<title>", fileName, "</title>"); 21 stdout.writeln(q"[</head> 22 <body> 23 <style type="text/css"> 24 html { background-color: #fdf6e3; color: #002b36; } 25 .kwrd { color: #b58900; font-weight: bold; } 26 .com { color: #93a1a1; font-style: italic; } 27 .num { color: #dc322f; font-weight: bold; } 28 .str { color: #2aa198; font-style: italic; } 29 .op { color: #586e75; font-weight: bold; } 30 .type { color: #268bd2; font-weight: bold; } 31 .cons { color: #859900; font-weight: bold; } 32 </style> 33 <pre>]"); 34 35 while (!tokens.empty) 36 { 37 auto t = tokens.front; 38 tokens.popFront(); 39 if (isBasicType(t.type)) 40 writeSpan("type", str(t.type)); 41 else if (isKeyword(t.type)) 42 writeSpan("kwrd", str(t.type)); 43 else if (t.type == tok!"comment") 44 writeSpan("com", t.text); 45 else if (isStringLiteral(t.type) || t.type == tok!"characterLiteral") 46 writeSpan("str", t.text); 47 else if (isNumberLiteral(t.type)) 48 writeSpan("num", t.text); 49 else if (isOperator(t.type)) 50 writeSpan("op", str(t.type)); 51 else if (t.type == tok!"specialTokenSequence" || t.type == tok!"scriptLine") 52 writeSpan("cons", t.text.replace("<", "<")); 53 else 54 { 55 version (Windows) 56 { 57 // Stupid Windows automatically does a LF → CRLF, so 58 // CRLF → CRCRLF, which is obviously wrong. 59 // Strip out the CR characters here to avoid this. 60 stdout.write(t.text.replace("<", "<").replace("\r", "")); 61 } 62 else 63 stdout.write(t.text.replace("<", "<")); 64 } 65 66 } 67 stdout.writeln("</pre>\n</body></html>"); 68 } 69 70 void writeSpan(string cssClass, string value) 71 { 72 version (Windows) 73 stdout.write(`<span class="`, cssClass, `">`, value.replace("&", 74 "&").replace("<", "<").replace("\r", ""), `</span>`); 75 else 76 stdout.write(`<span class="`, cssClass, `">`, value.replace("&", 77 "&").replace("<", "<"), `</span>`); 78 }