-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
moved ANSI highlighter feature from Box2Tex to util::Highlighter. Thi…
…s commit also refactors toHTML and toLaTeX for readability and speed and removes some dead code
- Loading branch information
1 parent
a1ed555
commit 4ec236f
Showing
1 changed file
with
128 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,156 @@ | ||
|
||
@license{ | ||
Copyright (c) 2013-2024 CWI | ||
All rights reserved. This program and the accompanying materials | ||
are made available under the terms of the Eclipse Public License v1.0 | ||
which accompanies this distribution, and is available at | ||
http://www.eclipse.org/legal/epl-v10.html | ||
} | ||
@contributor{[email protected]} | ||
@contributor{[email protected]} | ||
@synopsis{Maps parse trees to highlighting markup in ANSI, HTML or LaTeX format.} | ||
module util::Highlight | ||
|
||
import ParseTree; | ||
import String; | ||
import IO; | ||
|
||
@synopsis{Yields the characters of a parse tree as the original input sentence in a <code>...</code> block, but with spans for highlighted segments in HTML} | ||
public str ToHTML(Tree t) { | ||
htmlEscapes = ( | ||
"\<": "<", | ||
"\>": ">", | ||
"&" : "&" | ||
); | ||
|
||
str rec(t:appl(prod(lit(str l), _, _), _)) | ||
= span("Keyword", l) when isKeyword(l); | ||
|
||
str rec(t:appl(prod(cilit(str l), _, _), _)) | ||
= span("Keyword", l) when isKeyword(l); | ||
|
||
str rec(t:appl(prod(_, _, {*_, \tag("category"(str cat))}), list[Tree] as)) | ||
= span(cat, "<for (a <- as) {><rec(a)><}>"); | ||
|
||
default str rec(appl(_, list[Tree] as)) | ||
= "<for (a <- as) {><rec(a)><}>"; | ||
|
||
str rec(amb({k, *_})) = rec(k); | ||
|
||
default str rec(Tree t:char(_)) = escape("<t>", htmlEscapes); | ||
|
||
str span(str class, str src) = "\<span class=\"<class>\"\><src>\</span\>"; | ||
|
||
return "\<pre class=\"rascal\"\>\<code\><trim(rec(t))>\</code\>\</pre\>"; | ||
} | ||
|
||
@synopsis{Yields the characters of a parse tree as the original input sentence but using macros to wrap to-be-highlighted areas.} | ||
public str toLaTeX(Tree t) { | ||
texEscapes = ( | ||
"\\": "\\textbackslash{}", | ||
"\<": "\\textless{}", | ||
"\>": "\\textgreater{}", | ||
"%": "\\%{}", | ||
"&" : "\\&{}", | ||
"_" : "\\_{}", | ||
"^" : "\\^{}", | ||
"{" : "\\{{}", | ||
"}" : "\\}{}", | ||
"$" : "\\${}", | ||
"[" : "{}[", | ||
"\t" : " " | ||
); | ||
|
||
str rec(appl(prod(lit(str l), _, _), _)) = cat("Keyword", l) | ||
when isKeyword(l); | ||
|
||
str rec(appl(prod(cilit(str l), _, _), _)) = cat("Keyword", l) | ||
when isKeyword(l); | ||
|
||
str rec(appl(prod(_, _, {*_, \tag("category"(str category))}), list[Tree] as)) | ||
= cat(category, "<for (a <- as) {><rec(a)><}>"); | ||
|
||
// A comment | ||
default str rec(appl(_, list[Tree] as)) | ||
= "<for (a <- as) {><rec(a)><}>"; | ||
|
||
str rec(amb({k, *_})) = rec(k); | ||
|
||
public map[str, str] htmlEscapes = ( | ||
"\<": "<", | ||
"\>": ">", | ||
"&" : "&" | ||
); | ||
default str rec(Tree t:char(_)) = escape("<t>", texEscapes); | ||
|
||
str cat(str class, str src) = "\\CAT{<class>}{<src>}"; | ||
|
||
str highlight2html(Tree t) | ||
= "\<pre class=\"rascal\"\>\<code\><trim(highlight2htmlRec(t))>\</code\>\</pre\>"; | ||
return rec(t); | ||
} | ||
|
||
bool isKeyword(str s) = /^[a-zA-Z0-9_\-]*$/ := s; | ||
@synopsis{Yields the characters of a parse tree as the original input sentence in a <code>...</code> block, but with spans for highlighted segments in HTML} | ||
public str toHTML(Tree t) { | ||
htmlEscapes = ( | ||
"\<": "<", | ||
"\>": ">", | ||
"&" : "&" | ||
); | ||
|
||
str highlight2htmlRec(t:appl(prod(lit(str l), _, _), _)) | ||
= wrapLink(span("Keyword", l), t) | ||
when isKeyword(l); | ||
str rec(t:appl(prod(lit(str l), _, _), _)) | ||
= wrapLink(span("Keyword", l), t) | ||
when isKeyword(l); | ||
|
||
str highlight2htmlRec(t:appl(prod(cilit(str l), _, _), _)) | ||
= wrapLink(span("Keyword", l), t) | ||
when isKeyword(l); | ||
str rec(t:appl(prod(cilit(str l), _, _), _)) | ||
= wrapLink(span("Keyword", l), t) | ||
when isKeyword(l); | ||
|
||
str highlight2htmlRec(t:appl(prod(_, _, {*_, \tag("category"(str cat))}), list[Tree] as)) | ||
= wrapLink(span(cat, ( "" | it + highlight2htmlRec(a) | a <- as )), t); | ||
str rec(t:appl(prod(_, _, {*_, \tag("category"(str cat))}), list[Tree] as)) | ||
= wrapLink(span(cat, ( "" | it + rec(a) | a <- as )), t); | ||
|
||
str highlight2htmlRec(appl(prod(_, _, set[Attr] attrs), list[Tree] as)) | ||
= ( "" | it + highlight2htmlRec(a) | a <- as ) | ||
when {*_, \tag("category"(str _))} !:= attrs; | ||
str rec(appl(prod(_, _, set[Attr] attrs), list[Tree] as)) | ||
= ( "" | it + rec(a) | a <- as ) | ||
when {*_, \tag("category"(str _))} !:= attrs; | ||
|
||
str highlight2htmlRec(appl(regular(_), list[Tree] as)) | ||
= ( "" | it + highlight2htmlRec(a) | a <- as ); | ||
str rec(appl(regular(_), list[Tree] as)) | ||
= ( "" | it + rec(a) | a <- as ); | ||
|
||
str highlight2htmlRec(amb({k, *_})) = highlight2htmlRec(k); | ||
str rec(amb({k, *_})) = rec(k); | ||
|
||
default str highlight2htmlRec(Tree t) | ||
= wrapLink(escape(unparse(t), htmlEscapes), t); | ||
default str rec(Tree t) | ||
= wrapLink(escape(unparse(t), htmlEscapes), t); | ||
|
||
str span(str class, str src) = "\<span class=\"<class>\"\><src>\</span\>"; | ||
str span(str class, str src) = "\<span class=\"<class>\"\><src>\</span\>"; | ||
|
||
default str wrapLink(str text, Tree _) = text; | ||
default str wrapLink(str text, Tree _) = text; | ||
|
||
// Latex | ||
return "\<pre class=\"rascal\"\>\<code\><trim(rec(t))>\</code\>\</pre\>"; | ||
} | ||
|
||
public map[str, str] texEscapes = ( | ||
"\\": "\\textbackslash{}", | ||
"\<": "\\textless{}", | ||
"\>": "\\textgreater{}", | ||
"%": "\\%{}", | ||
"&" : "\\&{}", | ||
"_" : "\\_{}", | ||
"^" : "\\^{}", | ||
"{" : "\\{{}", | ||
"}" : "\\}{}", | ||
"$" : "\\${}", | ||
"[" : "{}[", | ||
"\t" : " " | ||
); | ||
@synopsis{Unparse a parse tree to unicode characters, wrapping certain substrings with ANSI codes for highlighting.} | ||
public str toANSI(Tree t, bool underlineAmbiguity=false, int tabSize=4) { | ||
str rec(Tree x:appl(prod(lit(str l), _, _), _)) = isKeyword(l) ? bold("<x>") : "<x>"; | ||
str rec(Tree x:appl(prod(cilit(str l), _, _), _)) = isKeyword(l) ? bold("<x>") : "<x>"; | ||
|
||
str highlight2latex(appl(prod(lit(str l), _, _), _)) = catCmd("Keyword", l) | ||
when isKeyword(l); | ||
str rec(Tree x:appl(prod(_, _, {*_, \tag("category"(str cat))}), list[Tree] as)) | ||
= \map(cat, "<x>"); | ||
|
||
str highlight2latex(appl(prod(cilit(str l), _, _), _)) = catCmd("Keyword", l) | ||
when isKeyword(l); | ||
default str rec(x:appl(_, list[Tree] as)) | ||
= "<for (a <- as) {><rec(a)><}>"; | ||
|
||
str highlight2latex(appl(prod(_, _, {*_, \tag("category"(str cat))}), list[Tree] as)) | ||
= catCmd(cat, ( "" | it + highlight2latex(a) | a <- as )); | ||
str rec(amb({k, *_})) = underlineAmbiguity ? underline(rec(k)) : rec(k); | ||
|
||
str highlight2latex(appl(prod(_, _, set[Attr] attrs), list[Tree] as)) | ||
= ( "" | it + highlight2latex(a) | a <- as ) | ||
when {*_, \tag("category"(str _))} !:= attrs; | ||
str rec (char(9)) = right("", tabSize); | ||
default str rec(Tree t:char(_)) = "<t>"; | ||
|
||
str highlight2latex(appl(regular(_), list[Tree] as)) | ||
= ( "" | it + highlight2latex(a) | a <- as ); | ||
str ESC = "\a1b["; | ||
str Bold = "<ESC>1m"; | ||
str Underline = "<ESC>4m"; | ||
str Normal = "<ESC>0m"; | ||
str Comment = "<ESC>3m<ESC>2m"; | ||
str bold(str s) = "<Bold><s><Normal>"; | ||
str underline(str s) = "<Underline><s><Normal>"; | ||
str comment(str s) = "<Comment><s><Normal>"; | ||
|
||
str highlight2latex(amb({k, *_})) = highlight2latex(k); | ||
str \map("Comment", text) = comment(text); | ||
str \map("Keyword", text) = bold(text); | ||
default str \map(str _, str text) = text; | ||
|
||
default str highlight2latex(Tree t) = escape(unparse(t), texEscapes); | ||
return rec(t); | ||
} | ||
|
||
str catCmd(str class, str src) = "\\CAT{<class>}{<src>}"; | ||
@synopsis{Encodes when to highlight a literal as a keyword category} | ||
private bool isKeyword(str s) = /^[a-zA-Z0-9_\-]*$/ := s; |