Fix Show how to create an Asciidoctor instance with GEM_PATH
MODIFY
CHANGELOG.adoc
CHANGELOG.adoc
@@ -17,6 +17,10 @@ Build::
* Upgrade jruby-gradle-plugin to 2.0.0-alpha.7 and load Gems directly from rubygems.org instead of using torquebox Maven proxy.
+Documentation::
+
+ * Update documentation to show how to create an Asciidoctor instance with GEM_PATH (#890)
+
== 2.2.0 (2019-12-17)
Improvement::

MODIFY
README.adoc
README.adoc
@@ -915,10 +915,10 @@ You can find out more about how to write your own converters using AsciidoctorJ
Simple extensions may be fully implemented in Java, but if you want to create complex extensions you can mix Ruby and Java code.
This means that you may need to execute a Ruby file or a RubyGem (i.e., gem) inside your extension.
-To load a Ruby file inside the Ruby runtime, you can use `org.asciidoctor.internal.RubyUtils.loadRubyClass(Ruby, InputStream)`.
+To load a Ruby file inside the Ruby runtime, you can use `org.asciidoctor.jruby.internal.RubyUtils.loadRubyClass(Ruby, InputStream)`.
You can also load a gem using an API that wraps Ruby's `require` command.
The gem must be available inside the classpath.
-Next run `org.asciidoctor.internal.RubyUtils.requireLibrary(Ruby, String)`, passing the name of the gem as the second argument.
+Next run `org.asciidoctor.jruby.internal.RubyUtils.requireLibrary(Ruby, String)`, passing the name of the gem as the second argument.
// SW or AS: show an example of loading Ruby libraries or point to an external resource showing examples/further documentation.
@@ -928,19 +928,20 @@ Sometimes you may need the Ruby runtime used inside AsciidoctorJ.
One reason is because you are using JRuby outside AsciidoctorJ and you want to reuse the same instance.
Another reason is that you need to instantiate by yourself an Asciidoctor Ruby object.
-To get this instance you can use `org.asciidoctor.internal.JRubyRuntimeContext.get(Asciidoctor)` to get it from a given Asciidoctor instance.
+To get this instance you can use `org.asciidoctor.jruby.internal.JRubyRuntimeContext.get(Asciidoctor)` to get it from a given Asciidoctor instance.
== GEM_PATH
By default, AsciidoctorJ comes with all required gems bundled within the jar.
But in some circumstances like OSGi environments you may require to store gems in an external folder and be loaded by AsciidoctorJ.
-To accomplish this scenario, `create` method provides a parameter to set folder where gems are present.
-Internally, AsciidoctorJ will set `GEM_PATH` environment variable to given path.
+
+As the Java interface `org.asciidoctor.Asciidoctor` and its factory `org.asciidoctor.Asciidoctor.Factory` are agnostic to JRuby there are the interface `org.asciidoctor.jruby.AsciidoctorJRuby` and `org.asciidoctor.jruby.AsciidoctorJRuby.Factory` that allow to get an Asciidoctor instance using JRuby with a certain GEM_PATH.
+Note that `org.asciidoctor.jruby.AsciidoctorJRuby` directly extends `org.asciidoctor.Asciidoctor`.
[source]
.Example of setting GEM_PATH
----
-import static org.asciidoctor.Asciidoctor.Factory.create;
+import static org.asciidoctor.jruby.AsciidoctorJRuby.Factory.create;
import org.asciidoctor.Asciidoctor;
Asciidoctor asciidoctor = create("/my/gem/path"); // <1>
@@ -959,16 +960,19 @@ import org.asciidoctor.Asciidoctor;
Asciidoctor asciidoctor = create();
----
-In an OSGi context it will not work because JRuby needs some paths to find the Asciidoctor gems. In order to make it work, you will need to specify the Asciidoctor gems path using the JavaEmbedUtils class. We will update the previous snippet of code to specify this path:
+In an OSGi context it will not work because JRuby needs some paths to find the Asciidoctor gems.
+In order to make it work, you will need to specify the Asciidoctor gems path using the JavaEmbedUtils class.
+We will update the previous snippet of code to specify this path:
[source,java]
----
-import static org.asciidoctor.Asciidoctor.Factory.create;
+import static org.asciidoctor.jruby.AsciidoctorJRuby.Factory.create;
import org.asciidoctor.Asciidoctor;
-Asciidoctor asciidoctor = create(Arrays.asList("uri:classloader:/gems/asciidoctor-1.5.8/lib")); <1><2>
+Asciidoctor asciidoctor = create(Arrays.asList("uri:classloader:/gems/asciidoctor-2.2.0/lib")); // <1><2>
----
-<1> `uri:classloader:/gems/asciidoctor-<version>/lib` specifies where the gems for Asciidoctor are located. Actually this path is located inside the `asciidoctorj-<version>.jar` file
+<1> `uri:classloader:/gems/asciidoctor-<version>/lib` specifies where the gems for Asciidoctor are located.
+ Actually this path is located inside the `asciidoctorj-<version>.jar` file
<2> The version here differs from the AsciidoctorJ version as it corresponds to the version of Asciidoctor, not the AsciidoctorJ one.
[NOTE]

MODIFY
asciidoctorj-documentation/src/main/asciidoc/integrator-guide.adoc
asciidoctorj-documentation/src/main/asciidoc/integrator-guide.adoc
@@ -136,22 +136,27 @@ include::src/test/java/org/asciidoctor/integrationguide/SimpleAsciidoctorRenderi
=== The Asciidoctor interface
The main entry point for AsciidoctorJ is the `Asciidoctor` Java interface.
-You obtain an instance from the factory class `Asciidoctor.Factory` that provides multiple overloaded create methods:
+You obtain an instance from the factory class `Asciidoctor.Factory` that provides a simple create method.
+
+If you need to get an instance of Asciidoctor using a certain gem path the factory `org.asciidoctor.jruby.AsciidoctorJRuby.Factory` provides multiple create methods to get an instance with a certain gem or load path:
.Methods to create an Asciidoctor instance
[cols="1m,2"]
|===
|Method Name | Description
-| create()
+| org.asciidoctor.Asciidoctor.Factory +
+.create()
| The default create method that is used most often.
Only use other methods if you want to load extensions that are not on the classpath.
-| create(String gemPath)
+| org.asciidoctor.jruby.AsciidoctorJRuby.Factory +
+.create(String gemPath)
| Creates a new Asciidoctor instance and sets the global variable `GEM_PATH` to the given String.
The variable `GEM_PATH` defines where Ruby looks for installed gems.
-| create(List<String> loadPaths)
+| org.asciidoctor.jruby.AsciidoctorJRuby.Factory +
+.create(List<String> loadPaths)
| Creates a new Asciidoctor instance and set the global variable `LOAD_PATH` to the given Strings.
The variable `LOAD_PATH` defines where Ruby looks for files.
@@ -166,7 +171,7 @@ include::src/test/java/org/asciidoctor/integrationguide/AsciidoctorInterface.jav
----
As Asciidoctor instances can be created they can also be explicitly destroyed to free resources used in particular by the Ruby runtime associated with it.
-Therefore the Asciidoctor interface offers the method destroy.
+Therefore the Asciidoctor interface offers the method shutdown.
After calling this method every other method call on the instance will fail!
[source,java,indent=0]
@@ -175,6 +180,16 @@ After calling this method every other method call on the instance will fail!
include::src/test/java/org/asciidoctor/integrationguide/AsciidoctorInterface.java[tags=shutdown]
----
+The Asciidoctor interface also implements the interface `java.io.AutoCloseable` which also shuts down the Ruby runtime.
+Therefore the previous example is equivalent to this:
+
+[source,java,indent=0]
+.Automatically destroying an Asciidoctor instance
+----
+include::src/test/java/org/asciidoctor/integrationguide/AsciidoctorInterface.java[tags=autoclose]
+----
+
+
To convert AsciiDoc documents the Asciidoctor interface provides four methods:
* `convert`

MODIFY
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/AsciidoctorInterface.java
asciidoctorj-documentation/src/test/java/org/asciidoctor/integrationguide/AsciidoctorInterface.java
package org.asciidoctor.integrationguide;
import org.asciidoctor.Asciidoctor;
+import org.asciidoctor.OptionsBuilder;
import org.junit.Test;
import java.io.File;
@@ -35,4 +36,13 @@ public class AsciidoctorInterface {
asciidoctor.shutdown();
//end::shutdown[]
}
+
+ @Test
+ public void autocloseAsciidoctorInstance() {
+//tag::autoclose[]
+ try (Asciidoctor asciidoctor = Asciidoctor.Factory.create()) {
+ asciidoctor.convert("Hello World", OptionsBuilder.options());
+ }
+//end::autoclose[]
+ }
}

