From mboxrd@z Thu Jan 1 00:00:00 1970 From: aaronecay@gmail.com Subject: Re: org-exp-bibtex missing in git? Date: Fri, 08 Mar 2013 14:29:36 -0500 Message-ID: <87wqthk7vj.fsf@gmail.com> References: <20130303070635.GA12112@panahar> <87fw0cg42y.fsf@allisson.co> <87vc98be83.fsf@bzg.ath.cx> <87ehfwwgdd.fsf@gmail.com> <87ppzg2r05.fsf@med.uni-goettingen.de> <87ppzgusem.fsf@gmail.com> <87ppzcfy2e.fsf@med.uni-goettingen.de> <87lia0s7wi.fsf@bzg.ath.cx> <876213lqfk.fsf@gmail.com> <87wqtjo6h6.fsf@bzg.ath.cx> <87boavcpzc.fsf@gmail.com> <87fw075ivl.fsf@bzg.ath.cx> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([208.118.235.92]:39178) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UE2zB-0007AA-IQ for emacs-orgmode@gnu.org; Fri, 08 Mar 2013 14:29:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UE2z5-0003n8-6b for emacs-orgmode@gnu.org; Fri, 08 Mar 2013 14:29:45 -0500 Received: from mail-qe0-f47.google.com ([209.85.128.47]:57536) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UE2z4-0003n4-V4 for emacs-orgmode@gnu.org; Fri, 08 Mar 2013 14:29:39 -0500 Received: by mail-qe0-f47.google.com with SMTP id q19so1215103qeb.20 for ; Fri, 08 Mar 2013 11:29:38 -0800 (PST) In-Reply-To: <87fw075ivl.fsf@bzg.ath.cx> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: Bastien Cc: emacs-orgmode@gnu.org, Andreas Leha , Nicolas Goaziou --=-=-= Content-Type: text/plain 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. --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline; filename=0001-Add-support-for-link-properties.patch Content-Transfer-Encoding: quoted-printable >From 69e7a98a2f8044362597de31789b43b955e1fc7a Mon Sep 17 00:00:00 2001 From: Aaron Ecay 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=3DUTF-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=E2=80=99t 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 =E2=80=9C&&=E2=80=9D. Each property should have the form key=3Dval.= No escaping is applied to key or val, and they must not contain an =E2=80=9C=3D=E2=80= =9D 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 "=3D")) + (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-desc= ription-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 "%s" 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. --=20 1.8.1.5 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-Support-bibliographies-for-export.patch >From 6428103e7199acbf947cacaa5860ac39b3b78b46 Mon Sep 17 00:00:00 2001 From: Aaron Ecay 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 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-Support-properties-for-HTML-links.patch >From 8aaf0718e2d43195cc42ff9bbf2b0e0d6eff4bcf Mon Sep 17 00:00:00 2001 From: Aaron Ecay 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 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 --=-=-= Content-Type: text/plain -- Aaron Ecay --=-=-=--