Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notebook with multiple inline images only renders one for all #466

Open
dacort opened this issue Jul 12, 2021 · 1 comment
Open

Notebook with multiple inline images only renders one for all #466

dacort opened this issue Jul 12, 2021 · 1 comment

Comments

@dacort
Copy link

dacort commented Jul 12, 2021

I have a notebook in which I've pasted multiple images.

Unfortunately, each image has the same name. And due to this code that extracts the attachments, each image is overwritten with the same name until the last one.

Looks like there's not a way to correct this in Jupyter itself...this issue is still open. So I guess the only options are to pre-process the notebook manually or somehow fix it up in here.

I should note that nbconvert seems to support this fine as it uses inline, base64 images.

multi_image.ipynb.zip

@dacort
Copy link
Author

dacort commented Jul 12, 2021

I managed to workaround this by just writing a quick script to replace all image.png attachments with an incremented version.

import argparse
import json
import sys
from io import TextIOWrapper


def init_argparse() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description="Uniquify images in a Jupyter Notebook.",
    )
    parser.add_argument(
        "-v", "--version", action="version", version=f"{parser.prog} version 1.0.0"
    )
    parser.add_argument("infile", type=argparse.FileType("r"))
    parser.add_argument(
        "outfile", nargs="?", type=argparse.FileType("w"), default=sys.stdout
    )
    return parser


def uniquify_images(input_file: TextIOWrapper, output_file: TextIOWrapper):
    data = json.loads(input_file.read())
    counter = 0
    for cell in data["cells"]:
        if cell.get("cell_type") != "markdown":
            continue
        if cell.get("attachments") and cell.get("attachments").get("image.png"):
            filename = f"image_{counter:03}.png"
            cell["attachments"][filename] = cell["attachments"].pop("image.png")
            cell["source"] = [
                t.replace("(attachment:image.png)", f"(attachment:{filename})")
                for t in cell["source"]
            ]
            counter += 1

    output_file.write(json.dumps(data, indent=1))


def main() -> None:
    parser = init_argparse()
    args = parser.parse_args()
    uniquify_images(args.infile, args.outfile)


main()

Run with:

python convert.py docs/image_book.ipynb docs/image_book_new.ipynb

Works for my specific use-case. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant