jkitchin / org-ref

org-mode modules for citations, cross-references, bibliographies in org-mode and useful bibtex tools to go with it.
GNU General Public License v3.0
1.35k stars 242 forks source link

Names with colons don't seem to work in :var assignments #1093

Closed drghirlanda closed 7 months ago

drghirlanda commented 9 months ago

Note: I realize this is more org-mode than org-ref, and I have asked on stackexchange, but after a few days without answers I'll give it a shot here too. Feel free to close if irrelevant!

I have source blocks that take input from tables using the :var NAME=ASSIGN mechanism. It looks like org-mode always interprets a colon in ASSIGN as a filename (this is what the manual says) and so it cannot find references like tab:mytable. I have tried escaping in various ways but I have found no solution. For example, none of these work:


| x |
|---|
| 1 |

# reference not found
#+begin_src R :var data=tab:one
  data$x
#+end_src

# reference not found
#+begin_src R :var data=tab\:one
  data$x
#+end_src

# assigns the string "tab:one", not table content
#+begin_src R :var data="tab:one"
  data$x
#+end_src

# same as above
#+begin_src R :var data='tab:one'
  data$x
#+end_src

I have looked a bit in ob-core.el but I haven't figured out yet where this is handled.

jkitchin commented 9 months ago

I believe this happens in org-babel-ref-resolve in the case where (string-match "^\\(.+\\):\\(.+\\)$" ref). It does not look possible to bypass that to me without using an override advice, or you could do something like this, adapted from the code in the function I mentioned, just for the tables.

#+BEGIN_SRC emacs-lisp  
(defun get-table (ref)
  (org-with-wide-buffer
   (goto-char (point-min))
   (let* ((regexp (org-babel-named-data-regexp-for-name ref))
      (result
       (catch :found
         ;; Check for code blocks or named data.
         (while (re-search-forward regexp nil t)
           ;; Ignore COMMENTed headings and orphaned
           ;; affiliated keywords.
           (unless (org-in-commented-heading-p)
         (let ((e (org-element-at-point)))
           (when (equal (org-element-property :name e) ref)
             (goto-char
              (org-element-property :post-affiliated e))
             (pcase (org-element-type e) 
               ((and (let v (org-babel-read-element e))
                 (guard v))
            (throw :found v))
               (_ (error "Reference not found")))))))
         (error "Reference `%s' not found in this buffer" ref))))
     result)))
#+END_SRC

#+begin_src R :var data=(get-table "tab:one")
  data$x
#+end_src

#+RESULTS:
| 1 |
| 2 |
drghirlanda commented 9 months ago

Thanks, I'll have a look and give it some thought. Maybe the org people might consider a patch to resolve buffer-local stuff before filenames, given that tab:one is a fairly common idiom in LaTeX. Ambiguities could be resolved prepending ./ or / to filenames so that ./tab:one would look in file ./tab even if tab:one is defined in the buffer.

drghirlanda commented 8 months ago

I have found a workaround for now in that I can use a #+name: without the tab: part for the source block, and then I can include \label{tab:mytable} in the #+caption: line (I guess label:tab:mytable would also work). This makes the table assignable in a :var header argument and usable in LaTeX export. So now this is downgraded from something you cannot do to a minor inconvenience.

drghirlanda commented 8 months ago

Closing because not an org-ref problem.

drghirlanda commented 7 months ago

This has been fixed in org-mode now. It should soon be in ELPA.