Add documentation for logging from extensions
MODIFY
asciidoctorj-documentation/build.gradle
asciidoctorj-documentation/build.gradle
@@ -52,6 +52,7 @@ task copyExtensionsExamplesToDocs(type: Copy) {
include '**/extension/ImageInlineMacroProcessor.java'
include '**/extension/IssueInlineMacroProcessor.java'
include '**/extension/KeyboardInlineMacroProcessor.java'
+ include '**/extension/LoggingBlockMacroProcessor.java'
include '**/extension/LsIncludeProcessor.java'
include '**/extension/RobotsDocinfoProcessor.java'
include '**/extension/TerminalCommandExtension.java'
@@ -65,6 +66,7 @@ task copyExtensionsExamplesToDocs(type: Copy) {
include 'comment.adoc'
include 'comment-with-note.adoc'
include 'gist-macro.adoc'
+ include 'logging-macro.adoc'
include 'issue-inline-macro.adoc'
include 'treeprocessorcontent.adoc'
include 'treeprocessorresult.adoc'

ADD
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/extension/LoggingBlockMacroProcessor.java
+package org.asciidoctor.integrationguide.extension;
+
+import org.asciidoctor.ast.StructuralNode;
+import org.asciidoctor.extension.BlockMacroProcessor;
+import org.asciidoctor.extension.Name;
+
+import java.util.Map;
+
+//tag::include[]
+@Name("log")
+public class LoggingBlockMacroProcessor extends BlockMacroProcessor {
+
+ @Override
+ public Object process(
+ StructuralNode parent, String target, Map<String, Object> attributes) {
+
+ String message = target;
+
+ log(new org.asciidoctor.log.LogRecord( // <1>
+ org.asciidoctor.log.Severity.INFO,
+ parent.getSourceLocation(), // <2>
+ message));
+
+ return createBlock(parent, "paragraph", "Hello from the logging macro");
+ }
+
+}
+//end::include[]

ADD
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/extension/LoggingBlockMacroProcessorTest.java
+package org.asciidoctor.integrationguide.extension;
+
+import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.Options;
+import org.asciidoctor.log.LogRecord;
+import org.asciidoctor.util.ClasspathResources;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.test.api.ArquillianResource;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(Arquillian.class)
+public class LoggingBlockMacroProcessorTest {
+
+ @ArquillianResource
+ private Asciidoctor asciidoctor;
+
+ @ArquillianResource
+ private ClasspathResources classpathResources;
+
+ @Test
+ public void should_log_from_extension() {
+
+//tag::include[]
+ File loggingmacro_adoc = // ...
+//end::include[]
+ classpathResources.getResource("logging-macro.adoc");
+//tag::include[]
+ List<LogRecord> logRecords = new ArrayList<>();
+ asciidoctor.registerLogHandler(logRecords::add);
+ asciidoctor.javaExtensionRegistry().blockMacro(LoggingBlockMacroProcessor.class); // <1>
+
+ asciidoctor.convertFile(loggingmacro_adoc,
+ Options.builder()
+ .sourcemap(true)
+ .toFile(false)
+ .build());
+
+ assertEquals(1, logRecords.size());
+ assertTrue(logRecords.get(0).getCursor().getFile().endsWith("logging-macro.adoc"));
+ assertEquals(3, logRecords.get(0).getCursor().getLineNumber());
+ assertEquals("HelloWorld", logRecords.get(0).getMessage());
+//end::include[]
+ }
+
+
+}

ADD
asciidoctorj-documentation/src/test/resources/logging-macro.adoc
+= Log Test
+
+== A logging macro
+
+log::HelloWorld[]
\ No newline at end of file

MODIFY
docs/modules/ROOT/pages/asciidoctor-api-options.adoc
docs/modules/ROOT/pages/asciidoctor-api-options.adoc
@@ -115,6 +115,19 @@ OptionsBuilder optionsBuilder =
Options.builder().templateDirs(new File("templates_path"));
----
+[[sourcemap]]
+== sourcemap
+
+Keeps track of the file and line number for each parsed block. (Useful for tooling applications where the association between the converted output and the source file is important).
+The default for this option is `false`.
+
+[source,java]
+.Setting the option sourcemap
+----
+OptionsBuilder optionsBuilder =
+ Options.builder().sourcemap(true);
+----
+
== attributes
This option allows to define document attributes externally.

ADD
docs/modules/extensions/examples/logging-macro.adoc
+= Log Test
+
+== A logging macro
+
+log::HelloWorld[]
\ No newline at end of file

ADD
docs/modules/extensions/examples/org/asciidoctor/integrationguide/extension/LoggingBlockMacroProcessor.java
+package org.asciidoctor.integrationguide.extension;
+
+import org.asciidoctor.ast.StructuralNode;
+import org.asciidoctor.extension.BlockMacroProcessor;
+import org.asciidoctor.extension.Name;
+
+import java.util.Map;
+
+//tag::include[]
+@Name("log")
+public class LoggingBlockMacroProcessor extends BlockMacroProcessor {
+
+ @Override
+ public Object process(
+ StructuralNode parent, String target, Map<String, Object> attributes) {
+
+ String message = target;
+
+ log(new org.asciidoctor.log.LogRecord( // <1>
+ org.asciidoctor.log.Severity.INFO,
+ parent.getSourceLocation(), // <2>
+ message));
+
+ return createBlock(parent, "paragraph", "Hello from the logging macro");
+ }
+
+}
+//end::include[]

MODIFY
docs/modules/extensions/nav.adoc
docs/modules/extensions/nav.adoc
*** xref:register-extensions-manually.adoc[]
*** xref:register-extensions-bulk.adoc[]
*** xref:register-extensions-automatically.adoc[]
+** xref:logging.adoc[]
+

ADD
docs/modules/extensions/pages/logging.adoc
+= Logging
+
+Extensions are also able to log messages that are handled in the same way as messages logged by Asciidoctor itself as explained in xref:ROOT:logs-handling.adoc[].
+
+Logging messages via this API allows build tools like the Asciidoctor Maven plugin to capture them and for example xref:maven-tools:plugin:goals/process-asciidoc.adoc#configuration-logHandler[fail the build] in case an error or warning is logged.
+Therefore it might be preferable to use this instead of directly logging messages via slf4j or other APIs.
+
+Every extension inherits the method `Processor.log()` that allows it to log messages.
+The following example shows a Block Macro Processor that logs a message containing the target of the macro:
+
+[source,java]
+----
+include::example$org/asciidoctor/integrationguide/extension/LoggingBlockMacroProcessor.java[tags=include]
+----
+<1> The method `log(LogRecord)` is inherited from the Processor class hierarchy.
+<2> You can access the source location of the parent node to put the message in relation to the source document.
+ Note that the source location will be null unless you enable the xref:ROOT:asciidoctor-api-options.adoc#sourcemap[sourcemap] option
\ No newline at end of file

Add documentation for logging from extensions