Skip to content

Commit 25e29e8

Browse files
committed
Add prototype
1 parent 92bf25e commit 25e29e8

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

util/Highlighter.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// Highlighter.java, no comments, no checks.
2+
// $ javac Highlighter.java
3+
// $ jar -cvfe highlighter.jar Highlighter *.class
4+
// $ cat hello.py | java -jar highlighter.jar rouge python
5+
import org.graalvm.polyglot.Context;
6+
7+
import java.io.File;
8+
import java.io.FileNotFoundException;
9+
10+
import java.util.Scanner;
11+
12+
public class Highlighter {
13+
private abstract class Highlight {
14+
protected final Context polyglot =
15+
Context.newBuilder("js", "python", "ruby").allowAllAccess(true).allowIO(true)
16+
.build();
17+
18+
protected abstract String language();
19+
protected abstract String renderHtml(String language, String rawCode);
20+
21+
protected String execute(String sourceCode) {
22+
try {
23+
return polyglot.eval(language(), sourceCode).asString();
24+
} catch (RuntimeException re) { re.printStackTrace(); }
25+
return sourceCode;
26+
}
27+
28+
protected void importValue(String name, String value) {
29+
try {
30+
polyglot.getBindings(language()).putMember(name, value);
31+
} catch (RuntimeException re) { re.printStackTrace(); }
32+
}
33+
}
34+
35+
private class Hjs extends Highlight {
36+
@Override
37+
protected String language() { return "js"; }
38+
39+
@Override
40+
public String renderHtml(String language, String rawCode) {
41+
importValue("source", rawCode);
42+
43+
String hjs = "";
44+
try {
45+
hjs = new Scanner(new File("highlight.min.js")).useDelimiter("\\A").next();
46+
} catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); }
47+
48+
final String renderLanguageSnippet =
49+
hjs + "\n" +
50+
"hljs.highlight('" + language + "', String(source)).value";
51+
return execute(renderLanguageSnippet);
52+
}
53+
}
54+
55+
private class Rouge extends Highlight {
56+
@Override
57+
protected String language() { return "ruby"; }
58+
59+
@Override
60+
public String renderHtml(String language, String rawCode) {
61+
importValue("$source", rawCode);
62+
final String renderLanguageSnippet =
63+
"require 'rouge'" + "\n" +
64+
65+
"formatter = Rouge::Formatters::HTML.new" + "\n" +
66+
"lexer = Rouge::Lexer::find('" + language + "')" + "\n" +
67+
"formatter.format(lexer.lex($source.to_str))";
68+
return execute(renderLanguageSnippet);
69+
}
70+
}
71+
72+
private class Pygments extends Highlight {
73+
@Override
74+
protected String language() { return "python"; }
75+
76+
@Override
77+
public String renderHtml(String language, String rawCode) {
78+
importValue("source", rawCode);
79+
final String renderLanguageSnippet =
80+
"import site" + "\n" +
81+
"from pygments import highlight" + "\n" +
82+
"from pygments.lexers import get_lexer_by_name" + "\n" +
83+
"from pygments.formatters import HtmlFormatter" + "\n" +
84+
85+
"formatter = HtmlFormatter(nowrap=True)" + "\n" +
86+
"lexer = get_lexer_by_name('" + language + "')" + "\n" +
87+
"highlight(source, lexer, formatter)";
88+
return execute(renderLanguageSnippet);
89+
}
90+
}
91+
92+
public String highlight(String library, String language, String code) {
93+
switch (library) {
94+
default:
95+
case "hjs": return new Hjs().renderHtml(language, code);
96+
case "rouge": return new Rouge().renderHtml(language, code);
97+
case "pygments": return new Pygments().renderHtml(language, code);
98+
}
99+
}
100+
101+
public static void main(String[] args) {
102+
Scanner scanner = new Scanner(System.in).useDelimiter("\\A");
103+
if (scanner.hasNext()) {
104+
String code = scanner.next();
105+
if (!code.isEmpty()) {
106+
System.out.println(new Highlighter().highlight(args[0], args[1], code));
107+
}
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)