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

Support xref navigation in the preview #425

Closed
Ormesome opened this issue Aug 5, 2021 · 11 comments · Fixed by #853 · May be fixed by #872
Closed

Support xref navigation in the preview #425

Ormesome opened this issue Aug 5, 2021 · 11 comments · Fixed by #853 · May be fixed by #872

Comments

@Ormesome
Copy link

Ormesome commented Aug 5, 2021

Description

Given:

:revnumber: v0.1
:revdate: 16.09.2020
:revremark: First draft
:imagesdir: ./img
:toc: top
:icons: font
:experimental: true
:relfilesuffix: .adoc
:relfileprefix: ./chapters/

== Links

image::logo_docker.png[Docker]
xref:docker.adoc[docker]

xref:aws.adoc[aws]

image::logos/logo_azure.png[Azure]
xref:azure.adoc[azure]

xref:infra/ports.adoc[ports]

== Training

include::jobs.adoc[]

include::training/javascript/style.adoc[]

link:https://javascript.info[the javascript training page]

When using the preview pane of vscode:

  • Both images are fine.
  • The xref do not work. Instead, when the xref is clicked on the browser will open with the error: Check if there is a typo in file+.vscode-resource.vscode-webview.net.
  • The include without pathing works.
  • The include with pathing does not work. Instead, the preview pane shows: Unresolved directive in
  • The link works.

System Information

Using

  • windows 10 home edition.
  • vscode 1.58.2, user setup
  • asciidoc 2.8.9

Additional Context

I really want to use asciidoc as a local document repo, a styled way to store tons of notes with tables and images in a hierarchal file structure with the potential to export as HTML.

Is my markup incorrect or does asciidoc have issues with xref and include?

@danyill
Copy link
Contributor

danyill commented Oct 17, 2021

Thank you for filing this issue and providing a complete example of the issue. 👍

This extension currently seems to have issues with the include preprocessor directive and I suspect with the xref directive also.

I don't see any issue with your markup.
I am also finding difficulty with relative document includes on Linux.

Somehow I think we are not providing the correct document directory/folder when we called asciidoctor.js. I will look into it.

danyill added a commit to danyill/asciidoctor-vscode that referenced this issue Oct 17, 2021
danyill added a commit that referenced this issue Oct 17, 2021
Part of #425, fix base directory references
@ViToni
Copy link
Contributor

ViToni commented Mar 1, 2024

Still valid. Seems to be only xref related, using link (for local files) instead of xref works just fine in the preview pane.
The editor itself can cope with both (Cmd+click). Saving this file

= Document A

xref:document-B.adoc[Document B - Xref]

link:document-B.adoc[Document B - link]

creates identical HTML:

<div id="content">
<div class="paragraph">
<p><a href="document-B.html">Document B - Xref</a></p>
</div>
<div class="paragraph">
<p><a href="document-B.adoc">Document B - link</a></p>
</div>

so it very much looks like the preview pane behaves differently than saving to HTML.

macOS: Sonoma 14.3.1
vscode: 1.87.0
asciidoc: 3.2.0

@getawaywithrmdir
Copy link

Chiming in to confirm that this does not work correctly at all.

Expected behavior:
Clicking an 'xref:' hyperlink followed by the path to an .adoc file should open that file in either the Preview or the Editor Pane, as specified by the "asciidoc.preview.openLinksToAsciidocFiles" setting.
Clicking a 'link:' hyperlink followed by the relative path to a local .adoc file should fail, cause an error, etc. (since parser must rightfully assume all .adoc files in the project would be parsed to .html, at least that's what your documentation states). Although...since HTML can technically be linking to an unparsed .adoc file, maybe it should just behave really differently (by opening the linked .adoc file in a new window or something) to signal that this may not be what the user meant to do...?

Current behavior:
Clicking an 'xref:' hyperlink followed by the path to an .adoc opens up some nonsense in my web browser, no matter the "asciidoc.preview.openLinksToAsciidocFiles" setting.
Clicking a 'link:' hyperlink followed by the relative path to a local .adoc file opens it in either the Preview or the Editor Pane, as specified by the "asciidoc.preview.openLinksToAsciidocFiles" setting.

As-is, the user is required to write inter-document links in a way that would never compile correctly into HTML just to make the previews navigable in VS Code. Please fix :).

OS: MacOS Sonoma 14.3.1
VSCode: VSCodium 1.87.0
AsciiDoc: v3.2.0

@ggrossetie
Copy link
Member

Thanks @ViToni and @getawaywithrmdir for your analysis.

We are listening to click events in the preview in the following file:

document.addEventListener('click', (event) => {
if (!event) {
return
}
let node: any = event.target
while (node) {
if (node.tagName && node.tagName === 'A' && node.href) {
if (node.getAttribute('href').startsWith('#')) {
return
}
let hrefText = node.getAttribute('data-href')
if (!hrefText) {
// Pass through known schemes
if (passThroughLinkSchemes.some((scheme) => node.href.startsWith(scheme))) {
return
}
hrefText = node.getAttribute('href')
}
// If original link doesn't look like a url, delegate back to VS Code to resolve
if (!/^[a-z-]+:\/\//i.test(hrefText) || hrefText.startsWith('file:///')) {
messaging.postMessage('clickLink', { href: hrefText })
event.preventDefault()
event.stopPropagation()
return
}
return
}
node = node.parentNode
}
}, true)

