jupyter
jupyter copied to clipboard
Results :file does not work.
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.
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.
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:
- Override the method above
- Add a source block with
(org-element-interpret-data (jupyter-org-export-block 'html (f-read-text fpath 'utf-8)))namedinsert-html, wherefpathis a variable for the block. - Execute block that returns huge HTML with
:file, thus persisting the result - 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.
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!
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:
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]]