Bad path resolution when building an individual files
We face a regression (No this is a regression just a missing feature).
Tested and reproduced in Pillar-dev8, v825, v826, v827 on Pharo 9 and Pharo 10 when compiling an individual files, the containing chapter is not part of the path.
how to reproduce
git clone https://github.com/pillar-markup/pillar.git
$ cd pillar
$ git checkout v8.2.6
$ chmod a+x ./scripts/build.sh
$ ./scripts/build.sh
../build/pillar archetype microdown-book
../build/pillar build pdf
produces correctly a pdf with corresponding figures. Each chapter contains a figures folder with some figures and such figures are correctly referenced hence found.
Here is the contents of Chapters/Chapter1/chapter1.md
## Compilation

### Welcome to Pillar's little user-guide !!
To write a book, you can create chapters and include them into `book.pillar`
or directly edit the file.
If you don't know ''Pillar'', check its documentation at [http://github.com/pillar-markup/pillar]()
Now
../build/pillar build pdf Chapters/Chapter1/chapter1.md
is failing
➜ tests git:(dev-8) ✗ ../build/pillar build pdf Chapters/Chapter1/chapter1.md
Instance of Character did not understand #readStream
Character(Object)>>doesNotUnderstand: #readStream
[ :stream |
self encode: string readStream to: stream ] in ZnPercentEncoder>>encode: in Block: [ :stream | ...
String class(SequenceableCollection class)>>new:streamContents:
String class(SequenceableCollection class)>>streamContents:
ZnPercentEncoder>>encode:
ZnResourceMetaUtils class>>encodePercent:safeSet:encoder:
ZnUrl>>encodePath:on:
[ :each |
stream nextPut: $/.
each == #/
ifFalse: [
self encodePath: each on: stream ] ] in ZnUrl>>printPathOn: in Block: [ :each | ...
OrderedCollection>>do:
ZnUrl>>printPathOn:
ZnUrl>>printPathQueryFragmentOn:
ZnUrl>>printOn:
[:s | self printOn: s] in ZnUrl(Object)>>printStringLimitedTo: in Block: [:s | self printOn: s]
String class(SequenceableCollection class)>>streamContents:limitedTo:
ZnUrl(Object)>>printStringLimitedTo:using:
ZnUrl(Object)>>printStringLimitedTo:
ZnUrl(Object)>>printString
MicZincPathResolver>>resolveReferenceIn:
MicZincPathResolver>>visitLink:
MicLinkBlock>>accept:
[ :each | each accept: self ] in MicZincPathResolver(MicrodownVisitor)>>visitChildrenOf: in Block: [ :each | each accept: self ]
Array(SequenceableCollection)>>collect:
MicZincPathResolver(MicrodownVisitor)>>visitChildrenOf:
MicZincPathResolver(MicrodownVisitor)>>visitParagraph:
MicParagraphBlock>>accept:
[ :each | each accept: self ] in MicZincPathResolver(MicrodownVisitor)>>visitChildrenOf: in Block: [ :each | each accept: self ]
OrderedCollection>>collect:
MicZincPathResolver(MicrodownVisitor)>>visitChildrenOf:
MicZincPathResolver(MicrodownVisitor)>>visitRoot:
MicRootBlock>>accept:
Syntax Error on line 3: 'Variable or expression expected'
=========================================================
1: Optionally parsers its delegate, or answers nil.
2:
3: Examples:
_^_
4: $a asPParser optional parse: 'b'
in the latex the path is
\begin{figure}[htpb]
\begin{center}
\includegraphics[width=0.3\textwidth]{/private/tmp/pillardev8InP10/pillar/tests/figures/pillar.png}
\caption{Pillar logo}
\end{center}
\end{figure}
/private/tmp/pillardev8InP10/pillar/tests/figures/pillar.png
while it should be /private/tmp/pillardev8InP10/pillar/tests/Chapters/Chapter1/figures/pillar.png
Now writing a test showing the problem!
In transformDocumentFor:
transformDocumentFor: aPRPDFDocument
"This is a hook to be able to have framework specific transformation hooks.
see PRAbstractOutputDocument>>#buildOn:"
self halt.
^ aPRPDFDocument transformDocument: (self resolveFrom: aPRPDFDocument project baseDirectory asMicResourceReference )
I have a file MicMicrodownInputDocument = '/private/tmp/pillardev8InP10/pillar/tests/Chapters/Chapter1/chapter1.md'
and we asked to resolve it via the baseDirectory `'/private/tmp/pillardev8InP10/pillar/tests'
^ aPRPDFDocument transformDocument: (self resolveFrom: aPRPDFDocument project baseDirectory asMicResourceReference )
and this part is lost: Chapters/Chapter1/
When I do aPRPDFDocument project baseDirectory asMicResourceReference
I get a MicFileResourceReference with a uri /private/tmp/pillardev8InP10/pillar/tests
resolveReferenceIn: aNode
"currently links, figures and input nodes need to be resolved"
| resolvedUri resolvedReference |
self halt.
aNode reference isRelative ifFalse: [ ^ self ].
resolvedUri := absoluteReference uri withRelativeReference: aNode reference relativePath.
resolvedReference := MicResourceReference fromUri: resolvedUri printString.
resolvedReference isFileReference ifTrue: [ resolvedReference filesystem: absoluteReference filesystem ].
aNode reference: resolvedReference
The bug is showing up In method resolveReferenceIn:
absoluteReference uri withRelativeReference: aNode reference relativePath.
/private/tmp/pillardev8InP10/pillar/tests withRelatedReference: figures/png
produces as expected /private/tmp/pillardev8InP10/pillar/tests/figures/png
because in
resolveDocument: document withBase: base
"resolve all relative urls in document with respect to the absolute uri
base can be a aString | aZnUrl | absoluteResourceReference"
base resolveDocument: document.
^ document
there is no reference to Chapters/Chapter1 so it cannot guess.
Now the PRPDFDocument knows that the file is .... Chapters/Chapter1/chapter1.md so instead of the base directory we should resolved from that file parent?
transformDocumentFor: aPRPDFDocument
"This is a hook to be able to have framework specific transformation hooks.
see PRAbstractOutputDocument>>#buildOn:"
self halt.
^ aPRPDFDocument transformDocument: (self resolveFrom: aPRPDFDocument file file asMicResourceReference )
No idea if it works for the index.md
I think that it was not a regression and that probably I produced chapter via the inputFile in the main.md. I would prefer to have a missing feature over a bug regression.
Fix is here
MicRootBlock >> transformDocumentFor: aPRPDFDocument
"This is a hook to be able to have framework specific transformation hooks.
see PRAbstractOutputDocument>>#buildOn:"
^ aPRPDFDocument transformDocument: (self resolveFrom: aPRPDFDocument file file asMicResourceReference)