Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Hi Sean,
AbstractBlock block = createBlock(parent, "literal", reader.readLines(), attributes, new HashMap<Object, Object>()); System.out.println(block.blocks()); for(AbstractBlock b : block.blocks()) { System.out.println("Block contents:"); System.out.println(b.content().toString()); } This assumes that the lines you pass to the new block get parsed. But Dan wrote above that they do not get parsed at the moment. So I fear that this approach does not work at the moment. But I think it should be possible to iterate over the child blocks of the original tabs block instead of creating a new block with the same string content and trying to get the child blocks from the new one. |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Ah, I misunderstood what he said above. Ok, I will give that a shot. Thank you!
|
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
I'm now trying to iterate over the child blocks of the parent, but I'm getting the following exception:
org.jruby.exceptions.RaiseException: (TypeError) exception class/object expected at RUBY.load(/Users/sean/.rvm/gems/ruby-2.2.1/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1362) at RUBY.convert(/Users/sean/.rvm/gems/ruby-2.2.1/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1458) at RUBY.convert_file(/Users/sean/.rvm/gems/ruby-2.2.1/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1562) at RUBY.convertFile(<script>:68) at org.jruby.gen.InterfaceImpl175252318.convertFile(org/jruby/gen/InterfaceImpl175252318.gen:13) It throws the exception as soon as I start iterating. I can successfully print out the content of the block, for what it's worth. Here's my code: @Override public Object process(AbstractBlock parent, Reader reader, Map<String, Object> attributes) { System.out.println(reader.read()); for(AbstractBlock b : parent.blocks()) { System.out.println("Block contents: ====================="); System.out.println(b.content().toString()); } . . . } |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
In reply to this post by sean.osterberg
Hi Sean,
This won't really help you, but just so you know I've also been working on adding tabs and collapsable accordions to my own document. I took the route of first hijacking some Slim templates and I'm now instead working on making a standalone Slim template. Thanks to a lot of help from Dan and others, I got things to work fairly well. However, at the moment my solution expects the content of the tabs or sections to be available in external files, not entered in-line within the document. This is very useful for me, but perhaps not always so for others. Also, I depend on a fair amount of metadata being passed as attributes which is not as clean as I'd like it to be. Your approach seems pretty good, too, so I'm looking forward to hearing about the outcome! Cheers! Sebastien |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Thanks Sebastien, is any of your code public for the Slim template? I would be interested in taking a look at it.
For our case, I really wanted to avoid having a separate file, but it does make a lot of sense for some cases. We're using external files for other use cases but not tabs, though maybe I'll have to consider that. Anyone have any other suggestions on how to process the child blocks? I've tried to get unblocked (no pun intended) but keep getting this exception. Thanks in advance! |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Administrator
|
On Mon, Jun 1, 2015 at 2:25 PM, sean.osterberg [via Asciidoctor :: Discussion] <[hidden email]> wrote: Anyone have any other suggestions on how to process the child blocks? I've tried to get unblocked (no pun intended) but keep getting this exception. As I mentioned, AsciidoctorJ currently doesn't expose the necessary interfaces to parse child blocks. However, it is possible to tap into the Ruby runtime to force the necessary methods to be invoked. Here's how that's done. First, define an interface for the Asciidoctor parser so that we can use the next_block method: public interface AsciiDocParser { Block nextBlock(Reader reader, AbstractBlock parent, Map<String, Object> attributes); } Next, in your block processor, define a field to hold an instance of the AsciiDocParser: private AsciiDocParser parser; then create an instance of the parser in the constructor so that it can be used in the process method. IRubyObject parserRubyClass = rubyRuntime.evalScriptlet("Asciidoctor::Parser"); this.parser = (AsciiDocParser) JavaEmbedUtils.rubyToJava(rubyRuntime, parserRubyClass, AsciiDocParser.class); Finally, you can use the parser to parse each block using the Reader instance that's passed to the process method: while (reader.hasMoreLines()) { Block child = parser.nextBlock(reader, parent, new HashMap<String, Object>()); } The final step is to attach the child blocks to a container block. For this, we have to tap into the Ruby runtime since the append method is missing from AbstractBlock. First, we create a container block. AbstractBlock container = createBlock(parent, "open", (String) null, inherited, new HashMap<Object, Object>()); Then, inside the above while loop, we append the to the container: while (reader.hasMoreLines()) { Block child = parser.nextBlock(reader, parent, new HashMap<String, Object>()); if (child != null) { JavaEmbedUtils.invokeMethod(rubyRuntime, container, "append", new Object[] { child }, Object.class); } } Here's what it looks like all together: public class SampleBlock extends BlockProcessor { private AsciiDocParser parser; private static Map<String, Object> CONFIG = new HashMap<String, Object>() {{ put("contexts", Arrays.asList(":open")); }}; public SampleBlock(String name, Map<String, Object> config) { super(name, CONFIG); IRubyObject parserRubyClass = rubyRuntime.evalScriptlet("Asciidoctor::Parser"); this.parser = (AsciiDocParser) JavaEmbedUtils.rubyToJava(rubyRuntime, parserRubyClass, AsciiDocParser.class); } @Override public Object process(AbstractBlock parent, Reader reader, Map<String, Object> attributes) { Map<String, Object> inherited = new HashMap<String, Object>(); // NOTE pass on any attributes you want to propagate //inherited.put("<key>", attributes.get("<key>")); AbstractBlock container = createBlock(parent, "open", (String) null, inherited, new HashMap<Object, Object>()); // parse all child blocks in the normal way while (reader.hasMoreLines()) { Block child = parser.nextBlock(reader, parent, new HashMap<String, Object>()); if (child != null) { // NOTE workaround missing append method on the AbstractBlock interface JavaEmbedUtils.invokeMethod(rubyRuntime, container, "append", new Object[] { child }, Object.class); } } return container; } } I hope that helps. I'll follow-up about changes we need to make in AsciidoctorJ to support this use case. |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Administrator
|
In reply to this post by sean.osterberg
Robert, As you can see from my previous message, we are missing two key methods in the AsciidoctorJ API. First, we need to add the append method to the AbstractBlock interface. This method allows child blocks to be added to a block. Second, we need to provide a way to parse child blocks. We talked about adding this feature to the createBlock method. I also think it's reasonable to add a method to AbstractBlock named either parseChildren() or parse(List<String>). In the first case, it would parse child blocks from the source lines passed to the block constructor. In the second case, it would parse blocks from an arbitrary set of lines and append them to the block as child nodes. I'm leaning more towards the second option. ...and of course, this would make a great test case. As a side note, I'm really looking forward to when we get the AST cleaned up in 1.6.0 because every time I use AsciidoctorJ right now to put together a sample, the lack of consistency in the AST drives me nuts. It always seems like the method I'm calling doesn't return the type I need or want. I know we're addressing that, so I'm very glad. Cheers, -Dan Dan Allen | http://google.com/profiles/dan.j.allen |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Administrator
|
In reply to this post by sean.osterberg
...and in case you're curious, I'm not sure we're ready yet to map the Parser API publicly. We'll just map it internally for right now and expose access to it's functionality. -Dan On Tue, Jun 2, 2015 at 4:31 PM, Dan Allen <[hidden email]> wrote:
... [show rest of quote] Dan Allen | http://google.com/profiles/dan.j.allen |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Just filed issues https://github.com/asciidoctor/asciidoctorj/issues/325 and https://github.com/asciidoctor/asciidoctorj/issues/326 to follow up on the open points.
|
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Administrator
|
Thanks Robert! As Robert pointed out in the first issue, it is possible to add child blocks to block already...so the hack to invoke the append method is unnecessary. container.getBlocks().add(child); Cheers, -Dan On Wed, Jun 3, 2015 at 12:40 AM, Robert.Panzer [via Asciidoctor :: Discussion] <[hidden email]> wrote: Just filed issues https://github.com/asciidoctor/asciidoctorj/issues/325 and https://github.com/asciidoctor/asciidoctorj/issues/326 to follow up on the open points. Dan Allen | http://google.com/profiles/dan.j.allen |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
This post was updated on Jun 03, 2015; 5:25pm.
In reply to this post by sean.osterberg
Hi Sean,
I haven't made my code available anywhere yet, but it's in the plan. In the meantime, I can you give the gist here. First, I created a new extension that I named bootstrap_extension.rb: require 'asciidoctor/extensions' Asciidoctor::Extensions.register do block do named :bootstrap on_contexts :paragraph,:open name_attributes 'component' process do |parent, reader, attrs| create_block parent, attrs['component'], reader.lines, attrs end end end Note that the "on_contexts" refers to both :paragraph and :open. I don't know what other contexts are available, so perhaps this could be improved. Note that at the moment, the content of the open block or paragraph is completely ignored. For a collapsable section, this could be easily changed so that it becomes the content (instead of an external file), but for a tab it would require more involved processing (a bit more on that later). Next, I make sure that this extension is used by the maven plugin by adding this tidbit to its <configuration>: <requires> <require>${project.basedir}/src/main/asciidoc/ext/bootstrap_extension.rb</require> </requires> Next, I created Slim templates for two of the Bootstrap components that I wanted to use, namely Tabs and Collapsable sections: ${project.basedir}/src/main/asciidoc/html5/navtabs.html.slim Code: ---- - if (attr? 'fileprefix') and (attr? 'filedir') and (attr? 'tabnames') and (attr? 'activetab') - tabs = (attr 'tabnames').split(",") ul id="bs-tab-#{attr 'id'}" class="nav nav-tabs" role="tablist" - tabs.each do |tab| - itemTarget = "#{attr 'id'}-#{tab.downcase}" - isTabActive = (tab == (attr 'activetab')) - itemClass = (isTabActive ? "active" : "") - tabStatus = (isTabActive ? "true" : "false") li role="presentation" class="#{itemClass}" a href="##{itemTarget}" id="#{itemTarget}-tab" role="tab" data-toggle="tab" aria-controls="#{itemTarget}" aria-expanded="#{tabStatus}" =tab div id="bs-content-#{attr 'id'}" class="tab-content" - tabs.each do |tab| - itemTarget = "#{attr 'id'}-#{tab.downcase}" - isTabActive = (tab == (attr 'activetab')) - tabClass = (isTabActive ? " active in" : "") div role="tabpanel" class="tab-pane fade#{tabClass}" id="#{itemTarget}" aria-labelledby="#{itemTarget}-tab" - filename = "#{attr 'filedir'}/#{attr 'fileprefix'}-#{tab}.adoc" - if (File.exist?(filename)) = Asciidoctor.convert(IO.read(filename), base_dir: @document.base_dir, safe: @document.safe) - else = filename + " not found" - else = "Missing configuration..." ---- ${project.basedir}/src/main/asciidoc/html5/collapse.html.slim Code: ---- - if (attr? 'id') and (attr? 'file') and (attr? 'title') div class='panel-group' id="bs-accordion-#{attr 'id'}" role="tablist" aria-multiselectable="true" div class="panel panel-default" div class="panel-heading" role="tab" id="bs-heading-#{attr 'id'}" a data-toggle="collapse" data-parent="#bs-accordion-#{attr 'id'}" href="#bs-collapse-#{attr 'id'}" aria-expanded="false" aria-controls="bs-collapse-#{attr 'id'}" = "#{attr 'title'}" div id="bs-collapse-#{attr 'id'}" class="panel-collapse collapse" role="tabpanel" aria-labelledby="bs-heading-#{attr 'id'}" div class="panel-body" - if (attr? 'file') - filename = "#{attr 'file'}" - if (File.file?(filename)) = Asciidoctor.convert(IO.read(filename), base_dir: @document.base_dir, safe: @document.safe) - else = filename + " does not exist" - else = "Missing some configuration..." ---- Next, I make the maven plugin aware of these templates by adding this to the <configuration> element: <templateDir>src/main/asciidoc/html5</templateDir> So the end result is that I can now use the following syntax to add a collapsable section or tabs: Collapsable section: [bootstrap,collapse, id="collapse1" title="Collapsable Section 1" file="{path_to_my_file}"] -- -- Tabs: [bootstrap,navtabs, id="getsub" filedir="{file_dir}" fileprefix="{file_prefix}" tabnames="JSON,XML" activetab="JSON"] -- -- IMPORTANT: this assumes that you've already included the Bootstrap CSS and JS dependencies to your document, as well as JQuery. If not, you can add those using the docinfo approach. Note that for the tab sections, I'm generating files like "http-request-JSON.adoc" and "http-request-XML.adoc" that are located in a common directory. This makes the file_dir to be that common directory, and the file prefix to be "http-request". As an aside, you might have noticed that I use some prefixes for the various IDs that are generated (ex: "bs-accordion-#{id}"). That's not necessary and is a bit of an artefact from previous incarnations that I ought to clean up. Disclaimer: I'm no expert in Ruby or Slim, so any improvement suggestions are most welcome. :) You might have also noticed that in my Slim templates the external files are being converted by Asciidoc. That's because those external files contain code that I want to have highlighted (or sometimes tables), so a typical file would contain something like this: [source,http,options="nowrap"] ---- PUT http://localhost:8080/some/relevant/path HTTP/1.1 Accept: application/json User-Agent: Apache-HttpClient/4.3.6 (java 1.5) Host: localhost:8080 Content-Length: <content_length> Proxy-Connection: Keep-Alive Content-Type: application/json; charset=UTF-8 { "key1": "value1", "key2": "value2" } ---- It could be useful to somehow move the configuration of the tabs into the block itself. Other than parsing the contents itself manually, I don't know how to do it. However, I just saw Dan's post about child blocks so perhaps I could piggy back on that approach. Other things that I'd like to improve is to cap the size of various panels so that a vertical scrollbar is made available instead of having my code eat up a lot of space. I've had weird results up to now (the horizontal scrollbar introduced by the "nowrap" option on the listing block only shows up when you've completed scrolled vertically to the end of the block). It might be nice to have a "maxlines" or something similar that would natively be available in the "options" of a listing block. Finally, BIG thanks to Dan and the community for helping me with this. I'm standing on the shoulders of giants. :) I hope that can be of help to you! Cheers, Sebastien |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
In reply to this post by mojavelinux
Thank you Dan, that mini-tutorial worked great and I've got everything working as expected.
The only issue I'm running into is that I'll get a warning displayed every time one of the child blocks is processed. Specifically: asciidoctor: WARNING: doc-test.adoc: line 8: invalid style for literal block: tab A reminder that the syntax I'm using is as follows: [tabs] ------ [tab,title="foo"] .... content goes here .... [tab,title="bar"] .... content goes here .... ------ Also, to close the loop on my tab implementation -- I'd really like to do block processing in the same manner for the Atom Asciidoctor Previewer that uses Asciidoctor.js. Is it possible to do block processing in the same manner for Asciidoctor.js and to display tabs in the previewer, assuming I can also inject my own CSS? Thanks a bunch, Sean |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
In reply to this post by torngat
Thank you Sebastien, I'm giving this a shot as well. I think you came up with a novel solution to the same problem, which probably looks a lot better when you have a really long tab section like we have in our documentation. For really long tabs it makes more sense to pull in from an external file. I'm investigating a mix of your solution with my own -- we'll see.
|
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Hi guys, I could use some more help. I'm having new trouble with my block processor -- it fails seemingly randomly on certain files with my tab syntax. The files are using the syntax just fine. In fact, I've used the same file contents and created many files with the same contents, and it will succeed on some of the files and then fail on others. There's no clear pattern of failure to help me debug.
I get the following error: org.jruby.exceptions.RaiseException: (TypeError) exception class/object expected at RUBY.load(/Users/user/.rvm/gems/ruby-2.2.1/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1362) at RUBY.convert(/Users/user/.rvm/gems/ruby-2.2.1/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1458) at RUBY.convert_file(/Users/user/.rvm/gems/ruby-2.2.1/gems/asciidoctor-1.5.2/lib/asciidoctor.rb:1562) at RUBY.convertFile(<script>:68) at org.jruby.gen.InterfaceImpl1177483828.convertFile(org/jruby/gen/InterfaceImpl1177483828.gen:13) Here's the ugly code I wrote to get things working and haven't yet refactored. Any help would be greatly appreciated! public class TabProcessor extends BlockProcessor { private AsciiDocParser parser; private AsciiDocProcessor processor; private static Map<String, Object> CONFIG = new HashMap<String, Object>() {{ put("contexts", Arrays.asList(":listing")); put("content_model", ":compound"); }}; public TabProcessor(String name, Map<String, Object> config) { super(name, CONFIG); IRubyObject parserRubyClass = rubyRuntime.evalScriptlet("Asciidoctor::Parser"); processor = AsciiDocProcessor.getProcessorInstance(); this.parser = (AsciiDocParser) JavaEmbedUtils.rubyToJava(rubyRuntime, parserRubyClass, AsciiDocParser.class); } @Override public Object process(AbstractBlock parent, Reader reader, Map<String, Object> attributes) { Map<String, Object> inherited = new HashMap<String, Object>(); AbstractBlock container = createBlock(parent, "open", (String)null, inherited, new HashMap<Object, Object>()); Map<String, String> titleAndId = new LinkedHashMap<String, String>(); int count = 0; while (reader.hasMoreLines()) { Block child = parser.nextBlock(reader, parent, new HashMap<String, Object>()); if (child != null) { String tabTitle = child.title(); String uniqueId = Utilities.cleanPageFileNames(tabTitle) + "-" + Utilities.getRandomAlphaNumericString(5); titleAndId.put(tabTitle, uniqueId); String singleTabHtmlOpen; if(count == 0) { singleTabHtmlOpen = "<div class=\"tab-pane in active fade no-padding\" id=\"" + uniqueId + "\">"; } else { singleTabHtmlOpen = "<div class=\"tab-pane fade no-padding\" id=\"" + uniqueId + "\">"; } String converted = processor.convertAsciiDocString(child.content().toString()); converted = Utilities.getOnlyContentDivFromHtml(converted); converted = singleTabHtmlOpen + converted + "</div>"; Block block = createBlock(parent, "pass", converted, inherited, new HashMap<Object, Object>()); count++; container.blocks().add(block); } } String tabsOpen = "<div class=\"panel panel-default no-padding\">\n" + " <div class=\"panel-heading no-padding\">\n" + " <!-- Nav tabs -->\n" + " <ul class=\"nav nav-tabs\" role=\"tablist\">\n"; List<Map.Entry<String,String>> randAccess = new ArrayList<Map.Entry<String,String>>(titleAndId.entrySet()); for(int i = 0; i < titleAndId.size(); i++) { if(i == 0) { tabsOpen += "<li class=\"active\">"; tabsOpen += "<a href=\"#" + randAccess.get(i).getValue() + "\" role=\"tab\" data-toggle=\"tab\">" + randAccess.get(i).getKey() + "</a></li>\n"; } else { tabsOpen += "<li><a href=\"#" + randAccess.get(i).getValue() + "\" role=\"tab\" data-toggle=\"tab\">" + randAccess.get(i).getKey() + "</a></li>\n"; } } tabsOpen += "</ul>\n</div>\n<div class=\"panel-body tab-content no-padding\">"; String tabsClose = "</div></div>"; String containerContents = tabsOpen + container.content().toString() + tabsClose; AbstractBlock containerNew = createBlock(parent, "pass", containerContents, inherited, new HashMap<Object, Object>()); container = containerNew; return container; } } |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Administrator
|
On Tue, Jul 21, 2015 at 6:55 PM, sean.osterberg [via Asciidoctor :: Discussion] <[hidden email]> wrote:
This stacktrace is probably the biggest hole in Asciidoctor 1.5.2 that we've resolved in the upcoming 1.5.3. The problem is that the real information is completely lost because core swallows the cause, so the error could literally be anything. Unfortunately, it's really hard to work around this problem since the gem is bundled in the jar so you can't just change the file. What I usually recommend is installing Asciidoctor (dev) locally (using gem install), then set the gemPath that you pass to Asciidoctor.Factory.create() to the location of the locally installed gems. Then, you can hack on the gem files directly...and apply this fix: https://github.com/asciidoctor/asciidoctor/commit/e16c015f7203c1dd86435e921dffb3a701741b37 As for errors with extensions, I'm noticing something similar. It seems like if you touch certain objects in the AST from the Java side, the converter fails to run for one reason or another. I'm going to file an issue about this so that we can track what's going on. I'm not sure if you are hitting the same issue, but I have noticed various places where this happens. Cheers, |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Thanks Dan, I'll try that workaround and see where it leads me.
|
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Administrator
|
Sean, I'll also mention that it's very possible the underlying problem is addressed in AsciidoctorJ 1.6.0 snapshot. Robert has fundamentally changed the way the AST gets mapped to the Ruby objects to achieve a cleaner and smoother integration. I plan to experiment with it myself to try to find out if the problem I'm seeing is still present or whether Robert's changes eliminated the issue. One thing is for certain. To do advanced-level extensions in AsciidoctorJ (Java or Groovy), it isn't going to work well with 1.5.2. We've learned a ton from the 1.5.2 code base and therefore can look forward to a much better integration in 1.6.0. Stay tuned for news about the 1.5.3 release, which should at least take care of the swallowing exception problem. Cheers, -Dan On Wed, Jul 22, 2015 at 8:42 AM, sean.osterberg [via Asciidoctor :: Discussion] <[hidden email]> wrote: Thanks Dan, I'll try that workaround and see where it leads me. Dan Allen | http://google.com/profiles/dan.j.allen |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Sean, If you send me the sources of extension I'd happily test it against AsciidoctorJ 1.6.0. I'm greedy for code that tests AsciidoctorJ:) You can send it to Robert . Panzer at me . com Robert
... [show rest of quote]
|
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
This post was updated on Jul 24, 2015; 3:38am.
Thanks Dan and Robert.
Is it possible for me to get the AsciidoctorJ 1.6.0 snapshot? Robert, I sent you the code files and an example file. I'm eager to hear if it's resolved in 1.6, because I'm going to have to figure out a workaround for the time being. Thanks, Sean |
Loading... |
Reply to author |
Edit post |
Move post |
Delete this post |
Delete this post and replies |
Change post date |
Print post |
Permalink |
Raw mail |
Hi Sean,
I just tried your example with AsciidoctorJ 1.5.2 and it ... worked on my computer! I am a actually a little bit surprised myself. I am responding here because your example very nicely shows where we still have some gaps for 1.6.0 that we have to fill. First you are using the Ruby runtime inside the processor. Independent of whether we can provide an API for your concrete problem I think there will always be some point where the user requires the Ruby runtime because we have no solution yet in the product. Therefore I filed https://github.com/asciidoctor/asciidoctorj/issues/364 Second point is you are using the Ruby runtime to get a wrapper around the Asciidoctor parser. We already have an issue https://github.com/asciidoctor/asciidoctorj/issues/326 and a PR https://github.com/asciidoctor/asciidoctorj/pull/337 for that. I think the PR would work for that, so that you'd no longer need to wrap the Parser yourself. Actually your approach would no longer with AsciidoctorJ 1.6.0 though! The point is that the Parser object wrapped by JRuby will produce JRuby's own proxy objects which have some drawbacks. For example that the `parse()` method will really always return a Block and not a Section if the Block was a Section. (To be pedantic the parse method should have returned an AbstractBlock, but then JRuby would really give you only an AbstractBlock and not a Block. That was the reason why we stepped back from this approach in 1.6.0 and now use an explicit mapping between JRuby and Java nodes.) But as I said above, the PR would help you with that one. I am super happy that I could have a look at your sources. Unfortunately I could not reproduce your problem, maybe you can get the full error message with Dan's hint. Best regards Robert |
Free forum by Nabble | Edit this page |