/*=============================================================================#
# Copyright (c) 2015-2016 David Green and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# David Green - initial API and implementation in Mylyn
# Stephan Wahlbrink (WalWare.de) - revised API and implementation
#=============================================================================*/
package de.walware.docmlet.wikitext.internal.commonmark.core.inlines;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder;
import org.eclipse.mylyn.wikitext.core.parser.builder.NoOpDocumentBuilder;
import de.walware.jcommons.collections.ImCollections;
import de.walware.jcommons.collections.ImList;
import de.walware.docmlet.wikitext.internal.commonmark.core.CommonmarkLocator;
import de.walware.docmlet.wikitext.internal.commonmark.core.Cursor;
import de.walware.docmlet.wikitext.internal.commonmark.core.ProcessingContext;
import de.walware.docmlet.wikitext.internal.commonmark.core.TextSegment;
public class InlineParser {
private static final CommonmarkLocator NO_OP_LOCATOR= new CommonmarkLocator();
public static void emit(final ProcessingContext context, final List<Inline> inlines,
final CommonmarkLocator locator, final DocumentBuilder builder) {
for (final Inline inline : inlines) {
locator.setInline(inline);
inline.emit(context, locator, builder);
}
}
public static String toStringContent(final ProcessingContext context, final List<Inline> contents) {
final StringBuilder stringBuilder= new StringBuilder();
final DocumentBuilder altDocumentBuilder= new NoOpDocumentBuilder() {
@Override
public void characters(final String text) {
stringBuilder.append(text);
}
@Override
public void entityReference(final String entity) {
final String replacement= context.getHelper().resolveHtmlEntity(entity);
if (replacement != null) {
stringBuilder.append(replacement);
}
}
};
for (final Inline inline : contents) {
inline.emit(context, NO_OP_LOCATOR, altDocumentBuilder);
}
return stringBuilder.toString();
}
private final ImList<SourceSpan> spans;
public InlineParser(final ImList<SourceSpan> spans) {
this.spans= ImCollections.toList(spans);
}
public void emit(final ProcessingContext context, final TextSegment textSegment,
final CommonmarkLocator locator, final DocumentBuilder builder) {
final List<Inline> inlines= parse(context, textSegment, false);
emit(context, inlines, locator, builder);
}
public String toStringContent(final ProcessingContext context, final TextSegment textSegment) {
final List<Inline> inlines= parse(context, textSegment, false);
return toStringContent(context, inlines);
}
public List<Inline> parse(final ProcessingContext context, final TextSegment segment,
final boolean inBlock) {
final Cursor cursor= new Cursor(segment);
final List<Inline> inlines= new ArrayList<>();
ITER_CHARS: while (cursor.hasChar()) {
for (final SourceSpan span : this.spans) {
final Inline inline= span.createInline(context, cursor);
if (inline != null) {
inline.apply(context, inlines, cursor, inBlock);
continue ITER_CHARS;
}
}
throw new IllegalStateException();
}
return secondPass(inlines);
}
static List<Inline> secondPass(final List<Inline> inlines) {
List<Inline> processedInlines= new ArrayList<>(inlines);
InlinesSubstitution substitution= null;
do {
for (final Inline inline : processedInlines) {
substitution= inline.secondPass(processedInlines);
if (substitution != null) {
processedInlines= substitution.apply(processedInlines);
break;
}
}
} while (substitution != null);
return processedInlines;
}
}