Create extension to embed source code

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

Create extension to embed source code

bodiam
Hi all,

I'm trying to write a small extension, but even after reading quite some documentation, I still have no idea what the difference is between createInline and createBlock, and I'm not sure if I'm doing things right here.

The 'problem' I have is that I have a lot of code like this:

[source, scala]
.Sample1.scala
----
include::{rootdir}/src/main/scala/samples/flatmap/Sample1.scala[tags=helloMethod]
----

That's 5 lines every time, plus there's duplication. So, I'd like to get of rid of that, and I was hoping I could do the same thing with creating a macro or extension like this:

source::flatmap/Sample1.scala[tags=helloMethod]

And be done. But I have no idea how write the code for this. I currently have the following code:

    // Here we can add the code for extensions we write.
    extensions {

        // Implementation for inline macro to replace
        // source:flatmap/Sample1[tag=helloMethod] with a link to the issue.
        inlinemacro (name: "source") { parent, target, attributes ->

            options = [
                "type": ":link",
                "target": "http://issue-server/browse/${target}".toString()
            ]

            // Create the link to the issue.
            createBlock(parent, "anchor", target, attributes, options).render()
        }
    }

but that doesn't do anything yet, it's based on:
http://blog.jdriven.com/2015/03/awesome-asciidoctor-use-inline-extension-dsl-with-gradle/
and
https://github.com/asciidoctor/asciidoctorj-groovy-dsl

Can anyone help me out, or point me in the right direction? Thanks!

Erik
Reply | Threaded
Open this post in threaded view
|

Re: Create extension to embed source code

LightGuardjp
I've not written one in the gradle script, but what you'll want is certainly a block and not inline. Think of a block as an HTML div and inline like a span. If what you're creating for the asciidoc output (not final output) is a child of something else it's an inline macro. If it lives on its own then it's a block macro. 

On Monday, August 10, 2015, bodiam [via Asciidoctor :: Discussion] <[hidden email]> wrote:
Hi all,

I'm trying to write a small extension, but even after reading quite some documentation, I still have no idea what the difference is between createInline and createBlock, and I'm not sure if I'm doing things right here.

The 'problem' I have is that I have a lot of code like this:

[source, scala]
.Sample1.scala
----
include::{rootdir}/src/main/scala/samples/flatmap/Sample1.scala[tags=helloMethod]
----

That's 5 lines every time, plus there's duplication. So, I'd like to get of rid of that, and I was hoping I could do the same thing with creating a macro or extension like this:

source::flatmap/Sample1.scala[tags=helloMethod]

And be done. But I have no idea how write the code for this. I currently have the following code:

    // Here we can add the code for extensions we write.
    extensions {

        // Implementation for inline macro to replace
        // source:flatmap/Sample1[tag=helloMethod] with a link to the issue.
        inlinemacro (name: "source") { parent, target, attributes ->

            options = [
                "type": ":link",
                "target": "http://issue-server/browse/${target}".toString()
            ]

            // Create the link to the issue.
            createBlock(parent, "anchor", target, attributes, options).render()
        }
    }

but that doesn't do anything yet, it's based on:
http://blog.jdriven.com/2015/03/awesome-asciidoctor-use-inline-extension-dsl-with-gradle/
and
https://github.com/asciidoctor/asciidoctorj-groovy-dsl

Can anyone help me out, or point me in the right direction? Thanks!

Erik


If you reply to this email, your message will be added to the discussion below:
http://discuss.asciidoctor.org/Create-extension-to-embed-source-code-tp3645.html
To start a new topic under Asciidoctor :: Discussion, email <a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;ml-node%2Bs49171n1h37@n6.nabble.com&#39;);" target="_blank">ml-node+s49171n1h37@...
To unsubscribe from Asciidoctor :: Discussion, click here.
NAML


--
Sent from Gmail Mobile
Reply | Threaded
Open this post in threaded view
|

Re: Create extension to embed source code

abelsromero
In reply to this post by bodiam
Right now, the documentation about extesions is not as good as it should be, you usually have to look for info in many places and look into the code.
On this thread you'll find some more links about how to create a extension. Specially, this links contains information you'll need https://github.com/asciidoctor/asciidoctor-documentation/issues/30.
Reply | Threaded
Open this post in threaded view
|

Re: Create extension to embed source code

bodiam
Thank you both for the information. I've read it, but it unfortunately doesn't make it that much clearer to me. Why do I have to create a block extension? Block extensions sound like something like the following:

[my-custom-extension]
----
content here
----

But that's not what I want. I want:

my-custom-extension::doSomething[withOptions]

Isn't that an inline extension? Does anyone have maybe some examples available? The documentation here is also limited: https://github.com/asciidoctor/asciidoctor-gradle-plugin, and I'm just looking for something which allows me to grasp what I'm doing :-)
Reply | Threaded
Open this post in threaded view
|

Re: Create extension to embed source code

abelsromero
Hi,

I’ve been doing some tests and I think I can shed some light on this case. Not the final solution though, but we can work together on it.

First of all, there is no special reason to use inline extension or block extension. Maybe, for simplicity, since you want to insert a block, it’s better to use another block as a reference.
Aswering you last question, note that this two lines are not the same:
  my-custom-extension::doSomething[withOptions] --> Note the double colons. This is a block is using a short notation to define a block. See http://asciidoctor.org/docs/user-manual/#role (Shorthand Asciidoctor block syntax)
  my-custom-extension:doSomething[withOptions] --> This is an inline macro


Now, back to the extension, I don’t think any of those extensions will work. As described in the manual http://asciidoctor.org/docs/user-manual/#include-directive
Include directives are handled by the preprocessor, so they are oblivious to the structure of the document. They are primarily just a file merger, with one exception. The include directives can resolve document-level attributes.
Even if you could insert the “include” directive, it won’t work because the content will not be fetched. As I understand includes must be dealt within a Preprocessor or IncludePreprocessor extension.
Both extensions allow to parse the text through a PreprocessorReader, which contains the method ‘push_include’.
void push_include(String data, String file, String path, int lineNumber, Map<String, Object> attributes);
‘data’ is basically a string containing the text to include and ‘lineNumber’ is the original line to replace.
You could iterate over the document reading line by line (and counting the line), check if it begins by ‘my-custom-extension’, then retrieve the content, and finally add the source block header/footer.

Here is a example of Preprocessor that shows how to manualy include some content: https://github.com/asciidoctor/asciidoctorj/blob/asciidoctorj-1.6.0/asciidoctorj-core/src/test/java/org/asciidoctor/extension/WhenJavaExtensionIsRegistered.java#L127-L185
Reply | Threaded
Open this post in threaded view
|

Re: Create extension to embed source code

mojavelinux
Administrator

there is no special reason to use inline extension or block extension

There is a huge difference, in fact. It's exactly the same as the difference between a span and a div in html. An inline extension is for a macro in the middle of a sentence, whereas a block stands by itself as its own...block.

In your case, you want a block macro extension.

I've been discussing with Robert about putting a source block macro in AsciidoctorJ by default to solve exactly the problem you are observing...to simplify the source listing coming from an external file (the most common case in mature documentation). I've always envisioned that this would one day become a built-in block because its so clear we could cut down on the number of lines we are currently typing.

Refer to this list to find extensions written in AsciidoctorJ: http://asciidoctor.org/docs/extensions/#third-party-extensions

Cheers,

-Dan

--
Dan Allen | @mojavelinux | http://google.com/profiles/dan.j.allen