emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [O] org-exp-bibtex missing in git?


From: aaronecay
Subject: Re: [O] org-exp-bibtex missing in git?
Date: Fri, 08 Mar 2013 14:29:36 -0500
User-agent: Notmuch/0.15.2+43~ge848af8 (http://notmuchmail.org) Emacs/24.3.50.1 (x86_64-unknown-linux-gnu)

Hello Bastien (et al),

2013ko martxoak 7an, Bastien-ek idatzi zuen:
> 
> Hi Nicolas,
> 
> I like Aaron's idea (maybe others proposed this too) of having
> parameters in links:
> 
> [[file:my.bib::key&&prenote=my prenote&&postnote=my postnote]]
> 
> [[http://perdu.com&&title=You're lost?]]
> 
> This is orthogonal to my proposal of extending #+LINK to be able
> to define new protocols (by allowing to add a follow and an export
> functions); and this is orthogonal to whether link abbrevs can have
> more than one formatting string %s.
> 
> We would just need to pass the parameters as keywords to the export
> function, either the default one, either the defined by the protocol.
> 
> E.g., the first link would be represented by the parser like this:
> 
>    (:type "file"
>     :path "my.bib"
>     :raw-link "file:orgmode.org::test2"
>     :application nil
>     :search-option "test2"
>     :parameters '(:title "You're lost")
>     :begin 63
>     :end 97
>     :contents-begin 90
>     :contents-end 95
>     :post-blank 0
>     :parent #3)

This is now implemented, in the first of three patches attached to this
email.  The second patch is a reworked version of the bibliography
support in my last patch, and the third implements link attributes for
HTML links.

To Nicolas:

> I think that if we ever implement a bibliography/citations handlers,
> they should be first class objects in Org syntax (like footnotes).
> Overloading link syntax would, IMO, be wrong in that case.

Do you have a proposal for how this syntax would look?  You certainly
know the parser very well, so you probably have an idea of what will
work and not conflict with other things.  I think minimally we need
to include info on:
- how to look up the citation (DOI, arXiv id, in a bibtex file, ...)
- how to display/export the citation (parens, footnote, in-text, ...)
- a list of properties (incl. at least pre- and post-note)
- (of course) the citation key

So maybe:

[cite:lookup-type:display-type:key:prop1=val1,prop2=val2]

Alternatively, the lookup-type and display-type could just be made
properties, as long as there is a clear notion of what the default for
these should be.

>From 69e7a98a2f8044362597de31789b43b955e1fc7a Mon Sep 17 00:00:00 2001
From: Aaron Ecay <address@hidden>
Date: Fri, 8 Mar 2013 13:31:38 -0500
Subject: [PATCH 1/3] Add support for link properties
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/org-element.el (org-element-link-parser): include :properties in
  plist of parsed link
* lisp/org.el (org-make-link-string): don’t escape properties
* lisp/ox-html.el (org-html-link)
  lisp/ox-latex.el (org-latex-link): pass link properties to
  org-link-protocols functions

The properties of a link are appended to the link path, separated by the
string “&&”.  Each property should have the form key=val.  No escaping
is applied to key or val, and they must not contain an “=” character.

The properties of a link are passed as the optional fourth argument to
export functions defined by org-add-link-type and
org-link-protocols.  (Currently only for the HTML and LaTeX backends).
---
 lisp/org-element.el | 18 ++++++++++++++----
 lisp/org.el         | 15 +++++++++------
 lisp/ox-html.el     |  3 ++-
 lisp/ox-latex.el    |  3 ++-
 4 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/lisp/org-element.el b/lisp/org-element.el
index 6810b98..b944ffd 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -2982,7 +2982,7 @@ Assume point is at the beginning of the link."
   (save-excursion
     (let ((begin (point))
          end contents-begin contents-end link-end post-blank path type
-         raw-link link search-option application)
+         raw-link link search-option application properties)
       (cond
        ;; Type 1: Text targeted from a radio target.
        ((and org-target-link-regexp (looking-at org-target-link-regexp))
@@ -2998,9 +2998,18 @@ Assume point is at the beginning of the link."
              ;; abbreviation in it.
              raw-link (org-translate-link
                        (org-link-expand-abbrev
-                        (org-match-string-no-properties 1)))
-             link (org-link-unescape raw-link))
-       ;; Determine TYPE of link and set PATH accordingly.
+                        (org-match-string-no-properties 1))))
+       (when (string-match "&&" raw-link)
+         (let ((components (split-string raw-link "&&"))
+               p)
+           (setq raw-link (nth 0 components))
+           (dolist (prop (cdr components))
+             (setq p (split-string prop "="))
+             (setq properties (plist-put properties
+                                         (intern (concat ":" (nth 0 p)))
+                                         (nth 1 p))))))
+        (setq link (org-link-unescape raw-link))
+        ;; Determine TYPE of link and set PATH accordingly.
        (cond
         ;; File type.
         ((or (file-name-absolute-p link) (string-match "^\\.\\.?/" link))
@@ -3058,6 +3067,7 @@ Assume point is at the beginning of the link."
                  :raw-link (or raw-link path)
                  :application application
                  :search-option search-option
+                 :properties properties
                  :begin begin
                  :end end
                  :contents-begin contents-begin
diff --git a/lisp/org.el b/lisp/org.el
index 811506a..5611adb 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -9449,12 +9449,15 @@ according to FMT (default from 
`org-email-link-description-format')."
             (not (string-match (org-image-file-name-regexp) link))
             (not (equal link (org-link-escape link))))
     (setq description (org-extract-attributes link)))
-  (setq link
-       (cond ((string-match (org-image-file-name-regexp) link) link)
-             ((string-match org-link-types-re link)
-              (concat (match-string 1 link)
-                      (org-link-escape (substring link (match-end 1)))))
-             (t (org-link-escape link))))
+  (let ((parts (split-string link "&&")))
+    (setq link (nth 0 parts))
+    (setq link
+         (cond ((string-match (org-image-file-name-regexp) link) link)
+               ((string-match org-link-types-re link)
+                (concat (match-string 1 link)
+                        (org-link-escape (substring link (match-end 1)))))
+               (t (org-link-escape link))))
+    (setq link (mapconcat #'identity (cons link (cdr parts)) "&&")))
   (concat "[[" link "]"
          (if description (concat "[" description "]") "")
          "]"))
diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 829fe28..9d5fdc7 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -2630,7 +2630,8 @@ INFO is a plist holding contextual information.  See
                        (org-export-resolve-coderef path info)))))
      ;; Link type is handled by a special function.
      ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
-      (funcall protocol (org-link-unescape path) desc 'html))
+      (funcall protocol (org-link-unescape path) desc
+               'html (org-element-property :properties link)))
      ;; External link with a description part.
      ((and path desc) (format "<a href=\"%s\"%s>%s</a>" path attributes desc))
      ;; External link without a description part.
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index d17dd60..a1cacf0 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1948,7 +1948,8 @@ INFO is a plist holding contextual information.  See
              (org-export-resolve-coderef path info)))
      ;; Link type is handled by a special function.
      ((functionp (setq protocol (nth 2 (assoc type org-link-protocols))))
-      (funcall protocol (org-link-unescape path) desc 'latex))
+      (funcall protocol (org-link-unescape path) desc
+               'latex (org-element-property link :properties)))
      ;; External link with a description part.
      ((and path desc) (format "\\href{%s}{%s}" path desc))
      ;; External link without a description part.
-- 
1.8.1.5

>From 6428103e7199acbf947cacaa5860ac39b3b78b46 Mon Sep 17 00:00:00 2001
From: Aaron Ecay <address@hidden>
Date: Fri, 8 Mar 2013 13:41:00 -0500
Subject: [PATCH 2/3] Support bibliographies for export

* lisp/ox.el (org-export-options-alist): Add BIBLIOGRAPHY
* lisp/ox-latex.el (org-latex-template): Support bibliographies
* lisp/ox-bib.el: Add file

Add export support for bibliographies.  Currently only works for
BibLaTeX, using the latex backend.  To use, put
#+BIBLIOGRAPHY: file.bib
in the header of the document, and (require 'ox-bib).  Then use
links of the form:
[[textcite:bibtex-key&&pre=foo&&post=bar][whatever]]
which will be exported to:
\textcite[foo][bar]{bibtex-key}
Using parencite as a link type is also supported.

The BIBLIOGRAPHY keyword in the header will be translated to an
appropriate \addbibresource command.
---
 lisp/ox-bib.el   | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lisp/ox-latex.el |  8 +++++
 lisp/ox.el       |  1 +
 3 files changed, 98 insertions(+)
 create mode 100644 lisp/ox-bib.el

diff --git a/lisp/ox-bib.el b/lisp/ox-bib.el
new file mode 100644
index 0000000..a3f9de9
--- /dev/null
+++ b/lisp/ox-bib.el
@@ -0,0 +1,89 @@
+(require 'bibtex)
+(require 'ox)
+
+(defvar ox-bib-find-entries-in-org-file nil
+  "Whether to look for bibliogrpahy entries in an org mode file
+or a bibtex file.")
+
+(defun ox-bib-get-bibliography ()
+  (mapcar (lambda (s)
+            (org-no-properties s))
+         ;; Don't explode if before the first headline
+          (or
+           (condition-case nil
+               (plist-get (org-export-get-environment nil t) :bibliography)
+             (error nil))
+           (save-excursion
+             (widen)
+             (goto-char (point-min))
+             (plist-get (org-export-get-environment) :bibliography)))))
+
+;; Adapted from org-find-entry-with-custom-id; there might be a better
+;; way to do this
+(defun org-find-entry-with-custom-id (ident)
+  (let ((id ident)
+        (case-fold-search nil))
+    (save-excursion
+      (save-restriction
+        (widen)
+        (goto-char (point-min))
+        (when (re-search-forward
+               (concat "^[ \t]*:CUSTOM_ID:[ \t]+" (regexp-quote id) "[ \t]*$")
+               nil t)
+          (org-back-to-heading t)
+          (point))))))
+
+(defun ox-bib-cite-follow (path)
+  (let* ((files (ox-bib-get-bibliography))
+        (key (ox-bib-get-key path))
+        file done)
+    (when ox-bib-find-entries-in-org-file
+      (setq files
+           (mapcar (lambda (s)
+                     (replace-regexp-in-string "\\.bib\\'" ".org" s))
+                   files)))
+    (while (and (car-safe files) (not done))
+      (setq file (car-safe files))
+      (when (file-exists-p file)
+        (let* ((buf (find-file-noselect file))
+
+              (pos (with-current-buffer buf
+                     (cond
+                      (ox-bib-find-entries-in-org-file
+                       (org-find-entry-with-custom-id key))
+                      (t (bibtex-search-entry key))))))
+         (when pos
+           (setq done (cons buf pos)))))
+      (setq files (cdr files)))
+    (if done
+       (progn
+          (pop-to-buffer (car done))
+         (goto-char (cdr done))
+          (when ox-bib-find-entries-in-org-file
+            (org-show-context)))
+      (message "Citation not found: %s" key))))
+
+(defun ox-bib-textcite-export (path desc format &optional props)
+  (cond
+   ((org-export-derived-backend-p format 'latex)
+    (format "\\textcite[%s][%s]{%s}"
+           (plist-get props :pre)
+           (plist-get props :post)
+           key))
+   (t
+    (format "[textcite to: %s]" path))))
+
+(defun ox-bib-parencite-export (path desc format &optional props)
+  (cond
+   ((org-export-derived-backend-p format 'latex)
+    (format "\\parencite[%s][%s]{%s}"
+            (plist-get props :pre)
+            (plist-get props :post)
+            key))
+   (t
+    (format "[parencite to: %s]" path))))
+
+(org-add-link-type "textcite" #'ox-bib-cite-follow #'ox-bib-textcite-export)
+(org-add-link-type "parencite" #'ox-bib-cite-follow #'ox-bib-parencite-export)
+
+(provide 'ox-bib)
diff --git a/lisp/ox-latex.el b/lisp/ox-latex.el
index a1cacf0..08cdd18 100644
--- a/lisp/ox-latex.el
+++ b/lisp/ox-latex.el
@@ -1192,6 +1192,14 @@ holding export options."
               (or (plist-get info :description) "")
               (if (not (plist-get info :with-creator)) ""
                 (plist-get info :creator))))
+     ;; Bibliography
+     (let* ((bibs (plist-get info :bibliography))
+            (bib-cmds (mapconcat (lambda (s)
+                                   (format "\\addbibresource{%s}" s))
+                                 bibs "\n")))
+       (if bibs
+          (concat bib-cmds "\n")
+        ""))
      ;; Document start.
      "\\begin{document}\n\n"
      ;; Title command.
diff --git a/lisp/ox.el b/lisp/ox.el
index 40c0617..f405eff 100644
--- a/lisp/ox.el
+++ b/lisp/ox.el
@@ -118,6 +118,7 @@
     (:select-tags "SELECT_TAGS" nil org-export-select-tags split)
     (:time-stamp-file nil "timestamp" org-export-time-stamp-file)
     (:title "TITLE" nil nil space)
+    (:bibliography "BIBLIOGRAPHY" nil nil split)
     (:with-archived-trees nil "arch" org-export-with-archived-trees)
     (:with-author nil "author" org-export-with-author)
     (:with-clocks nil "c" org-export-with-clocks)
-- 
1.8.1.5

>From 8aaf0718e2d43195cc42ff9bbf2b0e0d6eff4bcf Mon Sep 17 00:00:00 2001
From: Aaron Ecay <address@hidden>
Date: Fri, 8 Mar 2013 13:44:17 -0500
Subject: [PATCH 3/3] Support properties for HTML links

* lisp/ox-html.el (org-html-link--inline-image): use link properties in
  addition to ATTR_HTML ones
  (org-html--properties-to-attributes): new function
  (org-html-link): use link properties instead of ATTR_HTML ones

Link attributes of the form [[http://test.com/&&key=value]] will be
translated to <a href="http://test.com/"; key="value"> upon export.  For
image links which are exported inline, the key="value" will be inserted
in the img tag.
---
 lisp/ox-html.el | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/lisp/ox-html.el b/lisp/ox-html.el
index 9d5fdc7..fe2e10c 100644
--- a/lisp/ox-html.el
+++ b/lisp/ox-html.el
@@ -2405,7 +2405,8 @@ used as a communication channel."
         (parent (org-export-get-parent-element link))
         (caption (org-export-data (org-export-get-caption parent) info))
         (label (org-element-property :name parent))
-        (attr (mapconcat #'identity (org-element-property :attr_html parent) " 
")))
+        (attr (concat (mapconcat #'identity (org-element-property :attr_html 
parent) " ")
+                      (org-html--properties-to-attributes 
(org-element-property :properties link)))))
     ;; Return proper string, depending on DISPOSITION.
     (org-html-format-inline-image
      path caption label attr (org-html-standalone-image-p link info))))
@@ -2454,6 +2455,20 @@ standalone images, do the following.
                           (= (incf inline-image-count) 1)))
                        (t nil))))))))
 
+(defun org-html--properties-to-attributes (properties)
+  "Convert a plist of link properties to an HTML attribtes string.
+
+For a plist having the form (:key1 \"value1\" ...), returns a
+string of the form \"key1=\\\"value1\\\" ...\"."
+  (mapconcat #'identity
+             (loop for key in properties by 'cddr
+                   collect (concat " "
+                                   (substring (symbol-name key) 1)
+                                   "=\""
+                                   (plist-get properties key)
+                                   "\""))
+             ""))
+
 (defun org-html-link (link desc info)
   "Transcode a LINK object from Org to HTML.
 
@@ -2507,24 +2522,9 @@ INFO is a plist holding contextual information.  See
                                             (mapconcat 'number-to-string
                                                        numbers "-")))))))))
           (t raw-path)))
-        attributes protocol)
-    ;; Extract attributes from parent's paragraph. HACK: Only do this
-    ;; for the first link in parent.  This is needed as long as
-    ;; attributes cannot be set on a per link basis.
-    (and (setq attributes
-              (let ((parent (org-export-get-parent-element link)))
-                (if (not (eq (org-element-map parent 'link 'identity info t)
-                             link))
-                    ""
-                  (mapconcat
-                   'identity
-                   (let ((att (org-element-property :attr_html parent)))
-                     (unless (and desc att
-                                  (string-match (regexp-quote (car att)) desc))
-                       att))
-                   " "))))
-        (unless (string= attributes "")
-          (setq attributes (concat " " attributes))))
+        (properties (org-element-property :properties link))
+        (attributes (org-html--properties-to-attributes properties))
+        protocol)
     (cond
      ;; Image file.
      ((and (or (eq t org-html-inline-images)
-- 
1.8.1.5


-- 
Aaron Ecay

reply via email to

[Prev in Thread] Current Thread [Next in Thread]