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

attached image in ipynb not shown in html #699

Closed
abchenson opened this issue Nov 1, 2017 · 19 comments
Closed

attached image in ipynb not shown in html #699

abchenson opened this issue Nov 1, 2017 · 19 comments

Comments

@abchenson
Copy link

image_test.ipynb.zip
I tried converting this simple notebook with
python -m nbconvert docs/notebooks/image_test.ipynb
running nbconvert 5.3.1 . The notebook contains one markdown cell with a single line
![image.png](attachment:image.png)
But the image does not show up in the resulting html, only a cell with text 'image.png' in it.
(attachment:image.png). The image works in the notebook so it seems correctly embedded. Is this not supported? It's an important feature for me so any help would be really useful.
Thanks in advance

@platise
Copy link

platise commented Jan 15, 2018

I would also need this feature, as atm it is not possible to make any other output but browser's print to PDF.

For PDF export I would suggest images are exported under some temp dir, like .ipynb_tmp to be able to generate a PDF.

@platise
Copy link

platise commented Feb 17, 2018

How to increase intention for this feature?

Image attachments is such a cool feature with easy drag and drop images, makes it really possible to work in hardware development test and measurement projects, but without a proper HTML or PDF creation its use is limited.

@sglyon
Copy link
Contributor

sglyon commented Feb 19, 2018

I needed this, so I wrote a pre-processor to extract attached images and put them in the outputs, which is used for images in the output part of a code cell.

It has been working well for me.

https://gist.github.com/sglyon/5687b8455a0107afc6f4c60b5f313670

@platise
Copy link

platise commented Feb 19, 2018

Thank you @sglyon for response.

Sounds interesting, and if I understand it: it extracts all images in dict{} which you then save into files, and use the files when generating the pdf with pdflatex?

If you have a small (one figure) example of usage it would be really helpful to understand the whole procedure and how you run it.

@sglyon
Copy link
Contributor

sglyon commented Feb 19, 2018

No problem.

My usage was as follows

from traitlets.config import Config
import nbformat
import nbconvert


def to_pdf(ipynb_path)
    c = Config()
    my_preprocesors = [ExtractAttachmentsPreprocessor]
    c.PDFExporter.preprocessors = my_preprocesors
    c.LatexExporter.preprocessors = my_preprocesors

    exporter = nbconvert.PDFExporter(config=c, extra_loaders=[dl])
    writer = nbconvert.writers.FilesWriter()

    nb = nbformat.read(ipynb_path, as_version=4)

    (body, resources) = exporter.from_notebook_node(nb, resources=resources)
    writer.write(body, resources, "output.pdf")

@fuglede
Copy link

fuglede commented Mar 12, 2018

For what it's worth, fixing up the HTML post-conversion manually is also pretty straightforward: Assuming that all attachment filenames are unique, you could do something like

import nbconvert
import nbformat

with open('my_notebook.ipynb') as nb_file:
    nb_contents = nb_file.read()

# Convert using the ordinary exporter
notebook = nbformat.reads(nb_contents, as_version=4)
exporter = nbconvert.HTMLExporter()
body, res = exporter.from_notebook_node(notebook)

# Create a dict mapping all image attachments to their base64 representations
images = {}
for cell in notebook['cells']:
    if 'attachments' in cell:
        attachments = cell['attachments']
        for filename, attachment in attachments.items():
            for mime, base64 in attachment.items():
                images[f'attachment:{filename}'] = f'data:{mime};base64,{base64}'

# Fix up the HTML and write it to disk
for src, base64 in images.items():
    body = body.replace(f'src="{src}"', f'src="{base64}"')
with open('my_notebook.html', 'w') as output_file:
    output_file.write(body)

Of course, this does nothing to actually fix the bug. Without being able to claim much of an overview of how rendering occurs, it seems like you would want to somehow take this into account in the filter nbconvert.html.HTMLExporter.markdown2html (which does not see the NotebookNode itself, but if you don't mind adding this as state, you could do so in from_notebook_node).

@platise
Copy link

platise commented Mar 14, 2018

Thank you @fuglede it is a great work-around export lib for the HTML output!

@platise
Copy link

platise commented Mar 14, 2018

Have wrapped it together so anybody can immediately use it:

Usage: ipy2html.py filename.ipynb [--slides]

ipy2html.py.gz

@imcomking
Copy link

Hello guys. Thanks for your workaround code snippets.

I slightly changed @platise's code which can handle multiple non-unique attachments.

import nbformat
import nbconvert
import sys

if len(sys.argv) < 2:
    print("Usage:", sys.argv[0], 'filename.ipynb', '[--slides]')
    exit(-1)

with open(sys.argv[1]) as nb_file:
    nb_contents = nb_file.read()

# Convert using the ordinary exporter
notebook = nbformat.reads(nb_contents, as_version=4)
if len(sys.argv) == 3 and sys.argv[2] == '--slides':
    outname = sys.argv[1].split('.ipynb')[0] + '.slides.html'
    print("Converting to slides:", outname)    
    exporter = nbconvert.SlidesExporter()    
else:
    outname = sys.argv[1].split('.ipynb')[0] + '.html'
    print("Converting to HTML:", outname)
    exporter = nbconvert.HTMLExporter()
    
body, res = exporter.from_notebook_node(notebook)

# Create a list saving all image attachments to their base64 representations
images = []
for cell in notebook['cells']:
    if 'attachments' in cell:
        attachments = cell['attachments']
        for filename, attachment in attachments.items():
            for mime, base64 in attachment.items():
                images.append( [f'attachment:{filename}', f'data:{mime};base64,{base64}'] )

# Fix up the HTML and write it to disk
for itmes in images:
    src = itmes[0]
    base64 = itmes[1]
    body = body.replace(f'src="{src}"', f'src="{base64}"', 1)
    
with open(outname, 'w') as output_file:
    output_file.write(body)

The usage is same.

ipy2html.py

@tonycpsu
Copy link

tonycpsu commented May 2, 2018

For what it's worth, I've had success with the Export HTML with Embedded Images extension. Not sure if there's a motivating use case that's not handled by it, but it works for me.

@platise
Copy link

platise commented May 2, 2018

Thanks @imcomking for upgrade, works well! and also handles exports where Embedded HTML doesn't work, with ref to @tonycpsu

@carlthome
Copy link

Status on this?

@boffi
Copy link

boffi commented Jun 1, 2018

The proposed workarounds are fine but afaict nbviewer has no use for them and images embedded via MarkDown are rendered, e.g., with the string ![My beautiful washing machine](drawing.svg) displayed directly in the rendered notebook.

@Nikolai-Hlubek
Copy link

Thank you @imcomking and @platise for publishing your workarounds. They work fine.

Ultimately it would be nice, if nbconvert could implement this functionality as well.

@MSeal
Copy link
Contributor

MSeal commented Mar 21, 2019

We're always open to a nice PR :) I probably don't have time to move the work-around in and test it thoroughly for a while. But I'm trying to may attention to new PR contributions and not let them linger indefinitely.

@mgeier
Copy link
Contributor

mgeier commented Mar 21, 2019

I tried the example at the top of this page with master, and it worked as expected.

So I guess this is resolved?
I'm not sure if it's in a release yet, though.

@maartenbreddels
Copy link
Collaborator

For reference, this is partly solved in #780 indeed, but i'm working on a fix and possible improvement in #980

@antoinecarme
Copy link

Nice to have.

@t-makaro
Copy link
Contributor

t-makaro commented Aug 1, 2019

This issue appears resolved by #980 (#1057 notwithstanding). However, this issue does appear to still occur for the PDFExporter, but I will open a separate issue for that.

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