Before submitting
Description
Hi again. I am not sure if this is a desired behaviour or a bug. Feel free to close it or move it to discussions if this is actually intended behavior. Thank you 😄 .
When a block of content is passed as an argument to a user-defined function, relative paths inside
that content — both .qd subdocument links and media — are resolved against the directory of the
file that declares the function, not the file that calls it.
The content was authored at the call site, so I would expect it to resolve like any other content in
that file. Instead the base directory silently changes, and the same path cannot be correct in both
places: a link written in prose and the identical link one line below inside a .example {…} call
need different spellings.
Two things make this hard to notice:
- Built-in block functions (
.box, .row, .collapse) are not affected, and a byte-identical
function declared in the calling file is not affected either. So the call site gives no hint
which behaviour applies.
quarkdown c prints Success and exits 0. Unresolved links render an error box inline in the
published page; unresolved media just leaves the raw path in src with no visible marker at all.
I use quarkdown for a bigger documentation wiki using the docs doctype. So it is quite useful to structure the big wiki into several subfolders. This problem might not as easily occur if you have a single-page or single-folder project.
Input
Three files. _functions.qd at the project root:
.function {example}
content:
.box {Example} type:{tip}
.content
pages/page.qd, together with a pages/target.qd that sits right next to it:
.docname {Page}
.include {../_functions.qd}
[target.qd](target.qd)
.example
[target.qd](target.qd)
main.qd:
.docname {Repro}
.include {_functions.qd}
- [page](pages/page.qd)
Then: quarkdown c main.qd -o out --pretty
Actual output
Console — note Success and exit code 0:
Cannot resolve subdocument link: target.qd
[10:47] Success @ .../out/Repro
out/Repro/page/index.html — the first link resolved, the second became an inline error box:
<a href="../target/">target.qd</a>
<div class="box tip">
<div class="box-content">
<div class="box error">
<div class="box-content">
Cannot resolve subdocument link: target.qd
Expected output
Both links resolve to pages/target.qd, producing the same href. The path is written in
pages/page.qd, so it should be read relative to pages/ whether or not it passes through a
function call on the way to the renderer.
Operating system
Arch Linux (kernel 7.1.8), Quarkdown 2.5.1
Additional context
I isolated the behaviour into six cases that all build from one main.qd (repro attached as
quarkdown-repro.tar.gz — quarkdown c main.qd -o out --pretty). Each page in pages/
demonstrates exactly one fact.
| Case |
Setup |
Result |
| 1 |
link to a file next to the calling page |
resolves in prose, fails inside the call |
| 2 |
link to a file next to the declaring file |
fails in prose (correct), resolves inside the call |
| 3 |
identical function declared in the calling file |
resolves in both positions |
| 4 |
built-in .box, .row, .collapse |
resolves in all three |
| 5 |
function declared in lib/, called from pages/ |
only the lib/-relative path resolves |
| 6 |
image paths instead of document links |
same base shift |
Case 2 fixes the direction. It is the mirror of case 1: the path that is wrong for the calling
page is the one that works inside the call. So this is a base-directory swap, not merely a
resolution failure.
Case 5 rules out "the base is the project root". With .libexample declared in
lib/_libfunctions.qd and called from pages/5-declaring-dir-is-base.qd, only target-in-lib.qd
resolves. Both target-at-root.qd (the root document's directory) and target-in-pages.qd (the call
site) fail. The base is the declaring file's own directory, specifically.
Case 6 — media behaves the same and fails more quietly. No error box is rendered; the unresolved
path is left in the attribute, so the page ships with a broken image:
<img src="media/dot-in-pages@1128147620.png" /> <!-- prose: resolved -->
<img src="../dot-in-pages.png" /> <!-- inside the call: raw path, broken -->
<img src="media/dot-at-root@1351722863.png" /> <!-- inside the call: resolved, wrong file -->
If resolving relative to the declaring file is deliberate for a function's own body — reasonable for
assets a library ships alongside itself — then content passed in by the caller arguably still should
not follow that rule, since it was authored elsewhere.
quarkdown-repro.tar.gz
Before submitting
quarkdown doctor envand will include its output.Description
Hi again. I am not sure if this is a desired behaviour or a bug. Feel free to close it or move it to discussions if this is actually intended behavior. Thank you 😄 .
When a block of content is passed as an argument to a user-defined function, relative paths inside
that content — both
.qdsubdocument links and media — are resolved against the directory of thefile that declares the function, not the file that calls it.
The content was authored at the call site, so I would expect it to resolve like any other content in
that file. Instead the base directory silently changes, and the same path cannot be correct in both
places: a link written in prose and the identical link one line below inside a
.example {…}callneed different spellings.
Two things make this hard to notice:
.box,.row,.collapse) are not affected, and a byte-identicalfunction declared in the calling file is not affected either. So the call site gives no hint
which behaviour applies.
quarkdown cprintsSuccessand exits 0. Unresolved links render an error box inline in thepublished page; unresolved media just leaves the raw path in
srcwith no visible marker at all.I use quarkdown for a bigger documentation wiki using the
docsdoctype. So it is quite useful to structure the big wiki into several subfolders. This problem might not as easily occur if you have a single-page or single-folder project.Input
Three files.
_functions.qdat the project root:pages/page.qd, together with apages/target.qdthat sits right next to it:main.qd:Then:
quarkdown c main.qd -o out --prettyActual output
Console — note
Successand exit code 0:out/Repro/page/index.html— the first link resolved, the second became an inline error box:Expected output
Both links resolve to
pages/target.qd, producing the samehref. The path is written inpages/page.qd, so it should be read relative topages/whether or not it passes through afunction call on the way to the renderer.
Operating system
Arch Linux (kernel 7.1.8), Quarkdown 2.5.1
Additional context
I isolated the behaviour into six cases that all build from one
main.qd(repro attached asquarkdown-repro.tar.gz—quarkdown c main.qd -o out --pretty). Each page inpages/demonstrates exactly one fact.
.box,.row,.collapselib/, called frompages/lib/-relative path resolvesCase 2 fixes the direction. It is the mirror of case 1: the path that is wrong for the calling
page is the one that works inside the call. So this is a base-directory swap, not merely a
resolution failure.
Case 5 rules out "the base is the project root". With
.libexampledeclared inlib/_libfunctions.qdand called frompages/5-declaring-dir-is-base.qd, onlytarget-in-lib.qdresolves. Both
target-at-root.qd(the root document's directory) andtarget-in-pages.qd(the callsite) fail. The base is the declaring file's own directory, specifically.
Case 6 — media behaves the same and fails more quietly. No error box is rendered; the unresolved
path is left in the attribute, so the page ships with a broken image:
If resolving relative to the declaring file is deliberate for a function's own body — reasonable for
assets a library ships alongside itself — then content passed in by the caller arguably still should
not follow that rule, since it was authored elsewhere.
quarkdown-repro.tar.gz