Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cross-document links without anchor become wrong on include #3596

Open
Vampire opened this issue Mar 13, 2020 · 9 comments
Open

cross-document links without anchor become wrong on include #3596

Vampire opened this issue Mar 13, 2020 · 9 comments
Assignees
Milestone

Comments

@Vampire
Copy link

Vampire commented Mar 13, 2020

For the Spock documentation at https://github.com/spockframework/spock/tree/spock-1.3/docs, there is one adoc file per chapter and one all_in_one.adoc file that aggregates them into a one-page doc.

Difference can be seen in http://spockframework.org/spock/docs/1.3/ vs. http://spockframework.org/spock/docs/1.3/all_in_one.html.

The problem is, there are some dead links in the one-page version where top level of other documents are referenced.
If you for example go to http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_explicit_interaction_blocks, there is a link to Data Driven Testing that is defined in interaction_based_testing.adoc as <<data_driven_testing.adoc#,Data Driven Testing>>.
This works perfectly fine for the multi-page version.
But in the one-page version at http://spockframework.org/spock/docs/1.3/all_in_one.html#_explicit_interaction_blocks you can see, that the same link just links to # on the same page.

So if such a doc is included that contains a cross-document link without anchor, this should probably better be rendered as the anchor that is created only if the document is included, but not if it is rendered stand-alone.

Workaround: Manually define an anchor at the top section title of the document like = [[data-driven-testing]]Data Driven Testing and then make the link point to that anchor point with <<data_driven_testing.adoc#data-driven-testing,Data Driven Testing>>, then it works in both versions. While there is a warning about "possible invalid reference" in the conversion output.

@mojavelinux
Copy link
Member

Manually define an anchor at the top section title of the document like

That's exactly what you have to do in this scenario. Otherwise, the processor cannot know what you're linking to. Except, you should be adding the ID directly on the document title, not inline. That will fix your warning.

[#data-driven-testing]
= Data Driven Testing

@mojavelinux mojavelinux added this to the support milestone Mar 14, 2020
@mojavelinux mojavelinux self-assigned this Mar 14, 2020
@Vampire
Copy link
Author

Vampire commented Mar 19, 2020

Let's try not to mix the issues, as I still see them as separate.
I commented about the anchor in the other issue.
This issue is about not needing the work-around.

Why can't the processor know where to link to?
The processor knows that the document is included,
so for <<data_driven_testing.adoc#foo,Data Driven Testing>> he produces a link to data_driven_testing.html#foo when stand-alone and #foo for included.
For <<data_driven_testing.adoc#,Data Driven Testing>> he produces a link to data_driven_testing.html# when stand-alone and # for included.
So he actually knows the two different situations already.
Why can't he produce a link to #_data_driven_testing instead for the latter case, he should have all necessary information?

@mojavelinux
Copy link
Member

The processor knows that the document is included

Because the include directive is not a subdocument and thus has no concept of structure (it's a preprocessor line inserter). This is something that has come up many, many times. An include does not generate a referencable part of the document. So you have to explicitly add that reference so that once the include has been resolved, there is something there to reference.

We can debate about the merits of having a subdocument macro, which we've already established is necessary. But that doesn't change what is possible today.

@Vampire
Copy link
Author

Vampire commented Mar 19, 2020

Don't get me wrong, I'm just looking at this from a blackbox view, I'm not in any way into the implementation of asciidoctor, subdocuments and macros.
I'm just wondering, because

  • in including or sibling document the link <<data_driven_testing.adoc#,Data Driven Testing>> ist translated to data_driven_testing.html# for stand-alone and to # for included.
  • in included document the top-most section does not get any anchor when rendered stand-alone, but does get a proper anchor when rendered included

So from a blackbox view, the including and sibling documents know which situation it is and the included knows too, so it should hopefully be possible to translate to #_data_driven_testing for the include case instead of #.
Of if this is not possible, at least fail hard with error about the situation.
Because it is probably never the intended thing to have a dead link that does just nothing at all.

@mojavelinux
Copy link
Member

in included document the top-most section does not get any anchor when rendered stand-alone, but does get a proper anchor when rendered included

It's simply not possible to accommodate that with the current include mechanism (tracking where an include was used). We would need a new mechanism. While we've talked about introducing a subdocument macro in several issues, there has never been an issue that clearly proposes it. So I've opened one. #3603

if this is not possible, at least fail hard with error about the situation.

It's the policy of this processor to not hard fail by default. That's why we have the optional warning and the failure level setting. You can force it to fail if you decide.

For <<data_driven_testing.adoc#,Data Driven Testing>> he produces a link to data_driven_testing.html# when stand-alone and # for included.

It's doing exactly what you request it to do. It's using the fragment #. If you want to use the same xref in both scenarios, the xref has to be written as:

<<data_driven_testing.adoc#data_driven_testing,Data Driven Testing>>

where the target document has the ID data_driven_testing.

That's how the interdocument xref system is currently designed to work in Asciidoctor core (for reasons I have described).

@Vampire
Copy link
Author

Vampire commented Mar 19, 2020

It's the policy of this processor to not hard fail by default. That's why we have the optional warning and the failure level setting. You can force it to fail if you decide.

how? I didn't find it

@mojavelinux
Copy link
Member

The Asciidoctor CLI has a --failure-level flag for this purpose. If you're using the API, you can add logic that consults the logger and fail if it contains messages. Other tools should follows this guideline and add a similar switch. See asciidoctor/asciidoctor-gradle-plugin#536.

@Vampire
Copy link
Author

Vampire commented Mar 19, 2020

Well, that wouldn't really help, would it?
For the case of wrong IDs, the failure level would be INFO as you log that warning on info level, so the build would fail for any info-level message which doesn't sound right.

And besides that, that would work for the possibly wrong ID case,
but that was not what I suggested to hard fail.

What I suggested was, if you have some link like <<data_driven_testing.adoc#,Data Driven Testing>> and at rendering time it is converted to # because the documents are merged with includes, the link is practically a no-op and most probably not what was intended. This is what I suggested to hard-fail on, if you cannot produce a proper link to the top section of the included document.

@edward-encoord
Copy link

edward-encoord commented Mar 17, 2022

I believe I'm in a similar situation, so I post a small example here instead of #3603.

I understand inter-document xrefs are converted to internal xrefs, if I follow the rules.

So if I do:

== Chapter 1

[#test,reftext="go to chapter 1"]
Some test text.

xref:chapters/chapter-2.adoc#test[]
== Chapter 2

[#test,reftext="go to chapter 2"]
Some test text.

xref:chapters/chapter-1.adoc#test[]

The test ID in chapter 2 will say "id assigned to block already in use: test".

I need to write longer explicit IDs, like to append the file name:

== Chapter 1

[#1-test,reftext="go to chapter 1"]
Some test text.

xref:chapters/chapter-2.adoc#2-test[]
== Chapter 2

[#2-test,reftext="go to chapter 2"]
Some test text.

xref:chapters/chapter-1.adoc#1-test[]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants