Pandoc MD to RTF

I am trying to convert MD to RTF with pandoc, I am using a script seen many times on the internet that I have now running great as a service... but it's not working for me, I get an empty clipboard.
If I remove the piping to pbcopy I get an text representation of RTF... but that's not what I'm after. Any idea what I am doing wrong?

Cheers, Riccardo

Hi, Riccardo

Just swap the "Save to System Clipboard" to "Ignore results".

The former saves the output results of pbcopy (nothing) to the clipboard, when pbcopy has already done that.

To diagnose this, set up a separate macro to "Activate Clipboard History Switcher" and run it. Leave the Switcher window on screen.

Copy the Markdown you want to translate (and confirm it appears in the Switcher), then run your pandoc translation macro. The Switcher window should now show that the RTF is generated and copied by your macro, but it then copies an empty string straight afterwards...

Best wishes,
Steve

PS when you use #! at the start of the script, I'd remove the space between the characters

2 Likes

Didn't work as of today on my setup.

Used this ChatCPT prompt:

You are an advanced engineering level user of Keyboard Maestro and scripting languages.
Please troubleshoot the following:
I am trying to follow the instructions in the Keyboard Maestro post here: Pandoc MD to RTF
to convert the markdown on the clipboard to RTF when pasted into a Word document.
I get the following errors:

  1. Execute a Shell Script failed with script error: Execute a Shell Script failed with script error: [WARNING] Could not deduce format from file extension or
    Defaulting to markdown
    pandoc: I: withBinaryFile: does not exist (No such file or directory) Defaulting to markdown
  2. Execute a Shell Script failed with script error: [WARNING] Could not deduce format from file extension or
    Defaulting to markdown

Here is the Shell Script I am using:

/bin/bash

export LC_CTYPE=UTF-8
/usr/local/bin/pandoc -t rtf -s I pbcopy

Here is the version of pandoc I am using:

ChatGPT updated the script to this:

#!/usr/bin/env bash
export LC_CTYPE=UTF-8

/usr/bin/pbpaste
| /usr/local/bin/pandoc --from=markdown --to=rtf --standalone
| /usr/bin/pbcopy

And it worked.

Below is the ChatGPT output from the above prompt. I only followed step 2 and it worked.
The rest, along with the explanations, were interesting. I'm unclear about Pandoc or Shell scripts so I have no idea if ChatGPT is accurate or writing nonsense. Take it with a very large grain of salt.

I have ChatGPT set to answer straight without fluff.

Blunt reality check

  1. Your shell line is wrong. I and pbcopy are being treated as file names. Pandoc looks for a file literally called I, can’t find it, and throws the withBinaryFile error. The “[could not deduce format]” warning pops up because, once the file lookup fails, Pandoc has no file-extension to guess the input format from.

  2. Pandoc has to read from stdin and write to stdout, then you push the result back onto the clipboard. The classic, working pipeline is:

#!/usr/bin/env bash
export LC_CTYPE=UTF-8

/usr/bin/pbpaste \
  | /usr/local/bin/pandoc --from=markdown --to=rtf --standalone \
  | /usr/bin/pbcopy
    • pbpaste dumps the current clipboard to stdin.
  • pandoc converts Markdown → RTF on stdout (no temp file needed).
  • pbcopy stuffs that RTF back onto the clipboard as the correct public.rtf flavour. This is exactly the pattern shown in the original forum thread and in other Pandoc clipboard tutorials.
  1. Keyboard Maestro macro tweaks
Action Setting you need
Execute Shell Script “Ignore Results” (don’t pipe the script’s output back into KM – pbcopy already handled the clipboard)
Shell “/bin/bash” (or /usr/bin/env bash)
Pass input “Nothing”
Path to pandoc /usr/local/bin/pandoc on Intel Macs, /opt/homebrew/bin/pandoc on Apple-silicon unless you linked it into /usr/local/bin.
  1. Version is fine; path may not be. 3.7.0.2 supports RTF output. If which pandoc in Terminal shows a different path, point KM to that path or add it to PATH in the first line of your script:
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
  1. Why the flags?
  • --from=markdown silences the “could not deduce format” warning.
  • --standalone (-s) makes Pandoc emit complete RTF with the needed headers; Word is happier with that.
  • You don’t need an explicit -o because stdout is piped straight into pbcopy.
  1. Quick test outside Keyboard Maestro
pbpaste | pandoc -f markdown -t rtf -s | pbcopy
open -a "Microsoft Word"
# ⌘V  →  rich-text paste should work

If that behaves, the macro will behave.

  1. Still stuck? Checklist
  • Run the script in Terminal first—confirm no errors.
  • Make sure KM’s Execute Shell Script action is set to ignore its results.
  • Verify pbpaste actually contains Markdown (use pbpaste | head to peek).
  • Confirm that Word’s paste is set to keep source formatting (Word > Preferences > Edit).

That’s it—fix the pipeline, kill the bogus arguments, and the macro will just work with Keyboard Maestro.

The pipeline isn't broken -- the action's "With input from: System Clipboard" uses the contents of the Clipboard as stdin, so is effectively the same as pbpaste | in the shell script.

What it actually looks like you've done is mis-typed a capital "i" instead of a pipe. Pasting from your "Here is the Shell Script I am using" above:

/usr/local/bin/pandoc -t rtf -s I pbcopy

...which should be

/usr/local/bin/pandoc -t rtf -s | pbcopy

OP's script is fine (though it may have a extraneous space in the shebang) on Intel Macs with homebrew-installed pandoc -- change the path to suit other situations:

#!/bin/bash
export LC_CTYPE=UTF8
/usr/local/bin/pandoc -t rtf -s | pbcopy

Note that you still need to pipe to pbcopy to set the Clipboard -- if you use the action's "Save to: System Clipboard" instead you'll get raw RTF. While I'm sure there's a way round that, using pbcopy is much easier!

1 Like

Thanks for the good eye :wink: on that, @Nige_S

I know I didn't type it so I looked closer. Turns out the "Recognize Text" function in the shottr app turns a pipe | into a capital I at my default display resolution but if I click the OP's image magnifing it to full screen and then use shottr to recognize the text, the pipe is captured as a pipe. Good to know to look for that. As a non-coder I rarely use that character.

I'm curious, I'm using a M1 Mac with a package installed pandoc which installed as PanWriter. Would that need a different path?

Well, PanWriter says

You also have to install pandoc to export to most formats.

From there it'll depend on which installation route you chose. Hopefully not Conda ( :wink: ), brew will have put it into /opt/homebrew/bin/ and I don't know about the others.

But all you care about, since you're telling your script to use bash, is where bash thinks it is. Go to Terminal, type bash and hit Return (in case you default to zsh) then which pandoc and Return to see the path. Then exit and Return to go back to your original shell.

(base) nigel@Nigel's-MacBookAir Desktop % bash

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.
bash-3.2$ which pandoc
/opt/homebrew/bin/pandoc
bash-3.2$ exit
exit
(base) nigel@Nigel's-MacBookAir Desktop % 

The kewl kids (not me!) also set KM's Shell Script action's font to one where these things are more obvious. It's a "hidden preference", set via Terminal -- this will set it to Menlo Regular (the same as uncompiled text in Apple's Script Editor):

defaults write com.stairways.keyboardmaestro.editor Font-Shell -string "Menlo Regular"

image

To return to the default font use:

defaults delete com.stairways.keyboardmaestro.editor Font-Shell
1 Like

Thanks, yes, Pandoc is installed. Seems PanWriter is a MD editor on its own that can use Pandoc during export thereby functioning as a GUI for Pandoc if installed. Just my speed :face_holding_back_tears:.

Will see if Menlo makes a different. Thank you for the tip and for sharing your time and knowledge generously :saluting_face: