Understanding include directive and file path

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

Understanding include directive and file path

Jeremie Bresson
This post was updated on .

Imagine a repository like that:

  • docs/

    • main.adoc

    • inc/

      • section1.adoc

      • section2.adoc

  • src/

    • main/

      • java/

        • Asciidoctor.java

        • Main.java

I am trying to apply the pattern described in the user manual:

:sourcedir: src/main/java

[source,java]
----
include::{sourcedir}/Asciidoctor.java[]
----

Now imagine I want to define sourcedir in main.adoc and in section1.adoc.

In the main.adoc case it will be:

:sourcedir: ../src/main/java

In the section1.adoc case it will be:

:sourcedir: ../../src/main/java

Working like that, allows me to move some content from main.adoc to section1.adoc without having to think about the sourcedir value (initialized correctly in both documents).

This works great when I preview each section file separately or if the main.adoc document do not use sourcedir.

The problems comes when I try to preview/build the main.adoc document (using sourcedir everywhere). My understanding is that the include:: directive works relative to the current Asciidoc file.

This is what is written in the user manual:

Files included in the master (top-level) document are resolved relative to the base directory, which defaults to the directory of the master document unless otherwise specified. Files included inside a file which itself has been included are resolved relative to the current document.

How is this typically solved? I can imagine two solutions:

1/ having an option to tells that all the path are defined relative to the main.doc Asciidoc file or relative to something else (for example to root of my git repository). This would be true for all my documents: in the main.doc file and in the included section files.

2/ having a possibility to redefine the sourcedir variable in the section1.adoc but with a scope equals to this document. Meaning that when the engine is done with importing section1.adoc and comes back in main.doc the value of sourcedir defined in section1.adoc is reverted to the value defined in main.adoc.

I would really appreciate help to understand this. (I have seen other discussion on this mailing list, but I did not understand the solution).

I am ready to share this demo setup if necessary.

Thank you in advance.

Reply | Threaded
Open this post in threaded view
|

Re: Understanding include directive and file path

mojavelinux
Administrator
Jeremie,

You've identified a case in which the recommendation in the user manual breaks down. In other words, this case wasn't considered.

1/
One way to solve this problem is to use an absolute (qualified) path for the sourcedir when converting from the top-level. This is how it's usually solved by people using Maven and Gradle projects. If you pass the value to the API, any value in the include documents will be ignored, so you can still use the relative value for standalone documents and it will be overridden.

2a/
Although crude, another way you could solve this today is to wrap the assignment around the include directive.

----
= Document Title
:sourcedir: src/main/java
:sourcedir-root: {sourcedir}

:sourcedir: ../src/main/java

include::inc/section1.adoc[]

:sourcedir: {sourcedir-root}
----

2b/
This can be made less crude by implementing a custom IncludeProcessor that automatically adds these declarations. We do something similar internally to make the leveloffset defined in the include directive scoped to the include. See https://github.com/asciidoctor/asciidoctor/blob/master/lib/asciidoctor/reader.rb#L1040-L1051.

It's important to note that the include directive is not a sub-document. Therefore, it doesn't really have a scope. There's been a lot of discussion about having a subdoc directive or macro that can see the include as a standalone document and add features such as this. See https://github.com/asciidoctor/asciidoctor/issues/894.

I think we need to document (1) in the user manual. wdyt?

-Dan

On Thu, May 7, 2015 at 10:47 AM, Jeremie Bresson [via Asciidoctor :: Discussion] <[hidden email]> wrote:

Imagine a repository like that:

  • docs/

    • main.adoc

    • inc/

      • section1.adoc

      • section2.adoc

  • src/

    • main/

      • java/

        • Asciidoctor.java

        • Main.java

I am trying to apply the pattern described in the user manual:

:sourcedir: src/main/java

[source,java]
----
include::{sourcedir}/Asciidoctor.java[]
----

Now imagine I want to define sourcedir in main.adoc and in section1.adoc.

In the main.adoc case it will be:

:sourcedir: src/main/java

In the section1.adoc case it will be:

:sourcedir: ../src/main/java

Working like that, allows me to move some content from main.adoc to section1.adoc without having to think about the sourcedir value (initialized correctly in both documents).

