| /*=============================================================================# |
| # Copyright (c) 2018, 2021 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.internal.rhelp.core.index; |
| |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| |
| import org.eclipse.statet.rhelp.core.RHelpSearchMatch; |
| |
| |
| @NonNullByDefault |
| public class RHelpHtmlUtils { |
| |
| |
| public static final String HR_PREFIX= "<hr"; //$NON-NLS-1$ |
| public static final Pattern HR_LINE_PATTERN= Pattern.compile("\\A\\<hr\\ ?\\/\\>"); //$NON-NLS-1$ |
| |
| public static final int indexOfLastHr(final String html) { |
| Matcher matcher= null; |
| int idx= html.length(); |
| while ((idx= html.lastIndexOf(HR_PREFIX, idx - 1)) != -1) { |
| if (matcher == null) { |
| matcher= HR_LINE_PATTERN.matcher(html); |
| } |
| matcher.region(idx, html.length()); |
| if (matcher.find()) { |
| return idx; |
| } |
| } |
| return -1; |
| } |
| |
| |
| public static final int indexOfSectionEnd(final String html, final int idxBegin) { |
| final int idx= html.indexOf("<h3", idxBegin); //$NON-NLS-1$ |
| return idx; |
| } |
| |
| |
| public static final String MATCH_HIGHTLIGHT_CLASS_PREFIX= "SMATCH-"; |
| |
| private static final Pattern START_TAG_PATTERN= Pattern.compile("\\A\\<SMATCH\\-([A-J])\\>"); |
| |
| public static String formatHtmlMatches(final String html) { |
| final StringBuilder sb= new StringBuilder(html.length() + 64); |
| final Matcher startMatcher= START_TAG_PATTERN.matcher(html); |
| int idx= 0; |
| int beginIdx= 0; |
| while (idx < html.length()) { |
| final int nextIdx= html.indexOf('<', idx); |
| if (nextIdx != -1) { |
| if (startMatcher.region(nextIdx, html.length()).find()) { |
| sb.append(html, beginIdx, nextIdx); |
| idx= formatHtmlMatch(startMatcher.group(1).charAt(0), html, startMatcher.end(), sb); |
| beginIdx= idx; |
| continue; |
| } |
| } |
| idx++; |
| } |
| sb.append(html, beginIdx, html.length()); |
| return sb.toString(); |
| } |
| |
| private static int formatHtmlMatch(final char matchClass, |
| final String html, final int beginIdx, final StringBuilder sb) { |
| final int endIdx= html.indexOf(RHelpSearchMatch.POST_TAGS[matchClass - 'A'], beginIdx); |
| if (endIdx == -1) { |
| return beginIdx; |
| } |
| |
| sb.append("<span class=\""); |
| sb.append(MATCH_HIGHTLIGHT_CLASS_PREFIX); |
| sb.append(matchClass); |
| sb.append("\">"); |
| |
| // TODO check tag balance? |
| sb.append(html, beginIdx, endIdx); |
| |
| sb.append("</span>"); |
| |
| return endIdx + RHelpSearchMatch.POST_TAGS_PREFIX.length() + 2; |
| } |
| |
| } |