int (Matcher matcher, String text, Document document, Ref<Integer> textOffset) { document.deleteString(textOffset.get(), textOffset.get() + matcher.end() - matcher.start()); String marker = matcher.group("marker"); @NlsSafe String descr = matcher.group("descr"); String typeString = matcher.group("type"); String foregroundColor = matcher.group("foreground"); String backgroundColor = matcher.group("background"); String effectColor = matcher.group("effectcolor"); String effectType = matcher.group("effecttype"); String fontType = matcher.group("fonttype"); String attrKey = matcher.group("textAttributesKey"); String bundleMessage = matcher.group("bundleMsg"); @NlsSafe String tooltip = matcher.group("tooltip"); boolean closed = matcher.group("closed") != null; if (descr == null) { descr = ANY_TEXT; // no descr means any string by default } else if (descr.equals("null")) { descr = null; // explicit "null" descr } if (descr != null) { descr = descr.replaceAll("\\\\\\\\\"", "\""); // replace: \\" to ", doesn't check symbol before sequence \\" descr = descr.replaceAll("\\\\\"", "\""); } if (tooltip == null) { tooltip = ANY_TEXT; // no tooltip any string by default } else if (tooltip.equals("null")) { tooltip = null; // explicit "null" tooltip } if (tooltip != null) { tooltip = tooltip.replaceAll("\\\\\\\\\"", "\""); // replace: \\" to ", doesn't check symbol before sequence \\" tooltip = tooltip.replaceAll("\\\\\"", "\""); } HighlightInfoType type = WHATEVER; if (typeString != null) { try { type = getTypeByName(typeString); } catch (Exception e) { throw new RuntimeException(e); } if (type == null) { fail("Wrong highlight type: " + typeString); } } TextAttributes forcedAttributes = null; if (foregroundColor != null) { @JdkConstants.FontStyle int ft = fontType != null ? Integer.parseInt(fontType) : 0; forcedAttributes = new TextAttributes( Color.decode(foregroundColor), backgroundColor != null ? Color.decode(backgroundColor) : null, effectColor != null ? Color.decode(effectColor) : null, effectType != null ? EffectType.valueOf(effectType) : null, ft); } int rangeStart = textOffset.get(); int toContinueFrom; if (closed) { toContinueFrom = matcher.end(); } else { int pos = matcher.end(); Matcher closingTagMatcher = Pattern.compile("</" + marker + ">").matcher(text); while (true) { if (!closingTagMatcher.find(pos)) { toContinueFrom = pos; break; } int nextTagStart = matcher.find(pos) ? matcher.start() : text.length(); if (closingTagMatcher.start() < nextTagStart) { textOffset.set(textOffset.get() + closingTagMatcher.start() - pos); document.deleteString(textOffset.get(), textOffset.get() + closingTagMatcher.end() - closingTagMatcher.start()); toContinueFrom = closingTagMatcher.end(); break; } textOffset.set(textOffset.get() + nextTagStart - pos); pos = extractExpectedHighlight(matcher, text, document, textOffset); } } ExpectedHighlightingSet expectedHighlightingSet = myHighlightingTypes.get(marker); if (expectedHighlightingSet.enabled) { TextAttributesKey forcedTextAttributesKey = attrKey == null ? null : TextAttributesKey.createTextAttributesKey(attrKey); HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(type).range(rangeStart, textOffset.get()).severity(expectedHighlightingSet.severity); if (forcedAttributes != null) builder.textAttributes(forcedAttributes); if (forcedTextAttributesKey != null) builder.textAttributes(forcedTextAttributesKey); if (descr != null) { builder.description(descr); } if (tooltip != null) { if (tooltip.startsWith("<html>")) { builder.escapedToolTip(tooltip); } else { builder.unescapedToolTip(tooltip); } } if (expectedHighlightingSet.endOfLine) builder.endOfLine(); HighlightInfo highlightInfo = builder.createUnconditionally(); expectedHighlightingSet.infos.add(highlightInfo); } return toContinueFrom; }