If the href is valid, we are calling messaging.postMessage('clickLink', { href: hrefText }).

In the following file we are listening to this event:

case 'clickLink':
this.onDidClickPreviewLink(e.body.href)
break

And we call this function:

private async onDidClickPreviewLink (href: string) {
const targetResource = this.resolveDocumentLink(href)
const openLinks = this.config.get<string>('preview.openLinksToAsciidocFiles', 'inPreview')
if (openLinks === 'inPreview') {
const asciidocLink = await resolveLinkToAsciidocFile(targetResource.path)
if (asciidocLink) {
this.update(asciidocLink)
return
}
}
vscode.commands.executeCommand('_asciidoc.openDocumentLink', targetResource)
}

Please, feel free to open a pull request to support navigation from a xref.

@ggrossetie ggrossetie changed the title Does asciidoc have issues with xref and include? Support xref navigation in the preview Mar 9, 2024
@ggrossetie
Copy link
Member

I renamed this issue to make it actionable. If they are other things to improve/fix, please create a new issue.

@ViToni
Copy link
Contributor

ViToni commented Mar 9, 2024

@ggrossetie Thanks for the hints. I'll try to get a PR done.

@ViToni
Copy link
Contributor

ViToni commented Mar 11, 2024

@ggrossetie I can see a bit of the things going on, but see the full picture. It seems I cannot do breakpoints in preview-src/*, they are reported to be unbound. Seems to have something to do with sourceMaps or maybe sourceMapPathOverrides, but that's something I don't have a clue about and can't fix myself.

@ggrossetie
Copy link
Member

I don't know if it's possible to debug in preview-src since this code is executed in the WebView. You might need to rely on the good (bad) old fashion console.log and open the developer tools in VS Code. You can also try to add a break point in the developer tools (Help > Toggle Developer Tools).

@ViToni
Copy link
Contributor

ViToni commented Mar 11, 2024

@ggrossetie Thanks. The hint with the developer tools (Help > Toggle Developer Tools) really helped to narrow it down.
My approach is really tiny but might be wrong as I'm not that deep into the internals of neither vscode nor this project.

But it seems to do what it should.

@Ormesome Maybe you'd like to give it a try, to see if it works for you as well.

ggrossetie pushed a commit that referenced this issue Mar 19, 2024
@birdman7260
Copy link

@ggrossetie @ViToni

Hi, this is almost working correctly: it does not handle when xref'ing to a different file and using an id

Even with that, there are two separate issues:

  1. When the preview (of docB.adoc from below) is showing a link to a separate file (example below is xref to docA.adoc) that is not part of the preview -- in this case the preview switches to show the other file but does not scroll to the right location -- hovering over the link shows the help text that looks like docA.adoc#anchor
  2. When both files are in the preview (via an include, refer to the examples below, this is specifically when previewing docA.adoc) -- nothing happens, the preview stays in the same position -- hovering over the link still shows docA.adoc#anchor

Here are two example files that would cause the issue (if there were enough text to allow the preview to scroll vertically sufficiently)

docA.adoc

= Parent document

Some text

[#anchor]
== Link to here

Please scroll me into position

include::docB[]

docB.adoc

= Child document

Other text

I want to link to xref:docA.adoc#anchor[]

I have debugged and i know how to resolve the second case:
We need to supply the docname attribute to the asciidoctor processor, specifically here:

const options: { [key: string]: any } = {
attributes: {
...attributes,
...antoraAttributes,
'!data-uri': '', // disable data-uri since Asciidoctor.js is unable to read files from a VS Code workspace.
},
backend: 'webview-html5',
extension_registry: registry,
header_footer: true,
safe: 'unsafe',
sourcemap: true,
...(baseDir && { base_dir: baseDir }),
}

Why does this work? Because the way that xref's have their target changed when they end up in the same document via an include:: directive is through the macros substitution and part of that step is to look through all of the includes on the document but it also compares against the docname attribute. That is the issue here, if the xref from docB is targeting docA#anchor and we are previewing docA which is including docB.

Several of those intrinsic document attributes are not being set because we are processing the text directly instead of the file. I don't know if the other attributes (like docdir, docfile, docfilesuffix, filetype) are worth setting as well or what kind of impact they might have, but I do know setting docname will resolve xref issue 2 i listed above.

To be clear, docname should be the file name with no path or extension, so docA not ./docA.adoc.

Regarding the xref issue 1 from above of not scrolling into position when the preview opens the other file I do not have a good idea how to resolve this and unfortunately do not have much more time to look. I'm only familiar with asciidoctor and I suspect this is something that would need to be resolved in the preview code.

forgive me if I went into the weeds on things you already know above, I mostly typed it all out for my future reference

@ViToni
Copy link
Contributor

ViToni commented Apr 23, 2024

@birdman7260 Feel free to provide a PR. IMHO even if it "only" would fix case 2) it's an improvement already.
Since I have hardly found my way around the code myself, @ggrossetie can certainly answer more questions than I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment