Last active
July 12, 2018 00:25
-
-
Save Col-E/006ee9c807e3ded1881a39109fd16900 to your computer and use it in GitHub Desktop.
Java-2-HTML converter
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
/** | |
* When the window loads, insert collapse buttons. | |
*/ | |
window.onload = function() { | |
// Iterate code blocks: | |
var codeBlocks = document.getElementsByTagName("pre"); | |
for (var i = 0; i < codeBlocks.length; i++) { | |
// Iterate block children to identify the sections. | |
// They should be the only elements with ID's in the <pre> tag. | |
var pre = codeBlocks[i]; | |
var children = pre.getElementsByTagName("*"); | |
for (var c = 0; c < children.length; c++) { | |
var child = children[c]; | |
// ID span found, add collapse to it. | |
if (!isEmpty(child.id)){ | |
addCollapse(pre, child.id); | |
c++; | |
} | |
} | |
} | |
}; | |
/** | |
* containerx: | |
* Element that holds the container marked by the ID | |
* id: | |
* ID of collapseable content. Relative to the container, not the whole document. | |
*/ | |
function addCollapse(containerx, id) { | |
// create buttons that collapse the content of those containers. | |
var container = containerx.querySelector("#" + id); | |
//var parent = container.parentNode; | |
var toggleBtn = document.createElement("div"); | |
toggleBtn.className = "toggle-open"; | |
// click action | |
toggleBtn.onclick = function () { | |
collapse(toggleBtn, container, id); | |
}; | |
// hover to show what will be collapsed | |
toggleBtn.onmouseout = function () { | |
setHighlighted(container, true); | |
setHighlightedDummy(id, true); | |
} | |
toggleBtn.onmouseover = function () { | |
setHighlighted(container, false); | |
setHighlightedDummy(id, false); | |
} | |
containerx.insertBefore(toggleBtn, container); | |
} | |
/** | |
* container: | |
* Container to be marked. | |
* highlighted: | |
* If container should be highlighted, noting collapseable content. | |
*/ | |
function setHighlighted(container, highlighted) { | |
var cls = container.className; | |
if(highlighted) { | |
container.className = container.className.replace("toggle-section", ""); | |
} else { | |
container.className += " toggle-section"; | |
} | |
} | |
/** | |
* id: | |
* ID of dummy content to be marked. | |
* highlighted: | |
* If container should be highlighted, noting collapseable content. | |
*/ | |
function setHighlightedDummy(id, highlighted) { | |
var dcID = "dummy-cont-" + id; | |
var container = document.getElementById(dcID); | |
if (container != null) { | |
setHighlighted(container, highlighted); | |
} | |
} | |
/** | |
* button: | |
* The button that controls the visibility of the container. | |
* container: | |
* Span containing collapsable content. | |
* id: | |
* ID of the container. | |
*/ | |
function collapse(button, container, id) { | |
// toggle button format | |
var btnType = button.className; | |
var dlID = "dummy-line-" + id; | |
var dcID = "dummy-cont-" + id; | |
if(btnType == "toggle-open") { | |
button.className = "toggle-closed"; | |
// replace with dummy line | |
var dLine = document.createElement("span"); | |
var dContent = document.createElement("span"); | |
dLine.id = dlID; | |
dLine.className = "line"; | |
dContent.id = dcID; | |
dContent.className = "comment-line toggle-section"; // selection included since mouse will be over | |
dContent.innerHTML = "// " + id + "... "; | |
container.parentNode.insertBefore(dLine, container); | |
container.parentNode.insertBefore(dContent, container); | |
} else{ | |
button.className = "toggle-open"; | |
// remove dummy items | |
document.getElementById(dlID).outerHTML = ""; | |
document.getElementById(dcID).outerHTML = ""; | |
} | |
// toggle visibility of container | |
if (container.style.display === "none") { | |
container.style.display = "inline"; | |
} else { | |
container.style.display = "none"; | |
} | |
} | |
/** | |
* Check if string is empty. | |
*/ | |
function isEmpty(str) { | |
return (!str || 0 === str.length); | |
} |
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
package me.coley.j2h; | |
import javafx.application.Application; | |
import javafx.scene.Scene; | |
import javafx.scene.control.SplitPane; | |
import javafx.scene.control.TextArea; | |
import javafx.stage.Stage; | |
// https://mvnrepository.com/artifact/org.apache.commons/commons-text | |
import org.apache.commons.text.StringEscapeUtils; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
/** | |
* Basic java to HTML converter using regex | |
* | |
* @author Matt | |
*/ | |
public class Java2Html extends Application { | |
//@formatter:off | |
private static final String[] KEYWORDS = new String[] { "abstract", "assert", "boolean", "break", "byte", "case", "catch", | |
"char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", | |
"float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", | |
"package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", | |
"synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while" }; | |
//@formatter:on | |
private static final String KEYWORD_PATTERN = "\\b(" + String.join("|", KEYWORDS) + ")\\b"; | |
private static final String STRING_PATTERN = "\"([^\"\\\\]|\\\\.)*\""; | |
private static final String CONST_HEX_PATTERN = "(0[xX][0-9a-fA-F]+)+"; | |
private static final String CONST_VAL_PATTERN = "(\\b([\\d._]*[\\d])\\b)+|(true|false|null)"; | |
private static final String CONST_PATTERN = CONST_HEX_PATTERN + "|" + CONST_VAL_PATTERN; | |
private static final String COMMENT_SINGLE_PATTERN = "//[^\n]*"; | |
private static final String COMMENT_MULTI_SINGLE_PATTERN = "/[*](.|\\R)+?\\*/"; | |
private static final String COMMENT_MULTI_JAVADOC_PATTERN = "/[*]{2}(.|\\R)+?\\*/"; | |
private static final String ANNOTATION_PATTERN = "\\B(@[\\w]+)\\b"; | |
//@formatter:off | |
private static final Pattern PATTERN = Pattern.compile( | |
"(?<KEYWORD>" + KEYWORD_PATTERN + ")" + | |
"|(?<STRING>" + STRING_PATTERN + ")" + | |
"|(?<COMMENTDOC>" + COMMENT_MULTI_JAVADOC_PATTERN + ")" + | |
"|(?<COMMENTMULTI>" + COMMENT_MULTI_SINGLE_PATTERN + ")" + | |
"|(?<COMMENTLINE>" + COMMENT_SINGLE_PATTERN + ")" + | |
"|(?<ANNOTATION>" + ANNOTATION_PATTERN + ")" + | |
"|(?<CONSTPATTERN>" + CONST_PATTERN + ")"); | |
//@formatter:on | |
public static void main(String[] args) { | |
launch(args); | |
} | |
@Override | |
public void start(Stage primaryStage) { | |
TextArea input = new TextArea(); | |
TextArea output = new TextArea(); | |
input.textProperty().addListener((observable, oldValue, newValue) -> { | |
update(output, newValue); | |
}); | |
SplitPane pane = new SplitPane(input, output); | |
primaryStage.setScene(new Scene(pane, 900, 800)); | |
primaryStage.setTitle("Java2Html"); | |
primaryStage.show(); | |
} | |
/** | |
* Set the value of the TextArea <i>(output)</i> to the HTML-decorated version of the input <i>(text)</i>. | |
* | |
* @param output | |
* TextArea that will host the output. | |
* @param text | |
* Input text <i>(Java code)</i> | |
*/ | |
private static void update(TextArea output, String text) { | |
text = text.replace("\t", " "); | |
Matcher matcher = PATTERN.matcher(text); | |
StringBuilder sb = new StringBuilder(); | |
int lastEnd = 0; | |
while(matcher.find()) { | |
//@formatter:off | |
String styleClass = | |
matcher.group("STRING") != null ? "string" | |
: matcher.group("KEYWORD") != null ? "keyword" | |
: matcher.group("COMMENTDOC") != null ? "comment-javadoc" | |
: matcher.group("COMMENTMULTI") != null ? "comment-multi" | |
: matcher.group("COMMENTLINE") != null ? "comment-line" | |
: matcher.group("CONSTPATTERN") != null ? "const" | |
: matcher.group("ANNOTATION") != null ? "annotation" : null; | |
//@formatter:on | |
int start = matcher.start(); | |
int end = matcher.end(); | |
// append text not matched | |
if(start > lastEnd) { | |
sb.append(StringEscapeUtils.escapeHtml4(text.substring(lastEnd, start))); | |
} | |
// append match | |
sb.append("<span class=\"" + styleClass + "\">" + StringEscapeUtils.escapeHtml4(text.substring(start, end)) + "</span>"); | |
lastEnd = end; | |
} | |
sb.append(StringEscapeUtils.escapeHtml4(text.substring(lastEnd))); | |
StringBuilder fmt = new StringBuilder(); | |
for(String line : sb.toString().split("\n")) { | |
fmt.append("<span class=\"line\"></span>" + line + "\n"); | |
} | |
output.setText("<pre>" + fmt.toString() + "</pre>"); | |
} | |
} |
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
/* =========================== */ | |
/* Code block */ | |
/* =========================== */ | |
/* HTML auto-gen to match this with: | |
https://gist.github.com/Col-E/006ee9c807e3ded1881a39109fd16900 | |
*/ | |
pre { | |
font-family: monospace; | |
background: rgba(0,0,0,0.04); | |
border: 1px solid rgba(0,0,0,0.3); | |
counter-reset: ln; | |
margin-left: 2px; | |
margin-right: 2px; | |
overflow: auto; | |
} | |
pre * { | |
font-family: monospace; | |
} | |
/* show line numbers */ | |
pre .line { | |
display: inline-block; | |
} | |
pre .line::before { | |
counter-increment: ln; | |
content: counter(ln); | |
display: inline-block; | |
color: black; | |
font-weight: normal; | |
font-style: normal; | |
border-right: 1px solid rgba(200,200,200,1); | |
padding: 0 15; | |
margin: 0 10 0 0; | |
width: 20px; | |
text-align: center; | |
background: rgba(0,0,0,0.035); | |
} | |
/* code style for element types */ | |
pre .keyword { | |
color: rgb(127, 0, 85); | |
font-weight: bold; | |
text-shadow: none; | |
} | |
pre .string { | |
color: rgb(47, 100, 31); | |
font-style: italic; | |
} | |
pre .const { | |
color: rgb(173, 53, 0); | |
} | |
pre .annotation { | |
color: rgb(120, 130, 150); | |
} | |
pre .comment-line, | |
pre .comment-multi { | |
color: rgb(0, 111, 12); | |
font-style: italic; | |
} | |
pre .comment-javadoc { | |
color: rgb(0, 100, 114); | |
font-style: italic; | |
} | |
/* =========================== */ | |
/* Code block section toggle */ | |
/* =========================== */ | |
/* shared button style */ | |
.toggle-open, | |
.toggle-closed { | |
cursor: pointer; | |
position: absolute; | |
display: inline-block; | |
margin-left: -15px; | |
text-align: center; | |
width: 13px; | |
background: rgba(0,0,0,0.2); | |
border: 1px solid rgba(0,0,0,0.3); | |
} | |
/* closed button is more blue */ | |
.toggle-closed { | |
background: rgba(20,20,130,0.4); | |
} | |
/* text (+/-) for open/close button operations */ | |
.toggle-open::before { | |
content: '-'; | |
} | |
.toggle-closed::before { | |
content: '+'; | |
} | |
/* dark on hover */ | |
.toggle-open:hover, | |
.toggle-closed:hover { | |
background: rgba(0,0,0,0.34); | |
} | |
/* highlight for code belonging to a toggle-button */ | |
.toggle-section { | |
background: rgba(0,0,100,0.1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment