package com.scrivenvar.processors.markdown;
import com.vladsch.flexmark.ast.Text;
import com.vladsch.flexmark.html.HtmlWriter;
import com.vladsch.flexmark.html.renderer.NodeRenderer;
import com.vladsch.flexmark.html.renderer.NodeRendererContext;
import com.vladsch.flexmark.html.renderer.NodeRendererFactory;
import com.vladsch.flexmark.html.renderer.NodeRenderingHandler;
import com.vladsch.flexmark.util.ast.TextCollectingVisitor;
import com.vladsch.flexmark.util.data.DataHolder;
import com.vladsch.flexmark.util.data.MutableDataHolder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import static com.scrivenvar.processors.text.TextReplacementFactory.replace;
import static com.vladsch.flexmark.html.HtmlRenderer.Builder;
import static com.vladsch.flexmark.html.HtmlRenderer.HtmlRendererExtension;
public class LigatureExtension implements HtmlRendererExtension {
private static final Map<String, String> LIGATURES = new LinkedHashMap<>();
static {
LIGATURES.put( "ffi", "\uFB03" );
LIGATURES.put( "ffl", "\uFB04" );
LIGATURES.put( "ff", "\uFB00" );
LIGATURES.put( "fi", "\uFB01" );
LIGATURES.put( "fl", "\uFB02" );
LIGATURES.put( "ft", "\uFB05" );
LIGATURES.put( "AE", "\u00C6" );
LIGATURES.put( "OE", "\u0152" );
}
private static class LigatureRenderer implements NodeRenderer {
private final TextCollectingVisitor mVisitor = new TextCollectingVisitor();
@SuppressWarnings("unused")
public LigatureRenderer( final DataHolder options ) {
}
@Override
public @Nullable Set<NodeRenderingHandler<?>> getNodeRenderingHandlers() {
return Set.of( new NodeRenderingHandler<>(
Text.class, LigatureRenderer.this::render ) );
}
private void render(
@NotNull final Text textNode,
@NotNull final NodeRendererContext context,
@NotNull final HtmlWriter html ) {
final var text = mVisitor.collectAndGetText( textNode );
html.text( replace( text, LIGATURES ) );
}
}
private static class Factory implements NodeRendererFactory {
@NotNull
@Override
public NodeRenderer apply( @NotNull DataHolder options ) {
return new LigatureRenderer( options );
}
}
private LigatureExtension() {
}
@Override
public void rendererOptions( @NotNull final MutableDataHolder options ) {
}
@Override
public void extend( @NotNull final Builder builder,
@NotNull final String rendererType ) {
if( "HTML".equalsIgnoreCase( rendererType ) ) {
builder.nodeRendererFactory( new Factory() );
}
}
public static LigatureExtension create() {
return new LigatureExtension();
}
}