Asciidoctor Java Integration with Extension (this is only a sandbox but it works!!!)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Asciidoctor Java Integration with Extension (this is only a sandbox but it works!!!)

asotobu
Hello today I have started with the implementation of extensions for Asciidoctor Java Integration, and it works I have been able to register Ruby Preprocessor extension classes and Java Preprocessor extension classes, so you can implement extensions in Ruby or Java and register them from Java. Only two warnings:

First: this is a sandbox, the code I have implemented is horrible I know but it was to know that it was possible and see how JRuby deals with extensions. You can take a look at https://github.com/asciidoctor/asciidoctor-java-integration/tree/extension/src/test/java/org/asciidoctor/extension and please remember there is only a test with only preprocessors in a direct way, this will be changed in future.

Second: there is one small problem and is that when we use a java class as extension because we should import them dynamically inside JRuby using java_import method, that's a problem because each time a new extension is registered I should execute a Ruby script (not a big problem but can affect in performance). I  have tried by using java full qualified name, but I don't know why, but a Ruby exception is thrown.

Well now I am going to start working with final solution, first of all mapping some classes to Java like Preprocessor, TreeProcessor, Document, ... and so on. And then one question how do you think we should look the public interface of Asciidoctor to register extensions? Inspecting examples provided by Dan at http://asciidoctor.org/news/#extensions

where for example a Preprocessor is registered as:

Asciidoctor::Extensions.register do |document|
  preprocessor FrontMatterPreprocessor
end


or

Asciidoctor::Extensions.register do |document|
  treeprocessor TerminalCommandTreeprocessor
end


you prefer a methods like
registerPreprocessor(Class<? extends PreProcessor> preprocessor)
registerTreeProcessor(Class<? extends TreeProcessor> treeProcessor)

and for ruby extensions

registerPreprocessor(String preprocessor)
registerTreeProcessor(String treeProcessor)

and offer a DSL way to register as many as processors as you want,

Extensions.preprocessor(MyPreprocessor.class).preprocessor(MySecondPreprocessor.class).treeprocessor(MyTreeProcessor).

and then internally calling the previous methods, but also offering users the possibility to call them manually (public methods).

Or you prefer a more closed approach where you can only register processors using the DSL, more like:

Extensions.preprocessor(MyPreprocessor.class).preprocessor(MySecondPreprocessor.class).treeprocessor(MyTreeProcessor). but users could not deal with registerPreProcessor methods.


Alex.
Reply | Threaded
Open this post in threaded view
|

Re: Asciidoctor Java Integration with Extension (this is only a sandbox but it works!!!)

mojavelinux
Administrator
Alex,

Amazing work!

I finally had an opportunity to dig into the code and I'm so impressed by the depth of the integration. It's amazing to think that Java is invoking Ruby code, Java is manipulating Ruby objects, Ruby is working with Java objects and Java is creating Ruby objects that are populated in Java and passed to Ruby. It's kind of mindblowing, actually :)

I think what you have is an excellent start. As I stated very explicitly in the 0.1.4 release notes, the extensions are highly experimental in this release. I think that gives us opportunity to use this AJI release as a way to test the waters as well. In fact, we _want_ some rough edges so it encourages people to provide suggestions for API improvements.

As for the extension APIs themselves, the only sharp edge that really stands out for me is the RubyDocument type. That's an internal class that's being exposed through the extension API. I'd really like to see if we can converge that into a single Document object.

I like both of your approaches to registration that you are suggesting below. We could put both of them out there as "proposed" and see what people feel is more natural. We'll just cut one of them if no one finds it of any use.

Again, great work! This is an amazing start to providing full extension capabilities from the Java side! Wow.

-Dan


On Sun, Sep 15, 2013 at 5:51 AM, asotobu [via Asciidoctor :: Discussion] <[hidden email]> wrote:
Hello today I have started with the implementation of extensions for Asciidoctor Java Integration, and it works I have been able to register Ruby Preprocessor extension classes and Java Preprocessor extension classes, so you can implement extensions in Ruby or Java and register them from Java. Only two warnings:

First: this is a sandbox, the code I have implemented is horrible I know but it was to know that it was possible and see how JRuby deals with extensions. You can take a look at https://github.com/asciidoctor/asciidoctor-java-integration/tree/extension/src/test/java/org/asciidoctor/extension and please remember there is only a test with only preprocessors in a direct way, this will be changed in future.

Second: there is one small problem and is that when we use a java class as extension because we should import them dynamically inside JRuby using java_import method, that's a problem because each time a new extension is registered I should execute a Ruby script (not a big problem but can affect in performance). I  have tried by using java full qualified name, but I don't know why, but a Ruby exception is thrown.

Well now I am going to start working with final solution, first of all mapping some classes to Java like Preprocessor, TreeProcessor, Document, ... and so on. And then one question how do you think we should look the public interface of Asciidoctor to register extensions? Inspecting examples provided by Dan at http://asciidoctor.org/news/#extensions

where for example a Preprocessor is registered as:

Asciidoctor::Extensions.register do |document|
  preprocessor FrontMatterPreprocessor
end


or

Asciidoctor::Extensions.register do |document|
  treeprocessor TerminalCommandTreeprocessor
end


you prefer a methods like
registerPreprocessor(Class<? extends PreProcessor> preprocessor)
registerTreeProcessor(Class<? extends TreeProcessor> treeProcessor)

and for ruby extensions

registerPreprocessor(String preprocessor)
registerTreeProcessor(String treeProcessor)

and offer a DSL way to register as many as processors as you want,

Extensions.preprocessor(MyPreprocessor.class).preprocessor(MySecondPreprocessor.class).treeprocessor(MyTreeProcessor).

and then internally calling the previous methods, but also offering users the possibility to call them manually (public methods).

Or you prefer a more closed approach where you can only register processors using the DSL, more like:

Extensions.preprocessor(MyPreprocessor.class).preprocessor(MySecondPreprocessor.class).treeprocessor(MyTreeProcessor). but users could not deal with registerPreProcessor methods.


Alex.



If you reply to this email, your message will be added to the discussion below:
http://discuss.asciidoctor.org/Asciidoctor-Java-Integration-with-Extension-this-is-only-a-sandbox-but-it-works-tp618.html
To start a new topic under Asciidoctor :: Discussion, email [hidden email]
To unsubscribe from Asciidoctor :: Discussion, click here.
NAML



--