Fixes Initialize BlockProcessor.name correctly
MODIFY
asciidoctorj-core/src/main/java/org/asciidoctor/extension/processorproxies/BlockProcessorProxy.java
asciidoctorj-core/src/main/java/org/asciidoctor/extension/processorproxies/BlockProcessorProxy.java
@@ -61,7 +61,9 @@ public class BlockProcessorProxy extends AbstractProcessorProxy<BlockProcessor>
}
@JRubyMethod(name = "initialize", required = 1, optional = 1)
- public IRubyObject initialize(ThreadContext context, IRubyObject[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
+ public IRubyObject initialize(ThreadContext context, IRubyObject[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
+ String macroName = RubyUtils.rubyToJava(getRuntime(), args[0], String.class);
+
if (getProcessor() != null) {
// Instance was created in Java and has options set, so we pass these
// instead of those passed by asciidoctor
@@ -74,17 +76,24 @@ public class BlockProcessorProxy extends AbstractProcessorProxy<BlockProcessor>
JavaEmbedUtils.javaToRuby(getRuntime(), getProcessor().getName()),
RubyHashUtil.convertMapToRubyHashWithSymbols(getRuntime(), getProcessor().getConfig())},
Block.NULL_BLOCK);
+
+ if (macroName != null) {
+ getProcessor().setName(macroName);
+ } else if (getProcessor().getName() == null) {
+ RubyHash config = (RubyHash) this.callMethod(context, "config");
+ Object rubyName = config.get(context.getRuntime().newSymbol("name"));
+ if (rubyName != null) {
+ getProcessor().setName(rubyName.toString());
+ }
+ }
+
// The extension config in the Java extension is just a view on the @config member of the Ruby part
getProcessor().updateConfig(new RubyHashMapDecorator((RubyHash) getInstanceVariable(MEMBER_NAME_CONFIG)));
} else {
-
- String macroName = RubyUtils.rubyToJava(getRuntime(), args[0], String.class);
// First create only the instance passing in the block name
setProcessor(instantiateProcessor(macroName, new HashMap<String, Object>()));
- if (getProcessor().getName() == null) {
getProcessor().setName(macroName);
- }
// Then create the config hash that may contain config options defined in the Java constructor
RubyHash config = RubyHashUtil.convertMapToRubyHashWithSymbols(context.getRuntime(), getProcessor().getConfig());

MODIFY
asciidoctorj-core/src/main/java/org/asciidoctor/internal/JavaExtensionRegistryImpl.java
asciidoctorj-core/src/main/java/org/asciidoctor/internal/JavaExtensionRegistryImpl.java
@@ -181,7 +181,7 @@ public class JavaExtensionRegistryImpl implements JavaExtensionRegistry {
@Override
public JavaExtensionRegistry block(BlockProcessor blockProcessor) {
RubyClass rubyClass = BlockProcessorProxy.register(rubyRuntime, blockProcessor);
- getAsciidoctorModule().callMethod("block_processor", rubyClass, rubyRuntime.newString(blockProcessor.getName()));
+ getAsciidoctorModule().callMethod("block_processor", rubyClass);
return this;
}

ADD
asciidoctorj-core/src/test/java/org/asciidoctor/extension/BlockProcessorRegistrationTest.java
+package org.asciidoctor.extension;
+
+import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.OptionsBuilder;
+import org.asciidoctor.ast.StructuralNode;
+import org.asciidoctor.internal.AsciidoctorCoreException;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.jsoup.Jsoup;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.Map;
+
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Arquillian.class)
+public class BlockProcessorRegistrationTest {
+
+ @ArquillianResource
+ private Asciidoctor asciidoctor;
+
+ private String document(String blockName, String text) {
+ return "= Test\n" +
+ "\n" +
+ "== A section\n" +
+ "\n" +
+ "[" + blockName + "]\n" +
+ text + "\n";
+ }
+
+ public static class AbstractTestProcessor extends BlockProcessor {
+ @Override
+ public Object process(StructuralNode parent, Reader reader, Map<String, Object> attributes) {
+ List<String> s = reader.readLines().stream()
+ .map(line ->
+ line.chars()
+ .mapToObj(c -> Character.toString((char) c))
+ .collect(joining(" ")))
+ .collect(toList());
+ return createBlock(parent, "paragraph", s);
+ }
+ }
+
+ @Name(AnnotatedTestProcessor.NAME)
+ public static class AnnotatedTestProcessor extends AbstractTestProcessor {
+ public static final String NAME = "annotated";
+ }
+
+ @Test
+ public void testRegisterNamedClassAsClass() {
+ asciidoctor.javaExtensionRegistry().block(AnnotatedTestProcessor.class);
+ final String result = asciidoctor.convert(document(AnnotatedTestProcessor.NAME, "Hello World"), OptionsBuilder.options());
+ check("H e l l o W o r l d", result);
+ }
+
+ @Test
+ public void testRegisterNamedClassAsClassWithExplicitName() {
+ final String explicitblockname = "explicitblockname";
+ asciidoctor.javaExtensionRegistry().block(explicitblockname, AnnotatedTestProcessor.class);
+ final String result = asciidoctor.convert(document(explicitblockname, "Hello Explicit"), OptionsBuilder.options());
+ check("H e l l o E x p l i c i t", result);
+ }
+
+ @Test
+ public void testRegisterNamedClassAsInstance() {
+ asciidoctor.javaExtensionRegistry().block(new AnnotatedTestProcessor());
+ final String result = asciidoctor.convert(document(AnnotatedTestProcessor.NAME, "Another Test"), OptionsBuilder.options());
+ check("A n o t h e r T e s t", result);
+ }
+
+ @Test
+ public void testRegisterNamedClassAsInstanceWithExplicitName() {
+ final String blockName = "somename";
+ asciidoctor.javaExtensionRegistry().block(blockName, new AnnotatedTestProcessor());
+ final String result = asciidoctor.convert(document(blockName, "Yet Another Test"), OptionsBuilder.options());
+ check("Y e t A n o t h e r T e s t", result);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterClassWithoutExplicitName() {
+ asciidoctor.javaExtensionRegistry().block(AbstractTestProcessor.class);
+ }
+
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterClassAsClass() {
+ asciidoctor.javaExtensionRegistry().block(AbstractTestProcessor.class);
+ }
+
+ @Test
+ public void testRegisterClassAsClassWithExplicitName() {
+ final String explicitblockname = "anotherexplicitname";
+ asciidoctor.javaExtensionRegistry().block(explicitblockname, AbstractTestProcessor.class);
+ final String result = asciidoctor.convert(document(explicitblockname, "Hello Explicit Class"), OptionsBuilder.options());
+ check("H e l l o E x p l i c i t C l a s s", result);
+ }
+
+ @Test(expected = AsciidoctorCoreException.class)
+ public void testRegisterClassAsInstance() {
+ asciidoctor.javaExtensionRegistry().block(new AbstractTestProcessor());
+ asciidoctor.convert(document("foo", "Hello Explicit Instance"), OptionsBuilder.options());
+ }
+
+ @Test
+ public void testRegisterClassAsInstanceWithExplicitName() {
+ final String explicitblockname = "aname";
+ asciidoctor.javaExtensionRegistry().block(explicitblockname, new AbstractTestProcessor());
+ final String result = asciidoctor.convert(document(explicitblockname, "Hello Explicit Instance"), OptionsBuilder.options());
+ check("H e l l o E x p l i c i t I n s t a n c e", result);
+ }
+
+
+ private void check(String expected, String html) {
+ assertEquals(expected, Jsoup.parse(html).select("div.paragraph > p").first().text());
+ }
+}

Fixes #754. Initialize BlockProcessor.name correctly