johanwk / elot

Emacs Literate Ontology Tool
GNU General Public License v3.0
7 stars 3 forks source link

sparql/turtle/omn prefix insertion #28

Open VladimirAlexiev opened 6 months ago

VladimirAlexiev commented 6 months ago

This inserts a prefix using appropriate syntax for a variety of modes (codeblock langs), using prefix.cc and wikidata prefixes.

(defvar my-rdf-prefix-alist-wikidata
  '(("wd" . "http://www.wikidata.org/entity/")
    ("wds" . "http://www.wikidata.org/entity/statement/")
    ("wdv" . "http://www.wikidata.org/value/")
    ("wdt" . "http://www.wikidata.org/prop/direct/")
    ("wikibase" . "http://wikiba.se/ontology#")
    ("p" . "http://www.wikidata.org/prop/")
    ("ps" . "http://www.wikidata.org/prop/statement/")
    ("pq" . "http://www.wikidata.org/prop/qualifier/")
    ("rdfs" . "http://www.w3.org/2000/01/rdf-schema#")
    ("bd" . "http://www.bigdata.com/rdf#"))
  "Wikidata prefixes to complement rdf-prefix-alist. http://prefix.cc forbids single-char prefixes, so")

;; stolen from https://github.com/simenheg/rdf-prefix
(defun my-rdf-prefix-insert (prefix)
  "Insert URI associated with PREFIX, using Turtle or SPARQL syntax, according to major mode or org-babel language.
Prefixes are defined by `rdf-prefix-alist' (prefix.cc) and complemented with `my-rdf-prefix-alist-wikidata'."
  (interactive
   (progn
     (eval-and-compile (require 'rdf-prefix))
     (unless (assoc "p" rdf-prefix-alist)
       (setq rdf-prefix-alist (append my-rdf-prefix-alist-wikidata rdf-prefix-alist)))
     (list (completing-read
            "RDF prefix: " rdf-prefix-alist nil t nil 'rdf-prefix-history))))
  (let* ((lang (and (eq major-mode 'org-mode)
                    ;; org-mode can tell us the language per code block
                    (nth 0 (org-babel-get-src-block-info 'light))))
         (shaclc (or (eq major-mode 'SHACLC-mode)
                     ;; (string-match-p "\\.shaclc$" (buffer-file-name))
                     (member lang '("shaclc" "SHACLC"))))
         (turtle (and (not shaclc)
                      (or (memq major-mode '(n3-mode Turtle-mode))
                          (member lang '("n3" "N3" "ttl" "turtle" "Turtle")))))
         (omn (or (eq major-mode 'omn-mode)
                  (member lang '("omn" "manchester")))) ; Manchester notation
          ;; markdown doesn't report the lang of ``` blocks, so I'll assume it's SPARQL
         (sparql (or (memq major-mode '(sparql-mode SPARQL-mode xsparql-mode markdown-mode))
                     (member lang '("sparql" "SPARQL")))))
    (insert (if turtle "@" "")
            (if shaclc "PREFIX " (if (or turtle sparql) "prefix " (if omn "Prefix: ") ""))
            prefix ": "
            (if (or shaclc turtle omn sparql) "<" "")
            (rdf-prefix-lookup prefix)
            (if (or shaclc turtle omn sparql) ">" "")
            (if turtle " ." ""))))
johanwk commented 6 months ago

This looks useful, but I've so far taken a special approach to handling prefixes -- a table with #+name: prefix-table is a single source for all prefixes to be used under a heading for an ontology. This is inserted as part of the <os template. The table is read by org-babel code blocks to produce sparql-prefixes, omn-prefixes, and ttl-prefixes. So, maybe that means we already have this covered?

My thinking, here, is that the user should not need to worry about keeping prefixes in sync across different types of code blocks, for most common tasks.

The list of Wikidata prefixes looks really helpful. I would love to have some tempo templates that could make it easier to get started with Wikidata queries -- I think the way Wikidata is set up, it's quite hard for an occasional user (like myself).

VladimirAlexiev commented 6 months ago

Quite agree, with some additions:

johanwk commented 6 months ago

Quite agree, with some additions:

* How about producing `prefixes.ttl` from the table? That is used by `rdfpuml`

Absolutely. Here's a suggestion: When the user invokes a call to rdfpuml -- using something like rdfpuml-block in elot-lob.org (that block needs a whole lot of improvement, by the way! not finished!) -- we can write the content of ttl-prefixes out to file, so it's updated.

Question. Does rdfpuml maybe require some prefixes that would typically not be included in the ontology itself? If so, we should remember to include those as well.

* The prefix insertion function could be used to add prefixes to the table?
  I use it very often when making some turtle file, but for an ontology you'd collect prefixes once then work on the ontology for a month, so it's not that important.

Yes, absolutely. Maybe in some kind of combination with the package rdf-prefix?

VladimirAlexiev commented 6 months ago

rdfpuml predefines these

   crm    => 'http://www.cidoc-crm.org/cidoc-crm/',
   crmx   => 'http://purl.org/NET/cidoc-crm/ext#',
   frbroo => 'http://example.com/frbroo/',
   crmdig => 'http://www.ics.forth.gr/isl/CRMdig/',
   crmsci => 'http://www.ics.forth.gr/isl/crmsci/',
   puml   => 'http://plantuml.com/ontology#',
   rdf    => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
   rdfs   => 'http://www.w3.org/2000/01/rdf-schema#',
   skos   => 'http://www.w3.org/2004/02/skos/core#',
   leak   => 'http://data.ontotext.com/resource/leak/',

The code above uses rdf-prefix, see

(eval-and-compile (require 'rdf-prefix))
johanwk commented 6 months ago

rdfpuml predefines these

I suppose those are defined and used "inside" the rdfpuml code, so would not need to be added to prefixes.ttl?

There will perhaps be a slight possibility of a clash, if a user decides to introduce one of the mentioned prefixes with a different expansion. Is this something we need to worry about/check for?

The code above uses rdf-prefix, see

Sorry, I should have seen that!

Proposal -- maybe we could do the following: introduce a tempo template for adding a new row to prefix-table. The user would add something like <op("p" for "prefix") to a blank line in the table, and expand with Tab to be presented with a choice of prefix.

The template definition can include code for looking up common prefixes, using something like your code at the top of this issue. There's an example at the end of the org-tempo.el library that uses read-file-name for selecting a filename with completion, which may be a convenient starting point.

VladimirAlexiev commented 6 months ago

"inside" the rdfpuml code, so would not need to be added to prefixes.ttl?

Yes. (But I still add puml, rdf, rdfs, owl to prefixes.ttl to avoid flycheck errors).

possibility of a clash

puml is my own, rdf, rdfs, skos are canonical, the rest are quite esoteric (the CRM prefixes are used to visualize CRM reification). So I'm not very worried about a clash.