package com.noticeditorteam.noticeditor.controller; import com.noticeditorteam.noticeditor.io.IOUtil; import java.io.*; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; /** * @author aNNiMON */ public class SyntaxHighlighter { private static final File DIRECTORY = new File(System.getProperty("user.home"), ".noticeditor"); private static final Pattern PATTERN_CODE = Pattern.compile("<code class=\"(\\w+)\">"); public void unpackHighlightJs() { if (DIRECTORY.exists()) return; DIRECTORY.mkdir(); new Thread(unpackHighlightJs).start(); } public String highlight(String content) { return highlight(content, null); } /** * Adds html header with css and highlight.js library. * * @param content the html content * @param codeCssName css style name for code highlight * @return full html page */ public String highlight(String content, String codeCssName) { final Set<String> languages = getUsedLanguages(content); if (languages == null || languages.isEmpty()) return content; final String path = "file://" + DIRECTORY.toURI().getPath(); final String lang = path + "languages/"; if (codeCssName == null) { codeCssName = "vs.css"; } final StringBuilder sb = new StringBuilder(); sb.append("<html>\n<head>\n"); sb.append("<link type=\"text/css\" href=\"").append(path) .append("styles/").append(codeCssName).append("\" rel=\"stylesheet\" />\n"); sb.append("<script src=\"").append(path).append("highlight.js\"></script>\n"); for (String language : languages) { sb.append("<script src=\"").append(lang).append(language).append(".js\"></script>\n"); } sb.append("<script>hljs.initHighlightingOnLoad();</script>\n"); sb.append("</head>\n<body>\n"); sb.append(content); sb.append("</body>\n</html>"); return sb.toString(); } private Set<String> getUsedLanguages(String content) { Matcher matcher = PATTERN_CODE.matcher(content); if (!matcher.find()) return null; Set<String> languages = new HashSet<>(); do { languages.add(matcher.group(1).toLowerCase()); } while (matcher.find()); return languages; } private final Runnable unpackHighlightJs = new Runnable() { @Override public void run() { final File zipFile = new File(DIRECTORY, "highlightjs.zip"); try { copyZipTo(zipFile); extractZip(zipFile); } catch (IOException | ZipException ex) { } finally { zipFile.delete(); } } private void copyZipTo(File destFile) throws IOException { try (InputStream is = getClass().getResourceAsStream("/resources/highlightjs.zip"); OutputStream os = new FileOutputStream(destFile)) { IOUtil.copy(is, os); os.flush(); } } private void extractZip(File zipFile) throws ZipException { ZipFile zip = new ZipFile(zipFile); zip.extractAll(DIRECTORY.getAbsolutePath()); } }; }