Login  Register

Re: Link versus XRef

Posted by mojavelinux on Jun 11, 2013; 8:40pm
URL: https://discuss.asciidoctor.org/Re-Link-versus-XRef-tp327p334.html

Eric,

Your post triggered an idea in my mind about how to solve this.

As you pointed out, we actually have two use cases here:

1. Link to a standalone document
2. Link to section in the final document that is stored in source form in a separate document

The second use case has provided clarity for the first.

If you are willing to follow two conventions (one which is required anyway) we can make this work simply by modifying the backend templates (which make the HTML / DocBook). Here are those assumptions:

1. Section ids (and other anchors) are globally unique in the final document (Asciidoctor enforces this by appending counters if there is a conflict, but they need to be globally unique in the source documents for this to work cleanly)
2. The name of the document must match the id generated from the section title for any document that gets included in the master document (this is the default on GitHub anyway...don't worry about case, we can handle that)

Now, the reason this is going to work is because Asciidoctor builds a collection of all the ids in the document during parsing. Therefore, you can check if a cross reference is available in the final document. If so, we can make a xref link. If the id is not present, we assume we still have to link to the other document.

Here's how the syntax will work. First, the target of the link will be the AsciiDoc source document. We can recognize known AsciiDoc extensions to understand when we are dealing with this type of link in the renderer.

link:other-document.adoc[]

But that's not enough, because there may be a case when you want to link to the AsciiDoc document directly. So, we add one more requirement. You must specify an anchor on the target. If you want to reference the top-most heading, just append a hash:

link:other-document.adoc#[]

If you want to reference a section within that document:

link:other-document.adoc#example-section[]

Here are the rules for how the information from the macro is processed in the renderer.

1. Check if the target has a known AsciiDoc source extension (.ad, .adoc, .asciidoc, etc), then strip it from the target
2. If an anchor value is given (value after the hash), look for that id in the @document.references[:ids] table
2a. If found, create an cross-reference to that section /END
2b. If not found, use the target and anchor to create an external link to that document and section (e.g., <a href="other-document.html#example-section">...</a>) /END
3. If an anchor value is not given, look for the target in the @document.references[:ids] table
3a. If found, create a cross-reference to that section /END
3b. If not found, use the target to create an external link to the top of that document (e.g., <a href="other-document.html">...</a>)

Voila!

I'll follow up with an example to show how this will work. I just wanted to share that I had come up with a possible scenario.

NOTE: The tricky part is going to be making this work for links that have no file extension, like on the GitHub wiki. We could detect the 'wiki/' prefix, we could add an attribute to the link macro, or we can find some other way to hint to apply this logic.

-Dan


On Tue, Jun 11, 2013 at 2:06 AM, Eric Bottard [via Asciidoctor :: Discussion] <[hidden email]> wrote:
Hi, working with Gunnar on the very same issue.

The problem is even more complicated and I guess has been encountered by many, but I did not find a solution for it.
The thing is, we use several asciidoc documents included together to generate a full guide.

So basically, what we'd need is some macro that behaves like a link: when documents are separated, and like an xref (<<anchor>>) when they've been concatenated together.

At first, I thought about redefining the link: macro for the html and docbook backend to capture the anchor part (in link:document#anchor[Label]) together with the template for it (to render eg. Label in the html backend) but sadly, macro definitions don't seem to work in our toolchain (gradle plugin).

I'm curious, what is the usual solution to this, as I'm sure people have encountered that?

PS: One other option, and I guess I'll try that now, would be to rewrite links at the source level (ie. sed equivalent) before processing with asciidoctor.


If you reply to this email, your message will be added to the discussion below:
http://discuss.asciidoctor.org/Re-Link-versus-XRef-tp327p333.html
To start a new topic under Asciidoctor :: Discussion, email [hidden email]
To unsubscribe from Asciidoctor :: Discussion, click here.
NAML



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