What I am trying to do
I am working on a syntax-highlighter that highlights java-code in html (example below).
Example output
I've tested the code with the following java-code (caesar-encryption):
//Encryption
public static String encrypt(String text, int n) {
int x = 0;
int y = 0;
String out = ""; //Empty string for result.
while (x < text.length()) {
if (text.charAt(x) > 64 && text.charAt(x) < 91) {
if (text.charAt(x) + n > 90) {
y = 26;
}
out = out + (char) (text.charAt(x) + n - y);
} else {
out = out + text.charAt(x);
}
x++;
y = 0;
}
return out;
}
The output looks like this:
<!-- Code begins here -->
<div style = "background: LightGray; font: monospace; width: fit-content; height: min-height;"><pre><code>
<span style='color:green; font-weight:bold; '>//Encryption
</span><span style='color:#7f0055; font-weight:bold; '>public</span> <span style='color:#7f0055; font-weight:bold; '>static</span> <span style='color:#7f0055; font-weight:bold; '>String</span> encrypt(<span style='color:#7f0055; font-weight:bold; '>String</span> text, <span style='color:#7f0055; font-weight:bold; '>int</span> n) {
<span style='color:#7f0055; font-weight:bold; '>int</span> x = 0;
<span style='color:#7f0055; font-weight:bold; '>int</span> y = 0;
<span style='color:#7f0055; font-weight:bold; '>String</span> out = <span style='color:blue; font-weight:bold; '>""</span>; <span style='color:green; font-weight:bold; '>//Empty string <span style='color:#7f0055; font-weight:bold; '>for</span> result.
</span> <span style='color:#7f0055; font-weight:bold; '>while</span> (x < text.length()) {
<span style='color:#7f0055; font-weight:bold; '>if</span> (text.charAt(x) > 64 && text.charAt(x) < 91) {
<span style='color:#7f0055; font-weight:bold; '>if</span> (text.charAt(x) + n > 90) {
y = 26;
}
out = out + (<span style='color:#7f0055; font-weight:bold; '>char</span>) (text.charAt(x) + n - y);
} <span style='color:#7f0055; font-weight:bold; '>else</span> {
out = out + text.charAt(x);
}
x++;
y = 0;
}
<span style='color:#7f0055; font-weight:bold; '>return</span> out;
}
</pre></code></div>
<!-- Code ends here -->
If you open this code with a browser, it looks like this:
The code
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
public class Gui {
private JTextArea inputArea;
private JTextArea outputArea;
private boolean inputAreaClicked = false;
public Gui() {
//JFrame
JFrame frame = new JFrame("Syntax-Highlighter");
frame.setSize(700, 700);
frame.setMinimumSize(new Dimension(700, 700));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JPanel
JPanel panel = new JPanel(new GridBagLayout());
//Creating textArea for input
inputArea = new JTextArea("Enter text here...");
inputArea.setLineWrap(true);
inputArea.setTabSize(1);
inputArea.setFont(new Font("monospaced", Font.ITALIC, 12));
inputArea.addMouseListener(new MouseAdapter() { //Set text to "" the first time the inputArea is clicked
@Override
public void mouseClicked(MouseEvent e){
if(!inputAreaClicked) {
inputArea.setText("");
inputArea.setFont(new Font("monospaced", Font.PLAIN, 12));
inputAreaClicked = true;
}
}
});
JScrollPane input = new JScrollPane(inputArea);
input.setPreferredSize(new Dimension(600, 110));
input.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
input.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
//Creating buttons
JPanel buttonPanel = new JPanel(new FlowLayout(0, 50, 10)); //FlowLayout(align, hgap, vgap)
JButton button = new JButton("Highlight");
button.setFont(new Font("Arial", Font.PLAIN, 20));
button.addActionListener(e -> hightlight(inputArea.getText()));
button.setPreferredSize(new Dimension(140,30));
//Creating textArea for output
outputArea = new JTextArea();
outputArea.setEditable(false);
outputArea.setTabSize(1);
outputArea.setLineWrap(false);
outputArea.setFont(new Font("monospaced", Font.PLAIN, 12));
JScrollPane output = new JScrollPane(outputArea);
output.setPreferredSize(new Dimension(600, 400));
output.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
output.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
//Layout
GridBagConstraints gbc = new GridBagConstraints();
gbc.weighty = 5;
gbc.gridwidth = GridBagConstraints.REMAINDER;
//Add everything to panel
buttonPanel.add(button);
panel.add(input, gbc);
panel.add(buttonPanel, gbc);
panel.add(output, gbc);
//Add everything to frame
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
}
private void hightlight(String text) {
//Keywords
String[] array = {
"abstract", "assert", "boolean", "break", "byte", "case",
"catch", "char", "class", "const", "continue", "default", "do",
"double", "else", "enum", "extends", "false", "final", "finally", "float",
"for", "goto", "if", "implements", "import", "instanceof", "int",
"interface", "long", "native", "new", "null", "package", "private", "protected",
"public", "return", "short", "static", "String", "strictfp", "super", "switch", "synchronized",
"System", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while"
};
//Highlight every keyword with color:#7f0055
for(int i = 0; i < array.length; i++) {
text = text.replaceAll(array[i] + "(?![a-zA-Z])", "<span style='color:#7f0055; font-weight:bold; '>" + array[i] + "</span>");
}
//Highlight Strings
text = text.replaceAll("\"(?<render>.*?)\"", "<span style='color:blue; font-weight:bold; '>" + "\"${render}\"" + "</span>");
//Highlight import-statements
text = text.replaceAll("import(?<render>.*?);", "<span style='color:#7f0055; font-weight:bold; '>" + "import${render};" + "</span>");
//Highlight multiline-comments
Pattern p = Pattern.compile("/\\*(?<render>.*?)\\*/", Pattern.DOTALL);
Matcher m = p.matcher(text);
text = m.replaceAll("<span style='color:green; font-weight:bold; '>" + "/\\*${render}\\*/" + "</span>");
//Highlight single-line-comments
text = text.replaceAll("//(?<render>.*?)\n", "<span style='color:green; font-weight:bold; '>" + "//${render}\n" + "</span>");
text = "<!-- Code begins here -->\n<div style = \"background: LightGray; font: monospace; width: fit-content; height: min-height;\"><pre><code>\n"
+ text + "\n</pre></code></div>\n<!-- Code ends here -->\n";
outputArea.setText(text);
}
}
The problem
As you can see in the picture above, keywords in comments are still highlighted as keywords.
Do you have an idea how this problem can be solved?
What I have tried
I tried to use the following code (replacing in the backreference), but it didn't work:
// Highlight single-line-comments
text = text.replaceAll("//(?<render>.*?)\n", "<span style='color:green; font-weight:bold; '>"
+ "//" + "${render}".replaceAll("color: #7f0055", "color: green") + "\\n</span>");
Unfortunately this isn't working? How can this be corrected?
