Macro to save article as .epub

25 views
Skip to first unread message

Mark Johnno

unread,
Feb 26, 2025, 11:06:31 AMFeb 26
to news...@googlegroups.com
Hello,

How can I create a macro to save an article as an .epub file?

I tried:

macro S set pandoc "%T".epub

and

macro S set pandoc "%u".epub

but there seem to be not output at all.

I am starting from the fact that I can pipe an article to 'pandoc -o title.epub'.


Ludovico Gerardi

unread,
Feb 27, 2025, 3:47:31 AMFeb 27
to Mark Johnno, news...@googlegroups.com
Hi,

I managed to do this with a Python script that extracts the title from the article that is piped to it and then calls Pandoc:

#!/usr/bin/env python3

import sys
import subprocess

article = ""
title = ""
for line in sys.stdin:
article = article + line
if not title and line.startswith("Title:"):
title = line[7:].strip()

subprocess.run(
["pandoc", "--metadata", f'title="{title}"', "-o", title + ".epub"],
input=bytes(article, encoding="utf-8"),
)

Surely it can be made more robust etc., but this is a starting point. Then you
simply bind the macro key to the script using the pipe-to operator in
Newsboat's config file:

macro S pipe-to "save-article-to-epub.py"

I hope you find this useful :)

--
Regards,
Ludovico Gerardi

Mark Johnno

unread,
Feb 27, 2025, 5:58:44 AMFeb 27
to Ludovico Gerardi, news...@googlegroups.com
Thank you, Ludovico.

I did not realise newsboat might not be able to extract the file name (without the extension). Your answer helps me see this.

I don't use Python - but thanks anyway. I will try to do what your script does with awk, or Bash maybe. I need to look it up.

Thanks again.

Johnno.

Mark Johnno

unread,
Mar 1, 2025, 9:44:48 AMMar 1
to Ludovico Gerardi, news...@googlegroups.com


On Thursday, February 27th, 2025 at 9:47 AM, Ludovico Gerardi
Thanks, Ludivico.

I managed to get your script and macro to run. That's great.

I modified the Pandoc command to add a path to a directory where I save .epub files.

#!/usr/bin/env python3

import sys
import subprocess

article = ""
title = ""
for line in sys.stdin:
article = article + line
if not title and line.startswith("Title:"):
title = line[7:].strip()

subprocess.run(
["pandoc", "--metadata", f'title="{title}"', "-o", "/home/user/epub/" + title + ".epub"],
input=bytes(article, encoding="utf-8"),
)

Thanks again.

PS: on Google groups UI, indents of the script were removed, at least in the browser I use.

PS2: Pandoc produces an error when I use "~/epub"

Ludovico Gerardi

unread,
Mar 2, 2025, 5:40:06 AMMar 2
to Mark Johnno, news...@googlegroups.com
> PS: on Google groups UI, indents of the script were removed, at least in the browser I use.
Hm, honestly I don't know if that can be fixed in some way.

> PS2: Pandoc produces an error when I use "~/epub"
That is because the subprocess running pandoc is not executed through a shell,
so the expansion of "~" is not done. There are a few ways to address this:
- calling subprocess.run() with the parameter shell=True. This will run the
subprocess through a shell.
- constructing the path like this: os.getenv("HOME") + "/epub/" + ...
os.getenv("HOME") is replaced with "/home/username".
- constructing the path like this: os.path.expanduser("~/epub/") + ...
Which resolves ~ directly, like a shell would do.

--
Regards,
Ludovico Gerardi

Mark Johnno

unread,
Mar 2, 2025, 12:17:55 PMMar 2
to Ludovico Gerardi, news...@googlegroups.com

> > PS: on Google groups UI, indents of the script were removed, at least in the browser I use.
>
> Hm, honestly I don't know if that can be fixed in some way.

I was mentioning this in case someone like me (who doesn't know Python) copy the script from Google Groups's UI. I first did so (without indention.
>
> > PS2: Pandoc produces an error when I use "~/epub"
>
> That is because the subprocess running pandoc is not executed through a shell,
> so the expansion of "~" is not done. There are a few ways to address this:
> - calling subprocess.run() with the parameter shell=True. This will run the
> subprocess through a shell.
> - constructing the path like this: os.getenv("HOME") + "/epub/" + ...
> os.getenv("HOME") is replaced with "/home/username".
> - constructing the path like this: os.path.expanduser("~/epub/") + ...
> Which resolves ~ directly, like a shell would do.

Thank you for the explanation. I will stick with what I have for now. The script (and the macro) is working fine. But anyway, thanks again; I can come back to your explanation if I have issues in the future.
Reply all
Reply to author
Forward
0 new messages