| /*=============================================================================# |
| # Copyright (c) 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.r.ui.pager; |
| |
| import java.util.ArrayList; |
| |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.ITypedRegion; |
| import org.eclipse.jface.text.TypedRegion; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.collections.ImList; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| |
| |
| @NonNullByDefault |
| public class TextFileParser { |
| |
| |
| public static final String DEFAULT_FORMAT_TYPE= IDocument.DEFAULT_CONTENT_TYPE; |
| public static final String UNDERLINE_FORMAT_TYPE= "Pager.Underline"; |
| |
| |
| private boolean createDefaultRegions= false; |
| |
| private final StringBuilder cleanTextBuilder= new StringBuilder(); |
| |
| private final ArrayList<ITypedRegion> formatRegions= new ArrayList<>(); |
| private String cleanText= ""; //$NON-NLS-1$ |
| |
| |
| public TextFileParser() { |
| } |
| |
| |
| public void setCreateDefaultRegions(final boolean enable) { |
| this.createDefaultRegions= enable; |
| } |
| |
| |
| public void parse(final String in) { |
| this.formatRegions.clear(); |
| this.cleanTextBuilder.setLength(0); |
| |
| final int inLength= in.length(); |
| int offsetDone= 0; |
| while (offsetDone < inLength) { |
| final int backOffset= in.indexOf(0x08, offsetDone); |
| if (backOffset >= 0) { |
| this.cleanTextBuilder.append(in, offsetDone, backOffset - 1); |
| if (backOffset + 1 == inLength || backOffset == offsetDone) { |
| offsetDone= backOffset + 1; |
| continue; |
| } |
| switch (in.charAt(backOffset - 1)) { |
| case '_': |
| checkDefaultFormat(this.cleanTextBuilder.length()); |
| offsetDone= readBackspaceFormat(in, backOffset - 1, '_', UNDERLINE_FORMAT_TYPE); |
| continue; |
| default: |
| offsetDone= backOffset + 1; |
| continue; |
| } |
| } |
| else { |
| if (offsetDone > 0) { |
| this.cleanTextBuilder.append(in, offsetDone, inLength); |
| offsetDone= inLength; |
| } |
| break; |
| } |
| } |
| |
| this.cleanText= (offsetDone > 0) ? this.cleanTextBuilder.toString() : in; |
| checkDefaultFormat(this.cleanText.length()); |
| } |
| |
| private void checkDefaultFormat(final int offset) { |
| if (!this.createDefaultRegions) { |
| return; |
| } |
| final int lastEndOffset; |
| if (this.formatRegions.isEmpty()) { |
| lastEndOffset= 0; |
| } |
| else { |
| final ITypedRegion lastFormat= this.formatRegions.get(this.formatRegions.size() - 1); |
| lastEndOffset= lastFormat.getOffset() + lastFormat.getLength(); |
| } |
| if (offset > lastEndOffset) { |
| this.formatRegions.add(new TypedRegion( |
| lastEndOffset, offset - lastEndOffset, |
| DEFAULT_FORMAT_TYPE )); |
| } |
| } |
| |
| private int readBackspaceFormat(final String in, int offset, final char formatChar, |
| final String formatType) { |
| final int inLength= in.length(); |
| final int cleanStartOffset= this.cleanTextBuilder.length(); |
| |
| do { |
| this.cleanTextBuilder.append(in.charAt(offset + 2)); |
| offset+= 3; |
| } |
| while (offset + 2 < inLength |
| && in.charAt(offset) == formatChar |
| && in.charAt(offset + 1) == 0x08); |
| |
| this.formatRegions.add(new TypedRegion( |
| cleanStartOffset, this.cleanTextBuilder.length() - cleanStartOffset, |
| formatType )); |
| return offset; |
| } |
| |
| |
| public String getCleanText() { |
| return this.cleanText; |
| } |
| |
| public ImList<ITypedRegion> getFormatRegions() { |
| return ImCollections.toList(this.formatRegions); |
| } |
| |
| } |