> On Jan 10, 2025, at 8:59 AM, Richard H Stanton <[email protected]> wrote:
>
>>
>> On Jan 10, 2025, at 1:47 AM, Rens Oliemans <[email protected]> wrote:
>>
>> Richard H Stanton <[email protected]> writes:
>>
>>> what are the recommended headers for a Python code block that exports a
>>> table? For example, ":results output raw” and ":results output drawer” both
>>> seem to work (without :wrap), while “:results output” puts everything in an
>>> example block, which then seems to get exported verbatim, not as a LaTeX
>>> table.
>>
>> Take a look at
>> https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-python.html. I
>> found
>> this link in the Org manual, "(org) Results of Evaluation", and then to
>> "Documentation" link of python. From that page:
>>
>> :results {output, value}: Output results come from whatever the python code
>> prints on stdout. Value results are the value of the last expression
>> evaluated in the code block. Value mode is the default (as with other
>> languages). In value mode you can use the following subtypes:
>>
>> verbatim: value is returned as string. In particular, use this to
>> prevent conversion of lists and tuples to tables.
>>
>> table: (Org 9.7+) Try to convert the result to an Org table. Dicts,
>> numpy arrays, and pandas DataFrames/Series can be returned as tables
>> this way (by default, they are printed verbatim). Note that lists and
>> tuples are already converted to table by default (use verbatim to
>> prevent that).
>>
>> So, ':results output' will output whatever python prints to stdout. With
>> 'print()', I think that this will just be a string, and no conversion will
>> take
>> place. If you specify 'output raw', python will still just print the string,
>> but
>> *Org mode* will now interpret it as raw Org mode. This will probably work
>> fine,
>> but you'll have to add '|' and newlines in your string correctly.
>> Alternative:
>>
>> ':results value', the default. In this case ob-python will convert lists and
>> tuples to tables by default (and optionally, dicts and DataFrames as well).
>>
>> That would be my recommendation: a code block with the default headers, which
>> returns a list of lists. I've attached an org file which does this.
>>
>>> I actually generate this table from a Python code block. In the past, I’ve
>>> often run into problems with raw output (like this), where running the code
>>> block multiple times causes the output to appear multiple times, rather
>>> than overwriting.
>>
>> ':results append' will cause the output to appear multiple times, but I
>> expect
>> that it happened due to other circumstances (':results replace' is default
>> and I
>> expect you didn't change that). One such circumstance is when you, say, add a
>> ':results output' header argument, and then change it back. For reasons
>> unknown
>> to me, Org mode will then see the previous #+RESULTS: block as unrelated to
>> the
>> current one, and will not replace it.
>>
>> This is then kind of annoying, because you'll have to add the #+ATTR_LATEX:
>> line
>> to the table again. I'd fix this manually, but if it gets annoying you can
>> use
>> the suggestion by PA.
>
>
> Thanks, Rens. Lots of useful information!
>
> Regarding output appearing multiple times, I realize it’s not tables that are
> the prime offender. It’s more when I’m outputting text, usually trying to get
> Python to generate LaTeX code, e.g., after symbolically solving a system of
> equations in Python.
>
> Here’s an example:
>
> #+begin_src python :results output replace raw
> print("a")
> #+end_src
>
> Every time I run this code block, I get another line containing “a”. If I
> don't use the raw option, e.g.,
>
> #+begin_src python :results output
> print("a")
> #+end_src
>
> the multiple-output problem goes away, but now it appears as
>
> #+RESULTS:
> : a
>
> The extra “: “ interferes with LaTeX if I’ve just output something like
> “\begin{equation}”, which is why I’m using raw in the first place.
>
> Wrapping the output in a LaTeX environment helps, e.g.,
>
> #+begin_src python :results output raw :wrap flushleft
> print("a")
> #+end_src
>
> But is there a “preferred” way to output arbitrary text (e.g., LaTeX
> equations) from Python code blocks so that they compile fine *and* don’t
> append?
>
> Thanks for this discussion. This is about where I get to every time I think I
> want to use org mode to create LaTeX documents with embedded, live
> calculations, and then after wrestling with the headers for a while I tend to
> go back again to separate .py and .tex files controlled by GNU Make…
After a bit of experimentation, I think the solution is to put results in a
drawer, e.g.,
#+begin_src python :results output raw drawer
print("a")
#+end_src
This produces
#+RESULTS:
:results:
a
:end:
This exports to LaTeX vey nicely and (I assume because it's obvious where the
end is) org doesn’t over-write when you rerun the code block.
Just one more thing that might be helpful: I run various packages that fold
and/or hide drawers because most of the time I don’t want to see them. But now
I *do* want to see :results: drawers. So I created some functions (with the
help of ChatGPT) to make sure :results: drawers are always visible:
——
(defun org-open-drawer-if-closed ()
(interactive)
"Open the drawer at point if it is closed."
(when (and (looking-at org-drawer-regexp) (not (org-at-item-p)))
(save-excursion
(let ((element (org-element-at-point)))
(when (eq (org-element-type element) 'drawer)
(org-flag-drawer nil))))))
(defun my-org-unfold-results-drawers (&optional state)
"Unfold all :results: drawers in the current buffer.
STATE is ignored and is only present to match the signature for functions
used in `org-cycle-hook`."
(interactive)
(save-excursion
(goto-char (point-min))
(while (re-search-forward "^[ \t]*:results:$" nil t)
;; Go to the beginning of the line with :results:
(beginning-of-line)
;; Unfold the drawer using org-cycle
(org-open-drawer-if-closed)
;; Move forward to avoid toggling the same drawer again
(forward-line))))
(add-hook 'org-mode-hook
(lambda ()
(my-org-unfold-results-drawers)
(add-hook 'org-cycle-hook #'my-org-unfold-results-drawers)))
——