jupyter icon indicating copy to clipboard operation
jupyter copied to clipboard

Results :file does not work.

Open vale981 opened this issue 5 years ago • 5 comments

File output does not seem to be supported for non-image output. After skimming the source code, I see that this header argument is being deleted and not handled any further for text output.

Is this intentional? If it is, it should be mentioned in the docs.

vale981 avatar Apr 03 '20 11:04 vale981

I would also really like to able to save any output to a file, e.g. if the results are HTML but I've specified :file tmp.html then the result should be file:tmp.html rather than #+begin_export html .... This is extremely useful in cases where the session is remote, since actually saving the file and manually referencing won't work:)

I've been looking at the code for a while now and I'm struggling to figure out exactly where things go wrong. Could you point me in the right direction @dzop ? With a bit of guidance I might be able to help out with this issue.

torfjelde avatar May 04 '20 00:05 torfjelde

One hacky way I got the HTML results to respect :file was to do:

(cl-defmethod jupyter-org-result ((_mime (eql :text/html)) content params)
  (if (alist-get :file params)
      (let ((fpath (alist-get :file params)))
        (f-write-text (plist-get content :data) 'utf-8 fpath)
        (jupyter-org-file-link fpath))
    (jupyter-org-export-block-or-pandoc "html" (plist-get content :data) params)))

Would a "solution" be to add such an if for all MIME-types?

Btw, my use-case was as follows:

  • Using remote server
  • Source block returns a huge chunk of HTML that is quite annoying to have in the buffer but that I want to include in export
  • I want to persist the results locally

I "solved" it as follows:

  1. Override the method above
  2. Add a source block with (org-element-interpret-data (jupyter-org-export-block 'html (f-read-text fpath 'utf-8))) named insert-html, where fpath is a variable for the block.
  3. Execute block that returns huge HTML with :file, thus persisting the result
  4. Add a #+CALL: insert-html[:eval query](f="output.html")

This way the results persist, I don't have to deal with a huge #+BEGIN_EXPORT html in my buffer, and the results are still included in export.

torfjelde avatar May 04 '20 01:05 torfjelde

I'd really appreciate if :file worked for non image outputs. Specifically in my case when using sympy I'll sometimes get a latex result that is 4k characters long. Emacs' notoriously bad handling of long lines means that it'll slow emacs down to a crawl trying to insert that result into the buffer. I've been making do with a python function that saves the latex to a file, but having support for a source block header to do that would be fantastic!

akirakyle avatar May 04 '20 03:05 akirakyle

Another possible hack, lifted from here, is to set the mimetype of the output to text/org, and generate the appropriate link yourself. An example with the Altair plotting package (which is actually image output, but without builtin support in emacs-jupyter, so it would benefit from :results file working properly):

#+begin_src jupyter-python
import altair as alt
import seaborn as sns
from IPython.display import publish_display_data

iris = sns.load_dataset("iris")
chart = alt.Chart(iris).mark_circle().encode(
    x="sepal_length",
    y="sepal_width",
    color="species",
)
fname = "chart.png"
chart.save(fname)
publish_display_data({"text/org": f"[[file:{fname}]]"})
#+end_src

#+RESULTS:
:RESULTS:
[[file:chart.png]]
:END:

dlukes avatar Sep 18 '22 12:09 dlukes

Although I've just discovered that for the specific case of Altair, there is a much simpler solution which takes advantage of the possibility to generate image output, which then works perfectly fine with :file ...:

#+begin_src jupyter-python :file chart_via_renderer.png
alt.renderers.enable("png")
chart
#+end_src

#+RESULTS:
[[file:chart_via_renderer.png]]

dlukes avatar Sep 18 '22 12:09 dlukes