blob: 1b845f6fea7b333d6b73522f6977214fd4b68694 [file] [log] [blame]
/*=============================================================================#
# 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);
}
}