longform icon indicating copy to clipboard operation
longform copied to clipboard

Compile Step Request: Convert Wikilinks to md links for Pandoc

Open chrisgrieser opened this issue 3 years ago • 5 comments

Right now, there is a step to remove links, but not to convert them.

This one is quite relevant for images, since the Obsidian image-wikilink syntax ![[]] does not work with Pandoc (or any other following app), which only accepts ![]().

However, this step also isn't as straightforward to implement, as the conversion would require more than just simple regexes, since for Pandoc, you have to retrieve the relative path of the image, too, a piece of info missing in the file-name-only-wikilink-syntax.

The Obsidian Link converter already does this though, so in principle, it would also be an option to make the plugin a dependency or something like that... 🤔

chrisgrieser avatar Jan 23 '22 22:01 chrisgrieser

Could you maybe elaborate what exactly the capabilities of the longform scripts are? Can they pretty much run any javascript, similar to templater or dataview?

I just noticed this in your docs, and was wondering, whether the app as context allows you for example to run any command via app.commands.executeCommandById(""); ?

@param context The execution context of the step, including the step
    kind and option values:
      {
        app: App; // Obsidian app
      }

if the answer is yes, one could simply trigger the Link Converter's command here to streamline the whole process.

chrisgrieser avatar Jan 28 '22 22:01 chrisgrieser

I haven't tried running external commands in a step, but I don't see why you couldn't. In this case I would probably adapt that plugin's functionality into a dedicated step, though.

kevboh avatar Feb 02 '22 14:02 kevboh

I figured out a standalone solution for the problem. again, be welcome to sherlock it :)

module.exports = {
  description: {
  	name: "Convert Image Wikilinks to MD Links",
  	description: "Convert Image Links to a format that can be read by third-party applications like Pandoc.",
  	availableKinds: ["Manuscript"],
  	options: []
  },

  // not working with scenes yet, due to https://github.com/kevboh/longform/issues/77
  compile (input, context) {
  	if (!input.contents) return input;

  	const imageWikiLinkRegex = /!\[\[(.*?\.(?:png|jpe?g|tiff))(?:\|(.+))?]]/g; // https://regex101.com/r/8Qzbod/1

  	function linkConverter(match, p1, p2) {
  		const innerWikilink = p1;
  		const alias = p2 ? p2 : "";

  		// convert via Obsidian API
  		const linkPath = context.app.metadataCache.getFirstLinkpathDest(innerWikilink, context.projectPath).path;

  		return `![${alias}](${linkPath})`;
  	}
  	input.contents = input.contents.replace(imageWikiLinkRegex, linkConverter);
  	return input;
  }

};

chrisgrieser avatar Jul 31 '22 16:07 chrisgrieser

Ok, thanks to the assist in #77, I managed to write it for the Manuscript and the scene level.

module.exports = {
  description: {
  	name: "Convert Image Wikilinks to MD Links",
  	description: "For third-party applications like Pandoc. Step must come before any 'Remove Wikilinks' step.",
  	availableKinds: ["Manuscript","Scene"],
  	options: []
  },

  compile (input, context) {
  	const imageWikiLinkRegex = /!\[\[(.*?\.(?:png|jpe?g|tiff))(?:\|(.+))?]]/g; // https://regex101.com/r/8Qzbod/1
  	function linkConverter(match, innerWikilink, alias) {
  		if (!alias) alias = "";
  		const linkPath = context.app.metadataCache.getFirstLinkpathDest(innerWikilink, context.projectPath).path;
  		return `![${alias}](${linkPath})`;
  	}
  	if (context.kind === "Manuscript") {
  		input.contents = input.contents.replace(imageWikiLinkRegex, linkConverter);
  	}
  	if (context.kind === "Scene") {
  		input = input.map(i => {
  			i.contents = i.contents.replace(imageWikiLinkRegex, linkConverter);
  			return i;
  		});
  	}
  	return input;
  }
};

chrisgrieser avatar Aug 01 '22 19:08 chrisgrieser

Nice, I plan on revisiting compile once I ship 2.0.

kevboh avatar Aug 01 '22 20:08 kevboh