> On Jan 10, 2025, at 8:59 AM, Richard H Stanton <rhstan...@berkeley.edu> wrote: > >> >> On Jan 10, 2025, at 1:47 AM, Rens Oliemans <ha...@rensoliemans.nl> wrote: >> >> Richard H Stanton <rhstan...@berkeley.edu> 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))) ——