sparql-mode icon indicating copy to clipboard operation
sparql-mode copied to clipboard

Support :prologue header argument in ob-sparql.el

Open johanwk opened this issue 11 months ago • 2 comments

A small change to org-babel-expand-body:sparql allows for :prologue and :epilogue header arguments on SPARQL blocks in org-mode. With this, the list of query prefixes can kept in a single place, and sparql queries take up less space in the org file.

I find the following works for me -- replacing (insert body) in the current version of org-babel-expand-body:sparql to add the contents of prologue and epilogue header arguments.

  (defun org-babel-expand-body:sparql (body params)
    "Expand BODY according to PARAMS, returning expanded body.
  A variable is marked by the use of '?' or '$'; the marker is not
  part of the variable name, thus '?x' and '$x' refer to the same
  variable."
    (with-temp-buffer
;; from here
      (insert (mapconcat 'identity
                         (list (cdr (assq :prologue params))
                               body
                               (cdr (assq :epilogue params)))
                         "\n"))
;; to here
      (let ((case-fold-search nil)
            (case-replace nil))
        (dolist (pair (org-babel--get-vars params))
          (goto-char (point-min))
          (let ((regexp (concat "[$?]" (regexp-quote (format "%s" (car pair)))))
                (replacement (cdr pair)))
            (while (re-search-forward regexp nil t)
              (replace-match replacement nil nil)))))
      (buffer-string)))

How this can be used:

First, keep prefixes in block of its own. Here, the prefixes are neatly listed in an org table.

* Prefix block
#+name: prefix-table
| uri                                         | prefix    |
|---------------------------------------------+-----------|
| http://www.w3.org/2002/07/owl#              | owl:      |
| http://www.w3.org/1999/02/22-rdf-syntax-ns# | rdf:      |
| http://www.w3.org/2000/01/rdf-schema#       | rdfs:     |
| http://purl.obolibrary.org/obo/             | obo-term: |

#+name: sparql-prefixes
#+begin_src emacs-lisp :var prefixes=prefix-table
  (mapconcat (lambda (row) (format "PREFIX %-5s <%s>" (cadr row) (car row)))
             prefixes "\n")
#+end_src

Second, put the :prologue header argument in a property drawer for a section.

* My queries, using Ontobee
:PROPERTIES:
:header-args:sparql: :url https://sparql.hegroup.org/sparql/
:header-args:sparql+: :prologue (org-sbe sparql-prefixes)
:END:

** Query: Example 2 from https://ontobee.org/sparql
#+begin_src sparql 
SELECT DISTINCT ?x ?label
from <http://purl.obolibrary.org/obo/merged/OAE>
WHERE
{
?x rdfs:subClassOf obo-term:OAE_0000001.
?x rdfs:label  ?label.
} 
limit 3
#+end_src

#+RESULTS:
| x                                          | label                             |
|--------------------------------------------+-----------------------------------|
| http://purl.obolibrary.org/obo/OAE_0000003 | causal adverse event              |
| http://purl.obolibrary.org/obo/OAE_0000004 | vaccine adverse event             |
| http://purl.obolibrary.org/obo/OAE_0000008 | nutritional product adverse event |

johanwk avatar Mar 20 '24 08:03 johanwk