From bf3e9aa9a28832992f96c04902937c91cfc67a6a Mon Sep 17 00:00:00 2001 From: Jambunathan K Date: Sat, 17 Sep 2011 00:12:02 +0530 Subject: [PATCH] org-odt.el: Improve how labels are applied and generated. * contrib/lisp/org-odt.el (org-odt-entity-labels-alist, org-odt-entity-counts-plist) (org-odt-label-def-ref-spec): New variables. (org-odt-init-outfile): Reset above variables. (org-odt-add-label-definition, org-odt-get-label-definition) (org-odt-format-label-definition) (org-odt-format-label-reference) (org-odt-fixup-label-references): New functions. (org-export-odt-preprocess-label-references): Modified. (org-odt-end-export): Call `org-odt-fixup-label-references'. (org-odt-parse-label): Removed (org-odt-default-entity): Removed. (org-odt-format-entity-caption): Fixed signature so that category param is no longer optional. Use `org-odt-format-label-definition'. (org-export-odt-do-format-formula) (org-export-odt-do-format-image): Pass the mandatory category param to `org-odt-format-entity-caption'. * contrib/odt/styles/OrgOdtContentTemplate.xml: Add Figure and Equation as sequence declarations. Most of these changes can be pushed to org-exp.el. For now park the changes locally to org-odt.el. --- contrib/lisp/org-odt.el | 152 ++++++++++++++++++++------- contrib/odt/styles/OrgOdtContentTemplate.xml | 2 +- 2 files changed, 117 insertions(+), 37 deletions(-) diff --git a/contrib/lisp/org-odt.el b/contrib/lisp/org-odt.el index 806cdfd1b..7c03745aa 100644 --- a/contrib/lisp/org-odt.el +++ b/contrib/lisp/org-odt.el @@ -31,6 +31,8 @@ (require 'org-lparse) (defun org-odt-end-export () + (org-odt-fixup-label-references) + ;; remove empty paragraphs (goto-char (point-min)) (while (re-search-forward @@ -1204,7 +1206,7 @@ value of `org-export-odt-use-htmlfontify." (let ((extra "")) (org-odt-format-frame href "" width height extra "paragraph")) - (org-odt-format-entity-caption label caption))) + (org-odt-format-entity-caption label caption "Equation"))) "OrgCaptionFrame" width height)))))) (defun org-export-odt-format-formula (src href &optional embed-as) @@ -1465,7 +1467,7 @@ MAY-INLINE-P allows inlining it as an image." (let ((extra " style:rel-width=\"100%\" style:rel-height=\"scale\"")) (org-odt-format-frame href "OrgCaptionedGraphics" width height extra "paragraph")) - (org-odt-format-entity-caption label caption))) + (org-odt-format-entity-caption label caption "Figure"))) "OrgCaptionFrame" width height)))))) (defvar org-odt-embedded-images-count 0) @@ -1552,22 +1554,105 @@ MAY-INLINE-P allows inlining it as an image." (t (ignore))) (cons width height))) -(defvar org-odt-default-entity "Illustration") -(defun org-odt-format-entity-caption (label caption &optional default-entity) - (if (not label) (or caption "") - (let* ((label-components (org-odt-parse-label label)) - (entity (car label-components)) - (seqno (cdr label-components)) - (caption (and caption (concat ": " caption)))) - (unless seqno - (setq seqno label - entity (or default-entity org-odt-default-entity))) - (concat - entity " " - (org-odt-format-tags - '("" . "") - seqno label entity entity) - caption)))) +(defvar org-odt-entity-labels-alist nil + "Associate Labels with the Labelled entities. +Each element of the alist is of the form (LABEL-NAME +CATEGORY-NAME SEQNO). LABEL-NAME is same as that specified by +\"#+LABEL: ...\" line. CATEGORY-NAME is the type of the entity +that LABEL-NAME is attached to. CATEGORY-NAME can be one of +\"Table\", \"Figure\" or \"Equation\". SEQNO is the unique +number assigned to the referenced entity on a per-CATEGORY basis. +It is generated sequentially and is 1-based. + +Update this alist with `org-odt-add-label-definition' and +retrieve an entry with `org-odt-get-label-definition'.") + +(defvar org-odt-entity-counts-plist nil + "Plist of running counters of SEQNOs for each of the CATEGORY-NAMEs. +See `org-odt-entity-labels-alist' for known CATEGORY-NAMEs.") + +(defvar org-odt-label-def-ref-spec + '(;; ("Equation" "(%n)" "text" "(%n)") + ("" "%e %n%c" "category-and-value" "%e %n")) + "Specify how labels are applied and referenced. +This is an alist where each element is of the form (CATEGORY-NAME +LABEL-APPLY-FMT LABEL-REF-MODE LABEL-REF-FMT). CATEGORY-NAME is +as defined in `org-odt-entity-labels-alist'. It can additionally +be an empty string in which case it is used as a catch-all +specifier. + +LABEL-APPLY-FMT is used for applying labels and captions. It may +contain following specifiers - %e, %n and %c. %e is replaced +with the CATEGORY-NAME. %n is replaced with \" SEQNO \". %c is replaced with CAPTION. See +`org-odt-format-label-definition'. + +LABEL-REF-MODE and LABEL-REF-FMT are used for generating the +following label reference - \" LABEL-REF-FMT +\". LABEL-REF-FMT may contain following +specifiers - %e and %n. %e is replaced with the CATEGORY-NAME. %n is +replaced with SEQNO. See `org-odt-format-label-reference'.") + +(defun org-odt-add-label-definition (label category) + "Return (SEQNO . LABEL-APPLY-FMT). +See `org-odt-label-def-ref-spec'." + (setq label (substring-no-properties label)) + (let (seqno label-props fmt (category-sym (intern category))) + (setq seqno (1+ (plist-get org-odt-entity-counts-plist category-sym)) + org-odt-entity-counts-plist (plist-put org-odt-entity-counts-plist + category-sym seqno) + fmt (cadr (or (assoc-string category org-odt-label-def-ref-spec t) + (assoc-string "" org-odt-label-def-ref-spec t))) + label-props (list label category seqno)) + (push label-props org-odt-entity-labels-alist) + (cons seqno fmt))) + +(defun org-odt-get-label-definition (label) + "Return (LABEL-NAME CATEGORY-NAME SEQNO LABEL-REF-MODE LABEL-REF-FMT). +See `org-odt-entity-labels-alist' and +`org-odt-label-def-ref-spec'." + (let* ((label-props (assoc label org-odt-entity-labels-alist)) + (category (nth 1 label-props))) + (append label-props + (cddr (or (assoc-string category org-odt-label-def-ref-spec t) + (assoc-string "" org-odt-label-def-ref-spec t)))))) + +(defun org-odt-format-label-definition (label category caption) + (assert label) + (let* ((label-props (org-odt-add-label-definition label category)) + (seqno (car label-props)) + (fmt (cdr label-props))) + (or (format-spec + fmt + `((?e . ,category) + (?n . ,(org-odt-format-tags + '("" . "") + (format "%d" seqno) label category category)) + (?c . ,(or (and caption (concat ": " caption)) "")))) + caption ""))) + +(defun org-odt-format-label-reference (label category seqno fmt1 fmt2) + (assert label) + (save-match-data + (org-odt-format-tags + '("" + . "") + (format-spec fmt2 `((?e . ,category) + (?n . ,(format "%d" seqno)))) fmt1 label))) + +(defun org-odt-fixup-label-references () + (goto-char (point-min)) + (while (re-search-forward + "" nil t) + (let* ((label (match-string 1))) + (replace-match + (apply 'org-odt-format-label-reference + (org-odt-get-label-definition label)) t t)))) + +(defun org-odt-format-entity-caption (label caption category) + (or (and label (org-odt-format-label-definition label category caption)) + caption "")) (defun org-odt-format-tags (tag text &rest args) (let ((prefix (when org-lparse-encode-pending "@")) @@ -1588,8 +1673,9 @@ MAY-INLINE-P allows inlining it as an image." ;; reset variables (setq org-odt-manifest-file-entries nil org-odt-embedded-images-count 0 - org-odt-embedded-formulas-count 0) - + org-odt-embedded-formulas-count 0 + org-odt-entity-labels-alist nil + org-odt-entity-counts-plist (list 'Table 0 'Equation 0 'Figure 0)) content-file)) (defcustom org-export-odt-prettify-xml nil @@ -1824,14 +1910,6 @@ visually." (CODING-SYSTEM-FOR-SAVE 'utf-8) (t (error "Unknown property: %s" what)))) -(defun org-odt-parse-label (label) - (save-match-data - (if (not (string-match "\\`[a-zA-Z]+:\\(.+\\)" label)) - (cons label nil) - (cons - (capitalize (substring label 0 (1- (match-beginning 1)))) - (substring label (match-beginning 1)))))) - (defvar org-lparse-latex-fragment-fallback) ; set by org-do-lparse (defvar org-lparse-opt-plist) ; bound during org-do-lparse (defun org-export-odt-do-preprocess-latex-fragments () @@ -1873,16 +1951,18 @@ visually." (let (label label-components category value pretty-label) (while (re-search-forward "\\\\ref{\\([^{}\n]+\\)}" nil t) (org-if-unprotected-at (match-beginning 1) - (setq label (match-string 1) - label-components (org-odt-parse-label label) - category (car label-components) - value (cdr label-components) - pretty-label (if value (concat category " " value) label)) (replace-match - (let ((org-lparse-encode-pending t)) + (let ((org-lparse-encode-pending t) + (label (match-string 1))) + ;; markup generated below is mostly an eye-candy. At + ;; pre-processing stage, there is no information on which + ;; entity a label reference points to. The actual markup + ;; is generated as part of `org-odt-fixup-label-references' + ;; which gets called at the fag end of export. By this + ;; time we would have seen and collected all the label + ;; definitions in `org-odt-entity-labels-alist'. (org-odt-format-tags - '("" - . "") pretty-label label)) t t))))) + "" "" label)) t t))))) ;; process latex fragments as part of ;; `org-export-preprocess-after-blockquote-hook'. Note that this hook diff --git a/contrib/odt/styles/OrgOdtContentTemplate.xml b/contrib/odt/styles/OrgOdtContentTemplate.xml index 980f2646d..61143d994 100644 --- a/contrib/odt/styles/OrgOdtContentTemplate.xml +++ b/contrib/odt/styles/OrgOdtContentTemplate.xml @@ -111,8 +111,8 @@ + - -- 2.11.4.GIT