This works great when I preview each section file separately or if the main.adoc document do not use sourcedir.

The problems comes when I try to preview/build the main.adoc document (using sourcedir everywhere). My understanding is that the include:: directive works relative to the current Asciidoc file.

This is what is written in the user manual:

Files included in the master (top-level) document are resolved relative to the base directory, which defaults to the directory of the master document unless otherwise specified. Files included inside a file which itself has been included are resolved relative to the current document.

How is this typically solved? I can imagine two solutions:

1/ having an option to tells that all the path are defined relative to the main.doc Asciidoc file or relative to something else (for example to root of my git repository). This would be true for all my documents: in the main.doc file and in the included section files.

2/ having a possibility to redefine the sourcedir variable in the section1.adoc but with a scope equals to this document. Meaning that when the engine is done with importing section1.adoc and comes back in main.doc the value of sourcedir defined in section1.adoc is reverted to the value defined in main.adoc.

I would really appreciate help to understand this. (I have seen other discussion on this mailing list, but I did not understand the solution).

I am ready to share this demo setup if necessary.

Thank you in advance.




If you reply to this email, your message will be added to the discussion below:
http://discuss.asciidoctor.org/Understanding-include-directive-and-file-path-tp3137.html
To start a new topic under Asciidoctor :: Discussion, email [hidden email]
To unsubscribe from Asciidoctor :: Discussion, click here.
NAML



--
Reply | Threaded
Open this post in threaded view
|

Re: Understanding include directive and file path

Jeremie Bresson
Thank you for your answer. It is what I have expected, even if I had the hope to get a better solution.

---

I have experimented with the maven build on your solution (1).

I was not aware that variable set in the pom.xml cannot be overridden in the document. In my eyes this is also a kind of scope.

Yes information for (1) is missing in the user-manual, because it is an interesting pattern.

---

With solutions (1) and (2b), if I understand you correctly, this will not work with the “chrome-preview-plugin”. This was identified as an important feature by our team.
I recognize that the preview function will most likely not be used to preview the main document with all the include directives but only to preview sub-documents (in particular the one you are working on).

At the end it is a tradeoff… My understanding is that I will not manage to get everything with the current version of Asciidoctor.

---

You have answered for the "scope" part of my question (described as solution "2/" in my post).
The discussion is really interesting.

I would also be fine with my solution "1/":

Having a possibility to define an attribute "rootdir":
* If not set, the behavior is exactly the one we know today (include resolved relative to the current document).
* If set: all includes are defined relative to this root. No matter where I am. In all my document I start with "ifndef::rootdir[:rootdir: ../..]"
This way all my include directives would be relative to this root. In this case I would have the same value of sourcedir in each of my documents, because the path to the document to be included would be prefixed with rootdir.

The example: include::{sourcedir}/Asciidoctor.java[]

Would correspond to: “{rootdir} + path”, which is in this case: “{rootdir} + {sourcedir} + Asciidoctor.java”

Reply | Threaded
Open this post in threaded view
|

Re: Understanding include directive and file path

mojavelinux
Administrator

On Tue, May 12, 2015 at 12:14 AM, Jeremie Bresson [via Asciidoctor :: Discussion] <[hidden email]> wrote:
I was not aware that variable set in the pom.xml cannot be overridden in the document. In my eyes this is also a kind of scope.

Just to clarify, if you put a @ at the end of the value, then the document can still override it. See http://asciidoctor.org/docs/user-manual/#attribute-assignment-precedence

Reply | Threaded
Open this post in threaded view
|

Re: Understanding include directive and file path

mojavelinux
Administrator
In reply to this post by Jeremie Bresson

On Tue, May 12, 2015 at 12:14 AM, Jeremie Bresson [via Asciidoctor :: Discussion] <[hidden email]> wrote:
At the end it is a tradeoff… My understanding is that I will not manage to get everything with the current version of Asciidoctor.

We're trying to balance it all, but we're still playing that balance game right now to get it all working :)

Being able to pass attributes through the URL to the Chrome extension may solve this issue...though you'd likely need to bookmark the URL so that you don't have to type it every time. See https://github.com/asciidoctor/asciidoctor-chrome-extension/pull/103