From 2979d827559784063b19df93ba346f94cb6a596c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Fri, 10 Nov 2017 18:57:59 +0100 Subject: [PATCH] Allow tokens to receive several css classes --- .../SimpleRegexSyntaxHighlighter.java | 50 +++++++++----- .../syntaxhighlighting/HighlightClasses.java | 68 +++++++++++++++---- .../JavaSyntaxHighlighter.java | 6 +- .../XPathSyntaxHighlighter.java | 12 ++-- .../XmlSyntaxHighlighter.java | 18 +++-- .../pmd/util/fxdesigner/css/editor-theme.css | 43 +++--------- 6 files changed, 120 insertions(+), 77 deletions(-) diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/SimpleRegexSyntaxHighlighter.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/SimpleRegexSyntaxHighlighter.java index 872140e5a5..1e34c0d88c 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/SimpleRegexSyntaxHighlighter.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/SimpleRegexSyntaxHighlighter.java @@ -4,12 +4,13 @@ package net.sourceforge.pmd.util.fxdesigner.util.codearea; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -42,6 +43,8 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter protected SimpleRegexSyntaxHighlighter(String languageName, final RegexHighlightGrammar grammar) { this.grammar = grammar; this.languageName = languageName; + + grammar.addCommonClass(languageName); } @@ -51,12 +54,13 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter Matcher matcher = grammar.getMatcher(text); int lastKwEnd = 0; + final Set onlyLang = Collections.singleton(languageName); try { while (matcher.find()) { - String styleClass = grammar.getCssClassOfLastGroup(matcher); + Set styleClasses = grammar.getCssClassesOfLastGroup(matcher); - builder.add(Collections.singleton(languageName), matcher.start() - lastKwEnd); - builder.add(Arrays.asList(languageName, styleClass), matcher.end() - matcher.start()); + builder.add(onlyLang, matcher.start() - lastKwEnd); + builder.add(styleClasses, matcher.end() - matcher.start()); lastKwEnd = matcher.end(); } @@ -65,7 +69,7 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter } if (lastKwEnd == 0) { // no spans found/ no text - builder.add(Collections.emptySet(), text.length()); + builder.add(onlyLang, text.length()); } return builder.create(); @@ -86,7 +90,7 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter * * @return A builder */ - protected static RegexHighlightGrammarBuilder grammarBuilder(String cssClass, String pattern) { + protected static RegexHighlightGrammarBuilder grammarBuilder(Collection cssClass, String pattern) { return new RegexHighlightGrammarBuilder(cssClass, pattern); } @@ -97,10 +101,10 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter protected static class RegexHighlightGrammarBuilder { private Map groupNameToRegex = new LinkedHashMap<>(); - private Map groupNameToCssClass = new LinkedHashMap<>(); + private Map> groupNameToCssClasses = new LinkedHashMap<>(); - RegexHighlightGrammarBuilder(String cssClass, String regex) { + RegexHighlightGrammarBuilder(Collection cssClass, String regex) { or(cssClass, regex); } @@ -113,10 +117,10 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter * * @return The same builder */ - public RegexHighlightGrammarBuilder or(String cssClass, String regex) { + public RegexHighlightGrammarBuilder or(Collection cssClass, String regex) { String groupName = RandomStringUtils.randomAlphabetic(8); groupNameToRegex.put(groupName, regex); - groupNameToCssClass.put(groupName, cssClass); + groupNameToCssClasses.put(groupName, new HashSet<>(cssClass)); return this; } @@ -158,8 +162,8 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter } - private Map getGroupNamesToCssClasses() { - return Collections.unmodifiableMap(groupNameToCssClass); + private Map> getGroupNamesToCssClasses() { + return Collections.unmodifiableMap(groupNameToCssClasses); } } @@ -170,10 +174,10 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter protected static class RegexHighlightGrammar { private final Pattern pattern; - private final Map namesToCssClass; + private final Map> namesToCssClass; - RegexHighlightGrammar(Pattern pattern, Map namesToCssClass) { + RegexHighlightGrammar(Pattern pattern, Map> namesToCssClass) { this.pattern = pattern; this.namesToCssClass = namesToCssClass; } @@ -189,6 +193,18 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter } + /** + * Adds a css class to all the tokens described by this grammar. + * + * @param css The css class to add + */ + void addCommonClass(String css) { + for (String key : namesToCssClass.keySet()) { + namesToCssClass.get(key).add(css); + } + } + + /** * Gets the css class that should be applied to the last matched group (token), according to this grammar. * @@ -196,14 +212,14 @@ public abstract class SimpleRegexSyntaxHighlighter implements SyntaxHighlighter * * @return The name of the css class corresponding to the token */ - String getCssClassOfLastGroup(Matcher matcher) { - for (Entry groupToClass : namesToCssClass.entrySet()) { + Set getCssClassesOfLastGroup(Matcher matcher) { + for (Entry> groupToClass : namesToCssClass.entrySet()) { if (matcher.group(groupToClass.getKey()) != null) { return groupToClass.getValue(); } } - return ""; + return Collections.emptySet(); } } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/HighlightClasses.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/HighlightClasses.java index cad9d837d6..821a3ef102 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/HighlightClasses.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/HighlightClasses.java @@ -4,29 +4,67 @@ package net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + + /** * @author Clément Fournier * @since 6.0.0 */ public enum HighlightClasses { - MULTIL_COMMENT("multi-line-comment"), - SINGLEL_COMMENT("single-line-comment"), - PAREN("paren"), - BRACE("brace"), - BRACKET("bracket"), - SEMICOLON("semicolon"), - BOOLEAN("boolean"), - STRING("string"), - CHAR("char"), - NULL("null"), - NUMBER("number"), - KEYWORD("keyword"); + + COMMENT(Constants.COMMENT), + MULTIL_COMMENT("multi-line-comment", Constants.COMMENT), + SINGLEL_COMMENT("single-line-comment", Constants.COMMENT), + + PUNCTUATION(Constants.PUNCTUATION), + PAREN("paren", Constants.PUNCTUATION), + BRACE("brace", Constants.PUNCTUATION), + BRACKET("bracket", Constants.PUNCTUATION), + SEMICOLON("semicolon", Constants.PUNCTUATION), + + LITERAL(Constants.LITERAL), + BOOLEAN("boolean", Constants.LITERAL), + STRING("string", Constants.LITERAL), + CHAR("char", Constants.LITERAL), + NULL("null", Constants.LITERAL), + NUMBER("number", Constants.LITERAL), + + KEYWORD("keyword"), + ANNOTATION("annotation"), + CLASS_IDENTIFIER("class-identifier"), + + // XPath specific + XPATH_ATTRIBUTE("attribute", Constants.XPATH), + XPATH_AXIS("axis", Constants.XPATH), + XPATH_FUNCTION("function", Constants.XPATH), + XPATH_PATH("path", Constants.XPATH, Constants.PUNCTUATION), + + XML_CDATA_TAG("cdata-tag", Constants.XML), + XML_CDATA_CONTENT("cdata-content", Constants.XML), + XML_PROLOG("xml-prolog", Constants.XML), + XML_LT_GT("lt-gt", Constants.XML), + XML_TAG_NAME("tag-name", Constants.XML), + XML_ATTRIBUTE_NAME("attribute-name", Constants.XML), + ; + /** Name of the css class. */ - public final String css; + public final List css; - HighlightClasses(String css) { - this.css = css; + HighlightClasses(String... classes) { + this.css = Collections.unmodifiableList(Arrays.asList(classes)); + } + + + private static class Constants { + static final String LITERAL = "literal"; + static final String COMMENT = "comment"; + static final String PUNCTUATION = "punctuation"; + static final String XML = "xml"; + static final String XPATH = "xpath"; } } diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/JavaSyntaxHighlighter.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/JavaSyntaxHighlighter.java index 8c2352cbc2..156d3405a3 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/JavaSyntaxHighlighter.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/JavaSyntaxHighlighter.java @@ -4,10 +4,12 @@ package net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.ANNOTATION; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.BOOLEAN; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.BRACE; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.BRACKET; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.CHAR; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.CLASS_IDENTIFIER; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.KEYWORD; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.MULTIL_COMMENT; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.NULL; @@ -67,8 +69,8 @@ public class JavaSyntaxHighlighter extends SimpleRegexSyntaxHighlighter { .or(CHAR.css, "'(?:[^']|\\\\(?:'|u\\w{4}))'") // char .or(NULL.css, "\\bnull\\b") .or(BOOLEAN.css, "\\btrue|false\\b") - .or("annotation", "@[\\w]+") - .or("class-ident", "\\b[A-Z][\\w_$]*\\b") + .or(ANNOTATION.css, "@[\\w]+") + .or(CLASS_IDENTIFIER.css, "\\b[A-Z][\\w_$]*\\b") .create(Pattern.DOTALL); diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XPathSyntaxHighlighter.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XPathSyntaxHighlighter.java index 36f72fd0e9..92c504a98a 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XPathSyntaxHighlighter.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XPathSyntaxHighlighter.java @@ -9,6 +9,10 @@ import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighti import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.PAREN; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.SINGLEL_COMMENT; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.STRING; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XPATH_ATTRIBUTE; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XPATH_AXIS; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XPATH_FUNCTION; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XPATH_PATH; import net.sourceforge.pmd.util.fxdesigner.util.codearea.SimpleRegexSyntaxHighlighter; @@ -30,11 +34,11 @@ public class XPathSyntaxHighlighter extends SimpleRegexSyntaxHighlighter { private static final RegexHighlightGrammar GRAMMAR - = grammarBuilder("attribute", "@[\\w]+") - .or("axis", "(" + String.join("|", AXIS_NAMES) + ")(?=::)") + = grammarBuilder(XPATH_ATTRIBUTE.css, "@[\\w]+") + .or(XPATH_AXIS.css, "(" + String.join("|", AXIS_NAMES) + ")(?=::)") .or(KEYWORD.css, "\\b(" + String.join("|", KEYWORDS) + ")\\b") - .or("function", "[\\w-]+?(?=\\()") - .or("path", "//?") + .or(XPATH_FUNCTION.css, "[\\w-]+?(?=\\()") + .or(XPATH_PATH.css, "//?") .or(PAREN.css, "[()]") .or(BRACKET.css, "[\\[\\]]") .or(STRING.css, "('([^'\\\\]|\\\\.)*')|(\"([^\"\\\\]|\\\\.)*\")") diff --git a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XmlSyntaxHighlighter.java b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XmlSyntaxHighlighter.java index 5ab62a1aae..d336e01adc 100644 --- a/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XmlSyntaxHighlighter.java +++ b/pmd-ui/src/main/java/net/sourceforge/pmd/util/fxdesigner/util/codearea/syntaxhighlighting/XmlSyntaxHighlighter.java @@ -5,6 +5,12 @@ package net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting; import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.MULTIL_COMMENT; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XML_ATTRIBUTE_NAME; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XML_CDATA_CONTENT; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XML_CDATA_TAG; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XML_LT_GT; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XML_PROLOG; +import static net.sourceforge.pmd.util.fxdesigner.util.codearea.syntaxhighlighting.HighlightClasses.XML_TAG_NAME; import java.util.regex.Pattern; @@ -19,12 +25,12 @@ public class XmlSyntaxHighlighter extends SimpleRegexSyntaxHighlighter { private static final RegexHighlightGrammar GRAMMAR = grammarBuilder(MULTIL_COMMENT.css, "") - .or("cdata-tag", "") - .or("cdata-content", "(?<=)") - .or("xml-prolog", "<\\?xml.*?\\?>") - .or("lt-gt", "") - .or("tag-name", "\\b(?<=(") + .or(XML_CDATA_CONTENT.css, "(?<=)") + .or(XML_PROLOG.css, "<\\?xml.*?\\?>") + .or(XML_LT_GT.css, "") + .or(XML_TAG_NAME.css, "\\b(?<=(\\\\]|\\\\.)*')|(\"([^\"<>\\\\]|\\\\.)*\")") .create(Pattern.DOTALL); diff --git a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/editor-theme.css b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/editor-theme.css index c0bcc9b60d..bf88822893 100644 --- a/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/editor-theme.css +++ b/pmd-ui/src/main/resources/net/sourceforge/pmd/util/fxdesigner/css/editor-theme.css @@ -10,7 +10,9 @@ -fx-fill: lightgreen !important; } +/********/ /* Base */ +/*******/ .styled-text-area { -fx-background-color: whitesmoke; @@ -46,62 +48,37 @@ -fx-font-weight: normal; } +/****************************/ /* Syntax highlighting base */ +/****************************/ .styled-text-area .keyword { -fx-fill: #B58900; /* -fx-font-weight: bold; */ } -.styled-text-area .paren { +.styled-text-area .punctuation { } -.styled-text-area .brace { -} - -.styled-text-area .string { +.styled-text-area .literal { -fx-fill: #317ECC; } -.styled-text-area .number { - -fx-fill: #317ECC; -} -.styled-text-area .null { - -fx-fill: #317ECC; -} - -.styled-text-area .boolean { - -fx-fill: #317ECC; -} - -.styled-text-area .char { - -fx-fill: #317ECC; -} - -.styled-text-area .multi-line-comment { - -fx-fill: #93A1A1; - -fx-font-style: italic; -} - -.styled-text-area .single-line-comment { +.styled-text-area .comment { -fx-fill: #93A1A1; -fx-font-style: italic; /* doesn't work... */ } -.styled-text-area .semicolon { - -} - -/* Java specific */ - .styled-text-area .annotation { -fx-fill: #d30102; } -.styled-text-area .class-ident { +/* Java specific */ + +.styled-text-area .java.class-identifier { -fx-fill: #B05A65; }