Closed Comprehensive-Jason closed 9 months ago
Thanks. There are two ways to support wikilinks.
Write a lua-filter named wiki-links.lua
to do convertion, and put it into luaDir.
Then update the export template command (add --lua-filter="${luaDir}/wiki-links.lua"
before other lua-filter)
https://github.com/mokeyish/obsidian-enhancing-export/blob/04176511ba5f07bfa1073919bee0c12a9ceb4855/src/export_command_templates.ts#L25
to
- -f markdown --resource-path="${currentDir}" --resource-path="${attachmentFolderPath}" --lua-filter="${luaDir}/markdown.lua" -s -o "${outputPath}" -t commonmark_x-attributes
+ -f markdown --resource-path="${currentDir}" --resource-path="${attachmentFolderPath}" --lua-filter="${luaDir}/wiki-links.lua" --lua-filter="${luaDir}/markdown.lua" -s -o "${outputPath}" -t commonmark_x-attributes
Visit https://pandoc.org/try/
What do your think?
I see. I'm way more familiar with the Typescript approach, as I help code another plugin.
I might hold off on working on it for now, as exporting to standard markdown is on the Obsidian roadmap. Once that comes out, it will probably be the best solution.
In the meantime, if anyone else is looking for ways to convert their notes for export, they can use the Link Converter plugin mentioned above to prepare their files for export. I personally use the Obsidian Commander plugin to create the following macro for exporting:
I duplicate the note to be exported (so my export preparation doesn't affect the actual note), then use Link Converter to turn all links into standard markdown, then run Linter to standardize my note to match standard Markdown specs and avoid formatting issues with Pandoc, then export. I hope this is helpful!
@Comprehensive-Jason That's comprehensive alright! Thanks for the Commander macro suggestion!
I talked with the Obsidian devs about whether exporting to standard markdown is still a planned feature. They told me the feature will come later and to go ahead with the workaround. I will start work on adding the conversion code.
In any case, this plugin uses Pandoc, and it is not limited to conversion to Markdown, so it will be relevant even if the Obsidian devs implement .md export
@vanem I'm not trying to convert just to standard Markdown, I'm trying to preprocess Obsidian notes into standard Markdown so that this plugin works correctly.
The chief issue with this plugin right now is that it (and Pandoc) requires standard Markdown links with relative file paths in order to convert properly, while most users of Obsidian use wikilinks with just the file name.
Extra code is needed to convert Obsidian wikilinks into standard Markdown so that the plugin works for everyday users.
This plugin has been compatible with wikilinks for a while using Pandoc extensions, and yesterday, it also became compatible with wikilink images with the latest release of Pandoc! 🎉
The specific attribute that you need, to enable wikilink support, is:
wikilinks_title_after_pipe
To use it, change the default export command (for example to PDF) to:
-f markdown+wikilinks_title_after_pipe --resource-path="${currentPath}" --resource-path="${attachmentFolderPath}" --metadata title="${currentFileName}" -s -o "${outputPath}" -t pdf
You can also add other extensions like mark
and lists_without_preceding_blankline
that improve Obsidian and Pandoc compatibility, so it becomes:
-f markdown+wikilinks_title_after_pipe+mark+lists_without_preceding_blankline --resource-path="${currentPath}" --resource-path="${attachmentFolderPath}" --metadata title="${currentFileName}" -s -o "${outputPath}" -t pdf
Also note that I removed some bloat in the command, as mentioned in #115.
This is pretty cool! I presume we still have to convert to relative file paths though?
I presume we still have to convert to relative file paths though?
Nope, not as long as you supply the resource-path, as in my example above (which is included by default, I think), then it should work with only the filename. Upgrade to Pandoc 3.1.7 and give it a try!
However, note that image sizing is not working yet, since you can't use link attributes with wikilinks. I've raised this issue on the Pandoc repo here, but the devs are reluctant to support the combination of Wikilinks + link attributes, since the apps that use wikilinks don't support the link attributes syntax. You're welcome to join the conversation over on the Pandoc repo!
On the Obsidian side, there's discussion in Forum about supporting link attributes or expanding the existing image sizing syntax to support units here.
@FeralFlora Gotcha. Currently I'm testing with the following:
Arguments: -f markdown+wikilinks_title_after_pipe+mark+lists_without_preceding_blankline --resource-path="${currentDir}" --resource-path="${attachmentFolderPath}" --lua-filter="${luaDir}/pdf.lua" ${ options.textemplate ? `--resource-path="${pluginDir}/textemplate" --template="${options.textemplate}"` : ` ` } --embed-resources --standalone -s -o "${outputPath}" -t pdf
Extra arguments: --pdf-engine=pdflatex
Internal links and embedding works fine with the following folder structures:
Vault
└── Attachments Folder (set in Obsidian)
└── imageToEmbed.png
└── note.md
OR
Vault
└── note.md
└── Attachments Folder (set in Obsidian)
└── imageToEmbed
When ![[imageToEmbed.png]]
is written in note.md
, and note.md
is placed inside the Attachments folder alongside the image such that they share the exact same directory, the embedding works properly.
Embedding also works properly if note.md
is kept outside of any folders while inside the vault.
However, when I use a more normal folder structure, where note.md
is in its own folder separate from the image:
Vault
└── Attachments Folder (set in Obsidian)
└── imageToEmbed.png
└── Notes Folder
└──note.md
I get the following error:
I think the issue is with how the plugin is replacing ${attachmentFolderPath}
.
The plugin replaces "${currentDir}" with "C:\Users\jason\AppData\Roaming\obsidian\Obsidian Sandbox\Notes".
However, it only replaces "${attachmentFolderPath}" with "Attachments", omitting the rest of the path.
When I explicitly insert the full path "C:\Users\jason\AppData\Roaming\obsidian\Obsidian Sandbox\Attachments" instead of using ${attachmentFolderPath}
, everything exports perfectly.
All in all, I think this is quite a minor fix for the plugin. First, we replace ${attachmentFolderPath}
with ${vaultDir}/${attachmentFolderPath}
in all the templates. Then, we could add a toggle in the plugin settings that appends +wikilinks_title_after_pipe
so the user can quickly enable wikilink compatibility.
-f markdown+wikilinks_title_after_pipe --resource-path="${currentPath}" --resource-path="${attachmentFolderPath}" --metadata title="${currentFileName}" -s -o "${outputPath}" -t pdf
For some reason, using these settings I can't export contents of an expanded link such as ![[note]]
because it thinks the links to notes are images. Using the default pdf export command had these links showing as plain text which is also not what I was aiming for.
@mrlinuxfish This is a different issue tracked in #14 .
However, when I use a more normal folder structure, where
note.md
is in its own folder separate from the image:
For me, I can export with the command I shared, even though my files are located as follows:
Vault
└── Inbox
└──note.md
└── Attachments Folder (set in Obsidian)
└── imageToEmbed.png
I just realized that this is because I have the full resource path in my defaults file. This is what enhancing export prints in the console:
pandoc -f markdown+wikilinks_title_after_pipe+mark+lists_without_preceding_blankline --resource-path="C:\Users\User\Documents\Notes\Obsidian-notes\01 - Inbox\Cat test.md" --resource-path="06 - Resources" --metadata title="Cat test" -s -o "C:\Users\User\Documents\Notes\Obsidian-notes\09 - Outputs/Cat test.pdf" -t pdf --defaults=C:\Users\user\Documents\Notes\Obsidian-notes\pandoc.yaml --citeproc "C:\Users\User\Documents\Notes\Obsidian-notes\01 - Inbox\Cat test.md"
So I guess it would fail for me without the defaults file too, and you are right that ${vaultDir}
is needed in the template. Perhaps a better solution would be for ${attachmentFolderPath}}
to actually resolve as the full path to the attachments folder.
Then, we could add a toggle in the plugin settings that appends +wikilinks_title_after_pipe so the user can quickly enable wikilink compatibility.
I agree, such a toggle would be nice.
@FeralFlora Sounds like a plan! I'll get working on a PR for it then.
Thanks. There are two ways to support wikilinks.
* Convert the markdown with TypeScript(like [Obsidian Link Converter plugin](https://github.com/ozntel/obsidian-link-converter)). and fill stdin of pandoc. * Write a [lua-filter](https://pandoc.org/lua-filters.html) named `wiki-links.lua` to do convertion, and put it into [luaDir](https://github.com/mokeyish/obsidian-enhancing-export/tree/main/lua). Then update the export template command (add `--lua-filter="${luaDir}/wiki-links.lua"` before other lua-filter) https://github.com/mokeyish/obsidian-enhancing-export/blob/04176511ba5f07bfa1073919bee0c12a9ceb4855/src/export_command_templates.ts#L25 to ```diff - -f markdown --resource-path="${currentDir}" --resource-path="${attachmentFolderPath}" --lua-filter="${luaDir}/markdown.lua" -s -o "${outputPath}" -t commonmark_x-attributes + -f markdown --resource-path="${currentDir}" --resource-path="${attachmentFolderPath}" --lua-filter="${luaDir}/wiki-links.lua" --lua-filter="${luaDir}/markdown.lua" -s -o "${outputPath}" -t commonmark_x-attributes ``` Visit https://pandoc.org/try/ <img alt="图片" width="1403" src="https://user-images.githubusercontent.com/16131917/240490128-5637d4f3-4e01-4017-a37c-a5ce03f21a79.png">
What do your think?
Thanks, i use the second way,it works
here is the lua code:
function Pandoc(doc)
-- 遍历文档中的所有块元素
for i, block in pairs(doc.blocks) do
if block.t == 'Para' then
-- 在段落文本中进行替换
doc.blocks[i] = pandoc.Para(replace_wikilinks(block.content))
end
end
return doc
end
function replace_wikilinks(content)
local new_content = {}
local text = pandoc.utils.stringify(content)
-- 使用正则表达式匹配文本中的 Wikilink 格式
text = text:gsub("!(%[%[[^%]]*%]%])", function(link)
local img_path = link:match("%[%[([^%]]*)%]%]")
return "![](" .. img_path .. ")"
end)
return pandoc.read(text).blocks[1].content
end
return { { Pandoc = Pandoc } }
@TimFruit Looks great, Are you willing to submit a PR?
@TimFruit Looks great, Are you willing to submit a PR?
sorry,i don't want to submit a PR. Writing pandoc lua scripts is difficult for me, I asked chat gpt to get this code
@TimFruit Looks great, Are you willing to submit a PR?
For standard markdown, wouldn't it be easier to just add the wikilinks_title_after_pipe
extension (Pandoc docs here) rather than using a lua filter to convert the wikilinks to markdown links?
As is, gfm
and commonmark
don't support the use wikilinks_title_after_pipe
extension for image links yet, but it looks like support will be added for that soon. Progress on that is tracked here: https://github.com/jgm/pandoc/issues/9164
Until then, the lua filter might be relevant for gfm
and commonmark
, but I think the most straightforward option for markdown
is to just use the extension.
@Comprehensive-Jason mentioned making a PR to change the default command, not sure if there's any progress on that? This requires ${attachmentFolderPath}}
to actually resolve as the full path to the attachments folder. Alternatively, the commands could be changed from ${attachmentFolderPath}
to ${vaultDir}/${attachmentFolderPath}
.
@Comprehensive-Jason I was wondering whether you need help with the PR?
Just voicing my enthusiastic support for this
Folks, I've been working on a similar problem, to get Obsidian style "|100" to set the width for images in pandoc beamer output.
Thought I would share some code here in case it helps with this problem.
The following works for wikilink images to propagate any given width/height attributes to resize the image:
function Image(elem)
local captionStr = pandoc.utils.stringify(elem.caption)
local parts = {}
for part in string.gmatch(captionStr, "[^|]+") do
table.insert(parts, string.match(part, "^%s*(.-)%s*$")) -- Trim whitespace
end
local width, height = nil, nil
if #parts > 0 then
width, height = parts[#parts]:match("^(%d+)%s*x?%s*(%d*)$")
if width then
table.remove(parts, #parts)
end
end
if width then
elem.attributes.width = width
if height and height ~= "" then
elem.attributes.height = height
end
end
if #parts > 0 then
local newCaption = table.concat(parts, " | ")
elem.caption = pandoc.read(newCaption, 'markdown').blocks[1].content
else
elem.caption = {}
end
return elem
end
e.g.
![[attachments/files/Pasted image 20240222051816.png| 100]]
![[attachments/files/Pasted image 20240222051816.png| Real caption. | 100]]
P.s.
The approach is not perfect for my use case because I would like to remove the width attribute from the display figure caption. Problem is that even thought the element caption is updated, the figure remains showing the old caption.
As a MWE to illustrate the problem, try this filter:
function Image(elem)
elem.caption = pandoc.List({pandoc.Str("foo")});
return elem
end
return {
{
Image = Image,
}
}
when applied to a document with:
![[attachments/files/Pasted image 20240222051816.png| real caption | 100]]
we get:
(image hidden; only caption shown)
So the image caption is updated, but the figure text is not.
It seems like pandoc generates the figure text before the lua filter sees element. The following for example updates no "Figure" captions, though the element is updated.
function Image(elem)
elem.caption = pandoc.List({pandoc.Str("foo")});
return elem
end
return {
{
Image = Image,
}
}
Perhaps a better solution would be for
${attachmentFolderPath}}
to actually resolve as the full path to the attachments folder.
@Comprehensive-Jason @universvm I just submitted a PR which introduces this change: https://github.com/mokeyish/obsidian-enhancing-export/pull/174
Currently, the plugin is not compatible with wikilinks and only works on embeds with relative file paths. The Obsidian Link Converter plugin can convert all the wikilinks in a file into Markdown, and all paths to relative file paths. The Converter plugin's code could be integrated into this plugin to increase Obsidian compatibility. Wikilinks and paths could be automatically converted into markdown and relative paths.
If needed, I can help with this project. Could have a couple of pointers on where best to add the necessary code in this repo?