How to have the returned Inline being formatted in an asciidoctorj InlineMacroProcessor

85 Views Asked by At

Given this example Inline macro:

package some;

import java.util.Map;

import org.asciidoctor.ast.ContentNode;
import org.asciidoctor.extension.InlineMacroProcessor;

public class SomeMacro extends InlineMacroProcessor {

    public SomeMacro(String macroName) {
        super(macroName);
    }

    public SomeMacro(String macroName, Map<String, Object> config) {
        super(macroName, config);
    }

    @Override
    public Object process(ContentNode parent, String target, Map<String, Object> attributes) {
        String text;
        switch (target) {
        case "test":
            text = "this is *me* and `you` here";
            break;

        default:
            text = "NOT DEFINED";
            break;
        }
        return createPhraseNode(parent, "quoted", text, attributes);
    }
}

In reality computation of the text is not hardcoded in a switch, but the result of a more complex logic.

The code to test this macro (presented as a unit test):

package some;

import static org.assertj.core.api.Assertions.assertThat;

import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Asciidoctor.Factory;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.SafeMode;
import org.junit.jupiter.api.Test;

import com.unblu.asciidoctorj.config.InMemoryLogHandler;

public class Snippet {

    @Test
    public void someTest() {
        String content = "This is some:test[] and some:other[] end.";

        String expected = "<div class=\"paragraph\">\n"
                + "<p>This is this is *me* and `you` here and NOT DEFINED end.</p>\n"
                + "</div>";

        Asciidoctor asciidoctor = Factory.create();

        asciidoctor.createGroup()
                .inlineMacro("some", "some.SomeMacro")
                .register();

        OptionsBuilder optionsBuilder = OptionsBuilder.options()
                .docType("article")
                .safe(SafeMode.UNSAFE);
        String html = asciidoctor.convert(content, optionsBuilder);

        assertThat(html.trim()).isEqualTo(expected);
    }
}

If the input is:

This is some:test[] and some:other[] end.

The result is:

<div class=\"paragraph\">
<p>This is this is *me* and `you` here and NOT DEFINED end.</p>
</div>

I would like the *me* and the you to be converted using text formatting:

<div class=\"paragraph\">
<p>This is this is <strong>me</strong> and <code>you</code> here and NOT DEFINED end.</p>
</div>
1

There are 1 best solutions below

0
On

Dan Allen provided explanations on Twitter

When calling createPhraseNode(parent, "quoted", text, attributes), it is possible to activate the conversation by activating the normal substitutions.

Map<String, Object> phraseNodeAttributes = new HashMap<>();
phraseNodeAttributes.put("subs", ":normal");
return createPhraseNode(parent, "quoted", text, phraseNodeAttributes);