MODIFY
docs/integrator-guide.adoc
docs/integrator-guide.adoc
@@ -154,22 +154,27 @@ public class SimpleAsciidoctorRendering {
=== The Asciidoctor interface
The main entry point for AsciidoctorJ is the `Asciidoctor` Java interface.
-You obtain an instance from the factory class `Asciidoctor.Factory` that provides multiple overloaded create methods:
+You obtain an instance from the factory class `Asciidoctor.Factory` that provides a simple create method.
+
+If you need to get an instance of Asciidoctor using a certain gem path the factory `org.asciidoctor.jruby.AsciidoctorJRuby.Factory` provides multiple create methods to get an instance with a certain gem or load path:
.Methods to create an Asciidoctor instance
[cols="1m,2"]
|===
|Method Name | Description
-| create()
+| org.asciidoctor.Asciidoctor.Factory +
+.create()
| The default create method that is used most often.
Only use other methods if you want to load extensions that are not on the classpath.
-| create(String gemPath)
+| org.asciidoctor.jruby.AsciidoctorJRuby.Factory +
+.create(String gemPath)
| Creates a new Asciidoctor instance and sets the global variable `GEM_PATH` to the given String.
The variable `GEM_PATH` defines where Ruby looks for installed gems.
-| create(List<String> loadPaths)
+| org.asciidoctor.jruby.AsciidoctorJRuby.Factory +
+.create(List<String> loadPaths)
| Creates a new Asciidoctor instance and set the global variable `LOAD_PATH` to the given Strings.
The variable `LOAD_PATH` defines where Ruby looks for files.
@@ -184,7 +189,7 @@ So most of the time you simply get an Asciidoctor instance like this:
----
As Asciidoctor instances can be created they can also be explicitly destroyed to free resources used in particular by the Ruby runtime associated with it.
-Therefore the Asciidoctor interface offers the method destroy.
+Therefore the Asciidoctor interface offers the method shutdown.
After calling this method every other method call on the instance will fail!
[source,java,indent=0]
@@ -194,6 +199,18 @@ After calling this method every other method call on the instance will fail!
asciidoctor.shutdown();
----
+The Asciidoctor interface also implements the interface `java.io.AutoCloseable` which also shuts down the Ruby runtime.
+Therefore the previous example is equivalent to this:
+
+[source,java,indent=0]
+.Automatically destroying an Asciidoctor instance
+----
+ try (Asciidoctor asciidoctor = Asciidoctor.Factory.create()) {
+ asciidoctor.convert("Hello World", OptionsBuilder.options());
+ }
+----
+
+
To convert AsciiDoc documents the Asciidoctor interface provides four methods:
* `convert`

Fix #890. Show how to create an Asciidoctor instance with GEM_PATH