Adding docs for Inline Macro Processor positional attributes
MODIFY
asciidoctorj-documentation/build.gradle
asciidoctorj-documentation/build.gradle
@@ -51,6 +51,7 @@ task copyExtensionsExamplesToDocs(type: Copy) {
include '**/extension/GistBlockMacroProcessor.java'
include '**/extension/ImageInlineMacroProcessor.java'
include '**/extension/IssueInlineMacroProcessor.java'
+ include '**/extension/IssueInlineMacroPositionalAttributesProcessor.java'
include '**/extension/KeyboardInlineMacroProcessor.java'
include '**/extension/LoggingBlockMacroProcessor.java'
include '**/extension/LsIncludeProcessor.java'
@@ -70,6 +71,7 @@ task copyExtensionsExamplesToDocs(type: Copy) {
include 'gist-macro.adoc'
include 'logging-macro.adoc'
include 'issue-inline-macro.adoc'
+ include 'issue-inline-macro-positional.adoc'
include 'treeprocessorcontent.adoc'
include 'treeprocessorresult.adoc'
include 'yell-block.adoc'

ADD
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/extension/IssueInlineMacroPositionalAttributesProcessor.java
+package org.asciidoctor.integrationguide.extension;
+
+//tag::include[]
+import org.asciidoctor.ast.ContentNode;
+import org.asciidoctor.extension.InlineMacroProcessor;
+import org.asciidoctor.extension.Name;
+import org.asciidoctor.extension.PositionalAttributes;
+
+//end::include[]
+import java.util.HashMap;
+import java.util.Map;
+
+//tag::include[]
+@Name("issue")
+@PositionalAttributes({"repo"}) // <1>
+public class IssueInlineMacroPositionalAttributesProcessor extends InlineMacroProcessor {
+
+ @Override
+ public Object process(ContentNode parent, String target, Map<String, Object> attributes) {
+
+ String href =
+ new StringBuilder()
+ .append("https://github.com/")
+ .append(attributes.containsKey("repo") ?
+ attributes.get("repo") :
+ parent.getDocument().getAttribute("repo"))
+ .append("/issues/")
+ .append(target).toString();
+
+ Map<String, Object> options = new HashMap<>();
+ options.put("type", ":link");
+ options.put("target", href);
+ return createPhraseNode(parent, "anchor", target, attributes, options); // <4>
+ }
+
+}
+//end::include[]

MODIFY
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/extension/IssueInlineMacroProcessorTest.java
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/extension/IssueInlineMacroProcessorTest.java
package org.asciidoctor.integrationguide.extension;
import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.Options;
import org.asciidoctor.OptionsBuilder;
import org.asciidoctor.util.ClasspathResources;
import org.jboss.arquillian.junit.Arquillian;
@@ -47,5 +48,27 @@ public class IssueInlineMacroProcessorTest {
//end::include[]
}
+ @Test
+ public void should_create_anchor_elements_for_inline_macros_with_positional_attributes() {
+
+ File issueinlinemacro_adoc = //...
+ classpathResources.getResource("issue-inline-macro-positional.adoc");
+
+ asciidoctor.javaExtensionRegistry().inlineMacro(IssueInlineMacroPositionalAttributesProcessor.class);
+
+ String result = asciidoctor.convertFile(issueinlinemacro_adoc, Options.builder().toFile(false).build());
+
+ assertThat(
+ result,
+ containsString(
+ "<a href=\"https://github.com/asciidoctor/asciidoctorj/issues/334\"")); // <2>
+
+ assertThat(
+ result,
+ containsString( // <2>
+ "<a href=\"https://github.com/asciidoctor/asciidoctorj-groovy-dsl/issues/3\""));
+
+ }
+
}

ADD
asciidoctorj-documentation/src/test/resources/issue-inline-macro-positional.adoc
+ = InlineMacroProcessor Test Document
+:repo: asciidoctor/asciidoctorj-groovy-dsl
+
+You might want to take a look at the issue issue:334[asciidoctor/asciidoctorj] and issue:3[].

ADD
docs/modules/extensions/examples/issue-inline-macro-positional.adoc
+= InlineMacroProcessor Test Document
+:repo: asciidoctor/asciidoctorj-groovy-dsl
+
+You might want to take a look at the issue issue:334[asciidoctor/asciidoctorj] and issue:3[].

ADD
docs/modules/extensions/examples/org/asciidoctor/integrationguide/extension/IssueInlineMacroPositionalAttributesProcessor.java
+package org.asciidoctor.integrationguide.extension;
+
+//tag::include[]
+import org.asciidoctor.ast.ContentNode;
+import org.asciidoctor.extension.InlineMacroProcessor;
+import org.asciidoctor.extension.Name;
+import org.asciidoctor.extension.PositionalAttributes;
+
+//end::include[]
+import java.util.HashMap;
+import java.util.Map;
+
+//tag::include[]
+@Name("issue")
+@PositionalAttributes({"repo"}) // <1>
+public class IssueInlineMacroPositionalAttributesProcessor extends InlineMacroProcessor {
+
+ @Override
+ public Object process(ContentNode parent, String target, Map<String, Object> attributes) {
+
+ String href =
+ new StringBuilder()
+ .append("https://github.com/")
+ .append(attributes.containsKey("repo") ?
+ attributes.get("repo") :
+ parent.getDocument().getAttribute("repo"))
+ .append("/issues/")
+ .append(target).toString();
+
+ Map<String, Object> options = new HashMap<>();
+ options.put("type", ":link");
+ options.put("target", href);
+ return createPhraseNode(parent, "anchor", target, attributes, options); // <4>
+ }
+
+}
+//end::include[]

MODIFY
docs/modules/extensions/pages/inline-macro-processor.adoc
docs/modules/extensions/pages/inline-macro-processor.adoc
@@ -42,10 +42,14 @@ The third parameter `target` defines that the text to render this link is the ta
The last parameter, the options, must contain the target of the line, i.e. the referenced URL, and that the type of the anchor is a link.
It could also be a ':xref', a ':ref', or a ':bibref'.
+== Creating phrase nodes
+
The example above has shown how to create a link from a macro.
But there are several other things that an InlineMacroProcessor can create like icons, inline images etc.
Even though the following examples might not make much sense, they show how phrase nodes have to be created for the different use cases.
+=== Create keyboard macros
+
To create keyboard icons like kbd:[Ctrl+T] which can be created directly in Asciidoctor via `\kbd:[Ctrl+T]` you create the PhraseNode as shown below.
The example assumes that the macro is called with the macro name `ctrl` and a key as the target, e.g. `\ctrl:S[]`, and creates kbd:[Ctrl + S] from it.
@@ -58,6 +62,8 @@ include::example$org/asciidoctor/integrationguide/extension/KeyboardInlineMacroP
<1> The attributes of the PhraseNode must contain the keys to be shown as a list for the attribute key `keys`.
<2> Create a PhraseNode with context `kbd` and no text and return it.
+=== Create button or menu selection macros
+
To create a menu selection as described at http://asciidoctor.org/docs/user-manual/#menu-selections a processor would create a PhraseNode with the `menu` context.
The following processor would render the macro `rightclick:New|Class[]` like this: menu:New[Class].
@@ -70,6 +76,8 @@ include::example$org/asciidoctor/integrationguide/extension/ContextMenuInlineMac
<1> The attributes of the PhraseNode must contain the key `menu` referring to the first menu selection, `submenus` referring to a possibly empty list of submenu selections, and finally the key `menuitem` referring to the final menu item selection.
<2> Create and return an PhraseNode with context `menu` and no text.
+=== Create inline images
+
To create an inline image the PhraseNode must have the context `image`.
The following example assumes that there is a site \http://foo.bar that serves images given as the target of the macro.
That means the MacroProcessor should replace the macro `foo:1234` to an image element that refers to \http://foo.bar/1234.
@@ -102,3 +110,28 @@ class CiteInlineMacroProcessor extends InlineMacroProcessor {
----
With the SHORT format, the attributes are not parsed, and the 'target' that is passed to your macro is the value between the brackets ("brown79").
+
+== Positional attributes
+
+The first example here has shown how to access named attributes.
+But AsciiDoc also supports positional attributes where the meaning implicitly derived from the position in the attribute list.
+In that example the attribute `repo` might also be defined as the first attribute so that the inline macro might also be written as `issue:333[asciidoctor/asciidoctorj]`.
+
+The following extension accepts the attribute `repo` as a positional attribute:
+
+.Accept positional attributes in an inline macro
+[source,java,indent=0]
+----
+include::example$org/asciidoctor/integrationguide/extension/IssueInlineMacroPositionalAttributesProcessor.java[tags=include]
+----
+<1> The annotation `@PositionalAttributes` defines the positional attributes and their order.
+If the macro accepted a second positional attribute `comment` the annotation would be `@PositionalAttributes({"repo", "comment"})`.
+
+This extension will accept the macros in this document:
+
+
+[source,asciidoc]
+----
+include::example$issue-inline-macro-positional.adoc[]
+----
+

Adding docs for Inline Macro Processor positional attributes