> 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)))



——



Reply via email to