diff options
Diffstat (limited to 'lisp/ox-odt.el')
-rw-r--r-- | lisp/ox-odt.el | 1078 |
1 files changed, 498 insertions, 580 deletions
diff --git a/lisp/ox-odt.el b/lisp/ox-odt.el index 9fce5e7..05d86bf 100644 --- a/lisp/ox-odt.el +++ b/lisp/ox-odt.el @@ -1,4 +1,4 @@ -;;; ox-odt.el --- OpenDocument Text Exporter for Org Mode +;;; ox-odt.el --- OpenDocument Text Exporter for Org Mode -*- lexical-binding: t; -*- ;; Copyright (C) 2010-2016 Free Software Foundation, Inc. @@ -25,12 +25,11 @@ ;;; Code: -(eval-when-compile - (require 'cl) - (require 'table nil 'noerror)) +(require 'cl-lib) (require 'format-spec) (require 'ox) (require 'org-compat) +(require 'table nil 'noerror) ;;; Define Back-End @@ -83,7 +82,6 @@ (underline . org-odt-underline) (verbatim . org-odt-verbatim) (verse-block . org-odt-verse-block)) - :export-block "ODT" :filters-alist '((:filter-parse-tree . (org-odt--translate-latex-fragments org-odt--translate-description-lists @@ -121,7 +119,7 @@ ;;; Hooks -;;; Function Declarations +;;; Function and Dynamically Scoped Variables Declarations (declare-function hfy-face-to-style "htmlfontify" (fn)) (declare-function hfy-face-or-def-to-name "htmlfontify" (fn)) @@ -129,6 +127,13 @@ (declare-function org-create-math-formula "org" (latex-frag &optional mathml-file)) (declare-function browse-url-file-url "browse-url" (file)) +(defvar nxml-auto-insert-xml-declaration-flag) ; nxml-mode.el +(defvar archive-zip-extract) ; arc-mode.el +(defvar hfy-end-span-handler) ; htmlfontify.el +(defvar hfy-begin-span-handler) ; htmlfontify.el +(defvar hfy-face-to-css) ; htmlfontify.el +(defvar hfy-html-quote-map) ; htmlfontify.el +(defvar hfy-html-quote-regex) ; htmlfontify.el ;;; Internal Variables @@ -172,7 +177,7 @@ and `org-odt-data-dir'.") (eval-when-compile (and (boundp 'org-odt-data-dir) org-odt-data-dir ; see make install (expand-file-name "./styles/" org-odt-data-dir))) - (expand-file-name "../../etc/styles/" org-odt-lib-dir) ; git + (expand-file-name "../etc/styles/" org-odt-lib-dir) ; git (expand-file-name "./etc/styles/" org-odt-lib-dir) ; elpa (expand-file-name "./org/" data-directory) ; system ) @@ -182,23 +187,14 @@ heuristically based on the values of `org-odt-lib-dir' and `org-odt-data-dir'.") (defconst org-odt-styles-dir - (let* ((styles-dir - (catch 'styles-dir - (message "Debug (ox-odt): Searching for OpenDocument styles files...") - (mapc (lambda (styles-dir) - (when styles-dir - (message "Debug (ox-odt): Trying %s..." styles-dir) - (when (and (file-readable-p - (expand-file-name - "OrgOdtContentTemplate.xml" styles-dir)) - (file-readable-p - (expand-file-name - "OrgOdtStyles.xml" styles-dir))) - (message "Debug (ox-odt): Using styles under %s" - styles-dir) - (throw 'styles-dir styles-dir)))) - org-odt-styles-dir-list) - nil))) + (let ((styles-dir + (cl-find-if + (lambda (dir) + (and dir + (file-readable-p + (expand-file-name "OrgOdtContentTemplate.xml" dir)) + (file-readable-p (expand-file-name "OrgOdtStyles.xml" dir)))) + org-odt-styles-dir-list))) (unless styles-dir (error "Error (ox-odt): Cannot find factory styles files, aborting")) styles-dir) @@ -210,9 +206,9 @@ This directory contains the following XML files - `org-odt-styles-file' and `org-odt-content-template-file'. The default value of this variable varies depending on the -version of org in use and is initialized from -`org-odt-styles-dir-list'. Note that the user could be using org -from one of: org's own private git repository, GNU ELPA tar or +version of Org in use and is initialized from +`org-odt-styles-dir-list'. Note that the user could be using Org +from one of: Org own private git repository, GNU ELPA tar or standard Emacs.") (defconst org-odt-bookmark-prefix "OrgXref.") @@ -277,7 +273,6 @@ except that the foreground and background colors are set according to the default face identified by the `htmlfontify'.") (defvar hfy-optimizations) -(define-obsolete-variable-alias 'hfy-optimisations 'hfy-optimizations "25.1") (defvar org-odt-embedded-formulas-count 0) (defvar org-odt-embedded-images-count 0) (defvar org-odt-image-size-probe-method @@ -383,28 +378,14 @@ visually." (require 'rng-loc) (defcustom org-odt-schema-dir - (let* ((schema-dir - (catch 'schema-dir - (message "Debug (ox-odt): Searching for OpenDocument schema files...") - (mapc - (lambda (schema-dir) - (when schema-dir - (message "Debug (ox-odt): Trying %s..." schema-dir) - (when (and (file-expand-wildcards - (expand-file-name "od-manifest-schema*.rnc" - schema-dir)) - (file-expand-wildcards - (expand-file-name "od-schema*.rnc" - schema-dir)) - (file-readable-p - (expand-file-name "schemas.xml" schema-dir))) - (message "Debug (ox-odt): Using schema files under %s" - schema-dir) - (throw 'schema-dir schema-dir)))) - org-odt-schema-dir-list) - (message "Debug (ox-odt): No OpenDocument schema files installed") - nil))) - schema-dir) + (cl-find-if + (lambda (dir) + (and dir + (file-expand-wildcards + (expand-file-name "od-manifest-schema*.rnc" dir)) + (file-expand-wildcards (expand-file-name "od-schema*.rnc" dir)) + (file-readable-p (expand-file-name "schemas.xml" dir)))) + org-odt-schema-dir-list) "Directory that contains OpenDocument schema files. This directory contains: @@ -661,8 +642,7 @@ values. See Info node `(emacs) File Variables'." ;;;; Drawers -(defcustom org-odt-format-drawer-function - (lambda (name contents) contents) +(defcustom org-odt-format-drawer-function (lambda (_name contents) contents) "Function called to format a drawer in ODT code. The function must accept two parameters: @@ -693,7 +673,7 @@ TAGS the tags string, separated with colons (string or nil). The function result will be used as headline text." :group 'org-export-odt - :version "25.1" + :version "25.2" :package-version '(Org . "8.3") :type 'function) @@ -714,7 +694,7 @@ The function must accept six parameters: The function should return the string to be exported." :group 'org-export-odt - :version "25.1" + :version "25.2" :package-version '(Org . "8.3") :type 'function) @@ -773,7 +753,7 @@ A rule consists in an association whose key is the type of link to consider, and value is a regexp that will be matched against link's path." :group 'org-export-odt - :version "25.1" + :version "25.2" :package-version '(Org . "8.3") :type '(alist :key-type (string :tag "Type") :value-type (regexp :tag "Path"))) @@ -992,11 +972,11 @@ See `org-odt--build-date-styles' for implementation details." (repeater-unit (org-element-property :repeater-unit timestamp))) (concat - (case repeater-type + (cl-case repeater-type (catchup "++") (restart ".+") (cumulate "+")) (when repeater-value (number-to-string repeater-value)) - (case repeater-unit + (cl-case repeater-unit (hour "h") (day "d") (week "w") (month "m") (year "y")))))) (concat @@ -1035,29 +1015,28 @@ See `org-odt--build-date-styles' for implementation details." (defun org-odt--zip-extract (archive members target) (when (atom members) (setq members (list members))) - (mapc (lambda (member) - (require 'arc-mode) - (let* ((--quote-file-name - ;; This is shamelessly stolen from `archive-zip-extract'. - (lambda (name) - (if (or (not (memq system-type '(windows-nt ms-dos))) - (and (boundp 'w32-quote-process-args) - (null w32-quote-process-args))) - (shell-quote-argument name) - name))) - (target (funcall --quote-file-name target)) - (archive (expand-file-name archive)) - (archive-zip-extract - (list "unzip" "-qq" "-o" "-d" target)) - exit-code command-output) - (setq command-output - (with-temp-buffer - (setq exit-code (archive-zip-extract archive member)) - (buffer-string))) - (unless (zerop exit-code) - (message command-output) - (error "Extraction failed")))) - members)) + (require 'arc-mode) + (dolist (member members) + (let* ((--quote-file-name + ;; This is shamelessly stolen from `archive-zip-extract'. + (lambda (name) + (if (or (not (memq system-type '(windows-nt ms-dos))) + (and (boundp 'w32-quote-process-args) + (null w32-quote-process-args))) + (shell-quote-argument name) + name))) + (target (funcall --quote-file-name target)) + (archive (expand-file-name archive)) + (archive-zip-extract + (list "unzip" "-qq" "-o" "-d" target)) + exit-code command-output) + (setq command-output + (with-temp-buffer + (setq exit-code (archive-zip-extract archive member)) + (buffer-string))) + (unless (zerop exit-code) + (message command-output) + (error "Extraction failed"))))) ;;;; Target @@ -1125,38 +1104,37 @@ specifying the depth of the table." </text:index-body> </text:table-of-content>")) -(defun* org-odt-format-toc-headline - (todo todo-type priority text tags - &key level section-number headline-label &allow-other-keys) - (setq text - (concat - ;; Section number. - (and section-number (concat section-number ". ")) - ;; Todo. - (when todo - (let ((style (if (member todo org-done-keywords) - "OrgDone" "OrgTodo"))) - (format "<text:span text:style-name=\"%s\">%s</text:span> " - style todo))) - (when priority - (let* ((style (format "OrgPriority-%s" priority)) - (priority (format "[#%c]" priority))) - (format "<text:span text:style-name=\"%s\">%s</text:span> " - style priority))) - ;; Title. - text - ;; Tags. - (when tags - (concat - (format " <text:span text:style-name=\"%s\">[%s]</text:span>" - "OrgTags" - (mapconcat - (lambda (tag) - (format - "<text:span text:style-name=\"%s\">%s</text:span>" - "OrgTag" tag)) tags " : ")))))) +(cl-defun org-odt-format-toc-headline + (todo _todo-type priority text tags + &key _level section-number headline-label &allow-other-keys) (format "<text:a xlink:type=\"simple\" xlink:href=\"#%s\">%s</text:a>" - headline-label text)) + headline-label + (concat + ;; Section number. + (and section-number (concat section-number ". ")) + ;; Todo. + (when todo + (let ((style (if (member todo org-done-keywords) + "OrgDone" "OrgTodo"))) + (format "<text:span text:style-name=\"%s\">%s</text:span> " + style todo))) + (when priority + (let* ((style (format "OrgPriority-%s" priority)) + (priority (format "[#%c]" priority))) + (format "<text:span text:style-name=\"%s\">%s</text:span> " + style priority))) + ;; Title. + text + ;; Tags. + (when tags + (concat + (format " <text:span text:style-name=\"%s\">[%s]</text:span>" + "OrgTags" + (mapconcat + (lambda (tag) + (format + "<text:span text:style-name=\"%s\">%s</text:span>" + "OrgTag" tag)) tags " : "))))))) (defun org-odt-toc (depth info &optional scope) "Build a table of contents. @@ -1164,7 +1142,7 @@ DEPTH is an integer specifying the depth of the table. INFO is a plist containing current export properties. Optional argument SCOPE, when non-nil, defines the scope of the table. Return the table of contents as a string, or nil." - (assert (wholenump depth)) + (cl-assert (wholenump depth)) ;; When a headline is marked as a radio target, as in the example below: ;; ;; ** <<<Some Heading>>> @@ -1211,7 +1189,7 @@ Use `org-odt-object-counters' to generate an automatic OBJECT-NAME and STYLE-NAME. If OBJECT-PROPS is non-nil, add a new entry in `org-odt-automatic-styles'. Return (OBJECT-NAME . STYLE-NAME)." - (assert (stringp object-type)) + (cl-assert (stringp object-type)) (let* ((object (intern object-type)) (seqvar object) (seqno (1+ (or (plist-get org-odt-object-counters seqvar) 0))) @@ -1233,7 +1211,7 @@ new entry in `org-odt-automatic-styles'. Return (OBJECT-NAME (let ((checkbox (org-element-property :checkbox item))) (if (not checkbox) "" (format "<text:span text:style-name=\"%s\">%s</text:span>" - "OrgCode" (case checkbox + "OrgCode" (cl-case checkbox (on "[✓] ") ; CHECK MARK (off "[ ] ") (trans "[-] ")))))) @@ -1277,31 +1255,30 @@ new entry in `org-odt-automatic-styles'. Return (OBJECT-NAME (case-fold-search nil) (re (mapconcat 'identity (mapcar 'car fmt-alist) "\\|")) match rpl (start 0) (filler-beg 0) filler-end filler output) - (mapc - (lambda (pair) - (setq fmt (replace-regexp-in-string (car pair) (cdr pair) fmt t t))) - '(("\\(?:%[[:digit:]]*N\\)" . "") ; strip ns, us and ns - ("%C" . "Y") ; replace century with year - ("%D" . "%m/%d/%y") - ("%G" . "Y") ; year corresponding to iso week - ("%I" . "%H") ; hour on a 12-hour clock - ("%R" . "%H:%M") - ("%T" . "%H:%M:%S") - ("%U\\|%W" . "%V") ; week no. starting on Sun./Mon. - ("%Z" . "") ; time zone name - ("%c" . "%Y-%M-%d %a %H:%M" ) ; locale's date and time format - ("%g" . "%y") - ("%X" . "%x" ) ; locale's pref. time format - ("%j" . "") ; day of the year - ("%l" . "%k") ; like %I blank-padded - ("%s" . "") ; no. of secs since 1970-01-01 00:00:00 +0000 - ("%n" . "<text:line-break/>") - ("%r" . "%I:%M:%S %p") - ("%t" . "<text:tab/>") - ("%u\\|%w" . "") ; numeric day of week - Mon (1-7), Sun(0-6) - ("%x" . "%Y-%M-%d %a") ; locale's pref. time format - ("%z" . "") ; time zone in numeric form - )) + (dolist (pair + '(("\\(?:%[[:digit:]]*N\\)" . "") ; strip ns, us and ns + ("%C" . "Y") ; replace century with year + ("%D" . "%m/%d/%y") + ("%G" . "Y") ; year corresponding to iso week + ("%I" . "%H") ; hour on a 12-hour clock + ("%R" . "%H:%M") + ("%T" . "%H:%M:%S") + ("%U\\|%W" . "%V") ; week no. starting on Sun./Mon. + ("%Z" . "") ; time zone name + ("%c" . "%Y-%M-%d %a %H:%M" ) ; locale's date and time format + ("%g" . "%y") + ("%X" . "%x" ) ; locale's pref. time format + ("%j" . "") ; day of the year + ("%l" . "%k") ; like %I blank-padded + ("%s" . "") ; no. of secs since 1970-01-01 00:00:00 +0000 + ("%n" . "<text:line-break/>") + ("%r" . "%I:%M:%S %p") + ("%t" . "<text:tab/>") + ("%u\\|%w" . "") ; numeric day of week - Mon (1-7), Sun(0-6) + ("%x" . "%Y-%M-%d %a") ; locale's pref. time format + ("%z" . "") ; time zone in numeric form + )) + (setq fmt (replace-regexp-in-string (car pair) (cdr pair) fmt t t))) (while (string-match re fmt start) (setq match (match-string 0 fmt)) (setq rpl (assoc-default match fmt-alist)) @@ -1334,7 +1311,6 @@ original parsed data. INFO is a plist holding export options." (subtitle (org-export-data (plist-get info :subtitle) info)) (author (let ((author (plist-get info :author))) (if (not author) "" (org-export-data author info)))) - (email (plist-get info :email)) (keywords (or (plist-get info :keywords) "")) (description (or (plist-get info :description) ""))) (write-region @@ -1397,13 +1373,11 @@ original parsed data. INFO is a plist holding export options." (let ((archive (nth 0 styles-file)) (members (nth 1 styles-file))) (org-odt--zip-extract archive members org-odt-zip-dir) - (mapc - (lambda (member) - (when (org-file-image-p member) - (let* ((image-type (file-name-extension member)) - (media-type (format "image/%s" image-type))) - (org-odt-create-manifest-file-entry media-type member)))) - members))) + (dolist (member members) + (when (org-file-image-p member) + (let* ((image-type (file-name-extension member)) + (media-type (format "image/%s" image-type))) + (org-odt-create-manifest-file-entry media-type member)))))) ((and (stringp styles-file) (file-exists-p styles-file)) (let ((styles-file-type (file-name-extension styles-file))) (cond @@ -1446,7 +1420,7 @@ original parsed data. INFO is a plist holding export options." ;; currently the zip command zips up the entire temp directory so ;; that any auto-generated files created under the hood ends up in ;; the resulting odt file. - (set (make-local-variable 'backup-inhibited) t) + (setq-local backup-inhibited t) ;; Outline numbering is retained only upto LEVEL. ;; To disable outline numbering pass a LEVEL of 0. @@ -1483,16 +1457,16 @@ original parsed data. INFO is a plist holding export options." (re-search-forward " </office:automatic-styles>" nil t) (goto-char (match-beginning 0)) ;; - Dump automatic table styles. - (loop for (style-name props) in - (plist-get org-odt-automatic-styles 'Table) do - (when (setq props (or (plist-get props :rel-width) "96")) - (insert (format org-odt-table-style-format style-name props)))) + (cl-loop for (style-name props) in + (plist-get org-odt-automatic-styles 'Table) do + (when (setq props (or (plist-get props :rel-width) "96")) + (insert (format org-odt-table-style-format style-name props)))) ;; - Dump date-styles. (when (plist-get info :odt-use-date-fields) (insert (org-odt--build-date-styles (car custom-time-fmts) - "OrgDate1") + "OrgDate1") (org-odt--build-date-styles (cdr custom-time-fmts) - "OrgDate2"))) + "OrgDate2"))) ;; Update display level. ;; - Remove existing sequence decls. Also position the cursor. (goto-char (point-min)) @@ -1600,7 +1574,7 @@ original parsed data. INFO is a plist holding export options." ;;;; Bold -(defun org-odt-bold (bold contents info) +(defun org-odt-bold (_bold contents _info) "Transcode BOLD from Org to ODT. CONTENTS is the text with bold markup. INFO is a plist holding contextual information." @@ -1610,7 +1584,7 @@ contextual information." ;;;; Center Block -(defun org-odt-center-block (center-block contents info) +(defun org-odt-center-block (_center-block contents _info) "Transcode a CENTER-BLOCK element from Org to ODT. CONTENTS holds the contents of the center block. INFO is a plist holding contextual information." @@ -1637,7 +1611,7 @@ channel." ;;;; Code -(defun org-odt-code (code contents info) +(defun org-odt-code (code _contents _info) "Transcode a CODE object from Org to ODT. CONTENTS is nil. INFO is a plist used as a communication channel." @@ -1646,16 +1620,6 @@ channel." (org-element-property :value code)))) -;;;; Comment - -;; Comments are ignored. - - -;;;; Comment Block - -;; Comment Blocks are ignored. - - ;;;; Drawer (defun org-odt-drawer (drawer contents info) @@ -1670,7 +1634,7 @@ holding contextual information." ;;;; Dynamic Block -(defun org-odt-dynamic-block (dynamic-block contents info) +(defun org-odt-dynamic-block (_dynamic-block contents _info) "Transcode a DYNAMIC-BLOCK element from Org to ODT. CONTENTS holds the contents of the block. INFO is a plist holding contextual information. See `org-export-data'." @@ -1679,7 +1643,7 @@ holding contextual information. See `org-export-data'." ;;;; Entity -(defun org-odt-entity (entity contents info) +(defun org-odt-entity (entity _contents _info) "Transcode an ENTITY object from Org to ODT. CONTENTS are the definition itself. INFO is a plist holding contextual information." @@ -1688,7 +1652,7 @@ contextual information." ;;;; Example Block -(defun org-odt-example-block (example-block contents info) +(defun org-odt-example-block (example-block _contents info) "Transcode a EXAMPLE-BLOCK element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (org-odt-format-code example-block info)) @@ -1696,7 +1660,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Export Snippet -(defun org-odt-export-snippet (export-snippet contents info) +(defun org-odt-export-snippet (export-snippet _contents _info) "Transcode a EXPORT-SNIPPET object from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (when (eq (org-export-snippet-backend export-snippet) 'odt) @@ -1705,7 +1669,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Export Block -(defun org-odt-export-block (export-block contents info) +(defun org-odt-export-block (export-block _contents _info) "Transcode a EXPORT-BLOCK element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (when (string= (org-element-property :type export-block) "ODT") @@ -1714,7 +1678,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Fixed Width -(defun org-odt-fixed-width (fixed-width contents info) +(defun org-odt-fixed-width (fixed-width _contents info) "Transcode a FIXED-WIDTH element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (org-odt-do-format-code (org-element-property :value fixed-width) info)) @@ -1727,34 +1691,31 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Footnote Reference -(defun org-odt-footnote-reference (footnote-reference contents info) +(defun org-odt-footnote-reference (footnote-reference _contents info) "Transcode a FOOTNOTE-REFERENCE element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (let ((--format-footnote-definition - (function - (lambda (n def) - (setq n (format "%d" n)) - (let ((id (concat "fn" n)) - (note-class "footnote") - (par-style "Footnote")) - (format - "<text:note text:id=\"%s\" text:note-class=\"%s\">%s</text:note>" - id note-class - (concat - (format "<text:note-citation>%s</text:note-citation>" n) - (format "<text:note-body>%s</text:note-body>" def))))))) + (lambda (n def) + (setq n (format "%d" n)) + (let ((id (concat "fn" n)) + (note-class "footnote")) + (format + "<text:note text:id=\"%s\" text:note-class=\"%s\">%s</text:note>" + id note-class + (concat + (format "<text:note-citation>%s</text:note-citation>" n) + (format "<text:note-body>%s</text:note-body>" def)))))) (--format-footnote-reference - (function - (lambda (n) - (setq n (format "%d" n)) - (let ((note-class "footnote") - (ref-format "text") - (ref-name (concat "fn" n))) - (format - "<text:span text:style-name=\"%s\">%s</text:span>" - "OrgSuperscript" - (format "<text:note-ref text:note-class=\"%s\" text:reference-format=\"%s\" text:ref-name=\"%s\">%s</text:note-ref>" - note-class ref-format ref-name n))))))) + (lambda (n) + (setq n (format "%d" n)) + (let ((note-class "footnote") + (ref-format "text") + (ref-name (concat "fn" n))) + (format + "<text:span text:style-name=\"%s\">%s</text:span>" + "OrgSuperscript" + (format "<text:note-ref text:note-class=\"%s\" text:reference-format=\"%s\" text:ref-name=\"%s\">%s</text:note-ref>" + note-class ref-format ref-name n)))))) (concat ;; Insert separator between two footnotes in a row. (let ((prev (org-export-get-previous-element footnote-reference info))) @@ -1786,8 +1747,8 @@ CONTENTS is nil. INFO is a plist holding contextual information." info)))) ;; Inline definitions are secondary strings. We ;; need to wrap them within a paragraph. - (if (memq (org-element-type (car (org-element-contents raw))) - org-element-all-elements) + (if (eq (org-element-class (car (org-element-contents raw))) + 'element) def (format "\n<text:p text:style-name=\"Footnote\">%s</text:p>" @@ -1822,15 +1783,16 @@ INFO is a plist holding contextual information." (headline-label (org-export-get-reference headline info)) (format-function (if (functionp format-function) format-function - (function* + (cl-function (lambda (todo todo-type priority text tags - &key level section-number headline-label - &allow-other-keys) + &key _level _section-number _headline-label + &allow-other-keys) (funcall (plist-get info :odt-format-headline-function) todo todo-type priority text tags)))))) (apply format-function todo todo-type priority text tags - :headline-label headline-label :level level + :headline-label headline-label + :level level :section-number section-number extra-keys))) (defun org-odt-headline (headline contents info) @@ -1839,9 +1801,7 @@ CONTENTS holds the contents of the headline. INFO is a plist holding contextual information." ;; Case 1: This is a footnote section: ignore it. (unless (org-element-property :footnote-section-p headline) - (let* ((text (org-export-data (org-element-property :title headline) info)) - ;; Create the headline text. - (full-text (org-odt-format-headline--wrap headline nil info)) + (let* ((full-text (org-odt-format-headline--wrap headline nil info)) ;; Get level relative to current parsed data. (level (org-export-get-relative-level headline info)) (numbered (org-export-numbered-headline-p headline info)) @@ -1928,7 +1888,7 @@ See `org-odt-format-headline-function' for details." ;;;; Horizontal Rule -(defun org-odt-horizontal-rule (horizontal-rule contents info) +(defun org-odt-horizontal-rule (_horizontal-rule _contents _info) "Transcode an HORIZONTAL-RULE object from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (format "\n<text:p text:style-name=\"%s\">%s</text:p>" @@ -1946,18 +1906,15 @@ CONTENTS is nil. INFO is a plist holding contextual information." "Return a character not used in string S. This is used to choose a separator for constructs like \\verb." (let ((ll "~,./?;':\"|!@#%^&-_=+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ<>()[]{}")) - (loop for c across ll - when (not (string-match (regexp-quote (char-to-string c)) s)) - return (char-to-string c)))) + (cl-loop for c across ll + when (not (string-match (regexp-quote (char-to-string c)) s)) + return (char-to-string c)))) -(defun org-odt-inline-src-block (inline-src-block contents info) +(defun org-odt-inline-src-block (_inline-src-block _contents _info) "Transcode an INLINE-SRC-BLOCK element from Org to ODT. CONTENTS holds the contents of the item. INFO is a plist holding contextual information." - (let* ((org-lang (org-element-property :language inline-src-block)) - (code (org-element-property :value inline-src-block)) - (separator (org-odt--find-verb-separator code))) - (error "FIXME"))) + (error "FIXME")) ;;;; Inlinetask @@ -1996,7 +1953,7 @@ See `org-odt-format-inlinetask-function' for details." ;;;; Italic -(defun org-odt-italic (italic contents info) +(defun org-odt-italic (_italic contents _info) "Transcode ITALIC from Org to ODT. CONTENTS is the text with italic markup. INFO is a plist holding contextual information." @@ -2011,30 +1968,18 @@ contextual information." CONTENTS holds the contents of the item. INFO is a plist holding contextual information." (let* ((plain-list (org-export-get-parent item)) - (type (org-element-property :type plain-list)) - (counter (org-element-property :counter item)) - (tag (let ((tag (org-element-property :tag item))) - (and tag - (concat (org-odt--checkbox item) - (org-export-data tag info)))))) - (case type - ((ordered unordered descriptive-1 descriptive-2) - (format "\n<text:list-item>\n%s\n%s" - contents - (let* ((--element-has-a-table-p - (function - (lambda (element info) - (loop for el in (org-element-contents element) - thereis (eq (org-element-type el) 'table)))))) - (cond - ((funcall --element-has-a-table-p item info) - "</text:list-header>") - (t "</text:list-item>"))))) - (t (error "Unknown list type: %S" type))))) + (type (org-element-property :type plain-list))) + (unless (memq type '(ordered unordered descriptive-1 descriptive-2)) + (error "Unknown list type: %S" type)) + (format "\n<text:list-item>\n%s\n%s" + contents + (if (org-element-map item 'table #'identity info 'first-match) + "</text:list-header>" + "</text:list-item>")))) ;;;; Keyword -(defun org-odt-keyword (keyword contents info) +(defun org-odt-keyword (keyword _contents info) "Transcode a KEYWORD element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." @@ -2048,13 +1993,13 @@ information." ((string= key "TOC") (let ((case-fold-search t)) (cond - ((org-string-match-p "\\<headlines\\>" value) + ((string-match-p "\\<headlines\\>" value) (let ((depth (or (and (string-match "\\<[0-9]+\\>" value) (string-to-number (match-string 0 value))) (plist-get info :headline-levels))) - (localp (org-string-match-p "\\<local\\>" value))) + (localp (string-match-p "\\<local\\>" value))) (org-odt-toc depth info (and localp keyword)))) - ((org-string-match-p "tables\\|figures\\|listings" value) + ((string-match-p "tables\\|figures\\|listings" value) ;; FIXME (ignore)))))))) @@ -2070,7 +2015,7 @@ information." ;; (unless (> (length ad-return-value) 0) ;; (setq ad-return-value (org-odt--encode-plain-text (ad-get-arg 0))))) -(defun org-odt-latex-environment (latex-environment contents info) +(defun org-odt-latex-environment (latex-environment _contents info) "Transcode a LATEX-ENVIRONMENT element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (let* ((latex-frag (org-remove-indentation @@ -2081,23 +2026,22 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Latex Fragment ;; (when latex-frag ; FIXME -;; (setq href (org-propertize href :title "LaTeX Fragment" +;; (setq href (propertize href :title "LaTeX Fragment" ;; :description latex-frag))) ;; handle verbatim ;; provide descriptions -(defun org-odt-latex-fragment (latex-fragment contents info) +(defun org-odt-latex-fragment (latex-fragment _contents _info) "Transcode a LATEX-FRAGMENT object from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." - (let* ((latex-frag (org-element-property :value latex-fragment)) - (processing-type (plist-get info :with-latex))) + (let ((latex-frag (org-element-property :value latex-fragment))) (format "<text:span text:style-name=\"%s\">%s</text:span>" "OrgCode" (org-odt--encode-plain-text latex-frag t)))) ;;;; Line Break -(defun org-odt-line-break (line-break contents info) +(defun org-odt-line-break (_line-break _contents _info) "Transcode a LINE-BREAK object from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." "<text:line-break/>") @@ -2108,27 +2052,25 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Links :: Label references (defun org-odt--enumerate (element info &optional predicate n) - (when predicate (assert (funcall predicate element info))) + (when predicate (cl-assert (funcall predicate element info))) (let* ((--numbered-parent-headline-at-<=-n - (function - (lambda (element n info) - (loop for x in (org-element-lineage element) - thereis (and (eq (org-element-type x) 'headline) - (<= (org-export-get-relative-level x info) n) - (org-export-numbered-headline-p x info) - x))))) + (lambda (element n info) + (cl-loop for x in (org-element-lineage element) + thereis (and (eq (org-element-type x) 'headline) + (<= (org-export-get-relative-level x info) n) + (org-export-numbered-headline-p x info) + x)))) (--enumerate - (function - (lambda (element scope info &optional predicate) - (let ((counter 0)) - (org-element-map (or scope (plist-get info :parse-tree)) - (org-element-type element) - (lambda (el) - (and (or (not predicate) (funcall predicate el info)) - (incf counter) - (eq element el) - counter)) - info 'first-match))))) + (lambda (element scope info &optional predicate) + (let ((counter 0)) + (org-element-map (or scope (plist-get info :parse-tree)) + (org-element-type element) + (lambda (el) + (and (or (not predicate) (funcall predicate el info)) + (cl-incf counter) + (eq element el) + counter)) + info 'first-match)))) (scope (funcall --numbered-parent-headline-at-<=-n element (or n (plist-get info :odt-display-outline-level)) @@ -2157,9 +2099,9 @@ the generated string. Return value is a string if OP is set to `reference' or a cons cell like CAPTION . SHORT-CAPTION) where CAPTION and SHORT-CAPTION are strings." - (assert (memq (org-element-type element) '(link table src-block paragraph))) + (cl-assert (memq (org-element-type element) '(link table src-block paragraph))) (let* ((element-or-parent - (case (org-element-type element) + (cl-case (org-element-type element) (link (org-export-get-parent-element element)) (t element))) ;; Get label and caption. @@ -2172,7 +2114,7 @@ SHORT-CAPTION are strings." (short-caption nil)) (when (or label caption) (let* ((default-category - (case (org-element-type element) + (cl-case (org-element-type element) (table "__Table__") (src-block "__Listing__") ((link paragraph) @@ -2188,14 +2130,15 @@ SHORT-CAPTION are strings." (t (error "Don't know how to format label for element type: %s" (org-element-type element))))) seqno) - (assert default-category) - (destructuring-bind (counter label-style category predicate) - (assoc-default default-category org-odt-category-map-alist) + (cl-assert default-category) + (pcase-let + ((`(,counter ,label-style ,category ,predicate) + (assoc-default default-category org-odt-category-map-alist))) ;; Compute sequence number of the element. (setq seqno (org-odt--enumerate element info predicate)) ;; Localize category string. (setq category (org-export-translate category :utf-8 info)) - (case op + (cl-case op ;; Case 1: Handle Label definition. (definition (cons @@ -2238,7 +2181,7 @@ SHORT-CAPTION are strings." (target-dir "Images/") (target-file (format "%s%04d.%s" target-dir - (incf org-odt-embedded-images-count) image-type))) + (cl-incf org-odt-embedded-images-count) image-type))) (message "Embedding %s as %s..." (substring-no-properties path) target-file) @@ -2317,7 +2260,7 @@ SHORT-CAPTION are strings." "Return ODT code for an inline image. LINK is the link pointing to the inline image. INFO is a plist used as a communication channel." - (assert (eq (org-element-type element) 'link)) + (cl-assert (eq (org-element-type element) 'link)) (let* ((src (let* ((type (org-element-property :type element)) (raw-path (org-element-property :path element))) (cond ((member type '("http" "https")) @@ -2332,7 +2275,7 @@ used as a communication channel." "\n<draw:image xlink:href=\"%s\" xlink:type=\"simple\" xlink:show=\"embed\" xlink:actuate=\"onLoad\"/>" (org-odt--copy-image-file src-expanded))) ;; Extract attributes from #+ATTR_ODT line. - (attr-from (case (org-element-type element) + (attr-from (cl-case (org-element-type element) (link (org-export-get-parent-element element)) (t element))) ;; Convert attributes to a plist. @@ -2366,7 +2309,7 @@ used as a communication channel." (standalone-link-p (org-odt--standalone-link-p element info)) (embed-as (if standalone-link-p "paragraph" "as-char")) (captions (org-odt-format-label element info 'definition)) - (caption (car captions)) (short-caption (cdr captions)) + (caption (car captions)) (entity (concat (and caption "Captioned") embed-as "Image")) ;; Check if this link was created by LaTeX-to-PNG converter. (replaces (org-element-property @@ -2387,8 +2330,7 @@ used as a communication channel." ;;;; Links :: Math formula (defun org-odt-link--inline-formula (element info) - (let* ((src (let* ((type (org-element-property :type element)) - (raw-path (org-element-property :path element))) + (let* ((src (let ((raw-path (org-element-property :path element))) (cond ((file-name-absolute-p raw-path) (expand-file-name raw-path)) @@ -2404,7 +2346,6 @@ used as a communication channel." (standalone-link-p (org-odt--standalone-link-p element info)) (embed-as (if standalone-link-p 'paragraph 'character)) (captions (org-odt-format-label element info 'definition)) - (caption (car captions)) (short-caption (cdr captions)) ;; Check if this link was created by LaTeX-to-MathML ;; converter. (replaces (org-element-property @@ -2422,7 +2363,7 @@ used as a communication channel." (cond ((eq embed-as 'character) (org-odt--render-image/formula "InlineFormula" href width height - nil nil title desc)) + nil nil title desc)) (t (let* ((equation (org-odt--render-image/formula "CaptionedDisplayFormula" href width height @@ -2437,7 +2378,7 @@ used as a communication channel." (defun org-odt--copy-formula-file (src-file) "Returns the internal name of the file" (let* ((target-dir (format "Formula-%04d/" - (incf org-odt-embedded-formulas-count))) + (cl-incf org-odt-embedded-formulas-count))) (target-file (concat target-dir "content.xml"))) ;; Create a directory for holding formula file. Also enter it in ;; to manifest. @@ -2447,13 +2388,13 @@ used as a communication channel." ;; Copy over the formula file from user directory to zip ;; directory. (message "Embedding %s as %s..." src-file target-file) - (let ((case-fold-search nil)) + (let ((ext (file-name-extension src-file))) (cond ;; Case 1: Mathml. - ((string-match "\\.\\(mathml\\|mml\\)\\'" src-file) + ((member ext '("mathml" "mml")) (copy-file src-file (concat org-odt-zip-dir target-file) 'overwrite)) ;; Case 2: OpenDocument formula. - ((string-match "\\.odf\\'" src-file) + ((string= ext "odf") (org-odt--zip-extract src-file "content.xml" (concat org-odt-zip-dir target-dir))) (t (error "%s is not a formula file" src-file)))) @@ -2464,8 +2405,8 @@ used as a communication channel." ;;;; Targets (defun org-odt--render-image/formula (cfg-key href width height &optional - captions user-frame-params - &rest title-and-desc) + captions user-frame-params + &rest title-and-desc) (let* ((frame-cfg-alist ;; Each element of this alist is of the form (CFG-HANDLE ;; INNER-FRAME-PARAMS OUTER-FRAME-PARAMS). @@ -2527,11 +2468,11 @@ used as a communication channel." (lambda (default user) "Merge default and user frame params." (if (not user) default - (assert (= (length default) 3)) - (assert (= (length user) 3)) - (loop for u in user - for d in default - collect (or u d))))))) + (cl-assert (= (length default) 3)) + (cl-assert (= (length user) 3)) + (cl-loop for u in user + for d in default + collect (or u d))))))) (cond ;; Case 1: Image/Formula has no caption. ;; There is only one frame, one that surrounds the image @@ -2565,7 +2506,7 @@ used as a communication channel." caption)) width height outer))))) -(defun org-odt--enumerable-p (element info) +(defun org-odt--enumerable-p (element _info) ;; Element should have a caption or label. (or (org-element-property :caption element) (org-element-property :name element))) @@ -2582,7 +2523,7 @@ used as a communication channel." (org-element-property :name p)))) ;; Link should point to an image file. (lambda (l) - (assert (eq (org-element-type l) 'link)) + (cl-assert (eq (org-element-type l) 'link)) (org-export-inline-image-p l (plist-get info :odt-inline-image-rules))))) (defun org-odt--enumerable-latex-image-p (element info) @@ -2597,7 +2538,7 @@ used as a communication channel." (org-element-property :name p)))) ;; Link should point to an image file. (lambda (l) - (assert (eq (org-element-type l) 'link)) + (cl-assert (eq (org-element-type l) 'link)) (org-export-inline-image-p l (plist-get info :odt-inline-image-rules))))) (defun org-odt--enumerable-formula-p (element info) @@ -2609,12 +2550,12 @@ used as a communication channel." (org-element-property :name p))) ;; Link should point to a MathML or ODF file. (lambda (l) - (assert (eq (org-element-type l) 'link)) + (cl-assert (eq (org-element-type l) 'link)) (org-export-inline-image-p l (plist-get info :odt-inline-formula-rules))))) -(defun org-odt--standalone-link-p (element info &optional - paragraph-predicate - link-predicate) +(defun org-odt--standalone-link-p (element _info &optional + paragraph-predicate + link-predicate) "Test if ELEMENT is a standalone link for the purpose ODT export. INFO is a plist holding contextual information. @@ -2628,7 +2569,7 @@ PARAGRAPH-PREDICATE in addition to having no other content save for leading and trailing whitespaces. Return nil, otherwise." - (let ((p (case (org-element-type element) + (let ((p (cl-case (org-element-type element) (paragraph element) (link (and (or (not link-predicate) (funcall link-predicate element)) @@ -2638,16 +2579,16 @@ Return nil, otherwise." (when (or (not paragraph-predicate) (funcall paragraph-predicate p)) (let ((contents (org-element-contents p))) - (loop for x in contents - with inline-image-count = 0 - always (case (org-element-type x) - (plain-text - (not (org-string-nw-p x))) - (link - (and (or (not link-predicate) - (funcall link-predicate x)) - (= (incf inline-image-count) 1))) - (t nil)))))))) + (cl-loop for x in contents + with inline-image-count = 0 + always (cl-case (org-element-type x) + (plain-text + (not (org-string-nw-p x))) + (link + (and (or (not link-predicate) + (funcall link-predicate x)) + (= (cl-incf inline-image-count) 1))) + (t nil)))))))) (defun org-odt-link--infer-description (destination info) ;; DESTINATION is a headline or an element (like paragraph, @@ -2672,31 +2613,31 @@ Return nil, otherwise." (or (let* ( ;; Locate top-level list. (top-level-list - (loop for x on data - when (eq (org-element-type (car x)) 'plain-list) - return x)) + (cl-loop for x on data + when (eq (org-element-type (car x)) 'plain-list) + return x)) ;; Get list item nos. (item-numbers - (loop for (plain-list item . rest) on top-level-list by #'cddr - until (not (eq (org-element-type plain-list) 'plain-list)) - collect (when (eq (org-element-property :type - plain-list) - 'ordered) - (1+ (length (org-export-get-previous-element - item info t)))))) + (cl-loop for (plain-list item . rest) on top-level-list by #'cddr + until (not (eq (org-element-type plain-list) 'plain-list)) + collect (when (eq (org-element-property :type + plain-list) + 'ordered) + (1+ (length (org-export-get-previous-element + item info t)))))) ;; Locate top-most listified headline. (listified-headlines - (loop for x on data - when (and (eq (org-element-type (car x)) 'headline) - (org-export-low-level-p (car x) info)) - return x)) + (cl-loop for x on data + when (and (eq (org-element-type (car x)) 'headline) + (org-export-low-level-p (car x) info)) + return x)) ;; Get listified headline numbers. (listified-headline-nos - (loop for el in listified-headlines - when (eq (org-element-type el) 'headline) - collect (when (org-export-numbered-headline-p el info) - (1+ (length (org-export-get-previous-element - el info t))))))) + (cl-loop for el in listified-headlines + when (eq (org-element-type el) 'headline) + collect (when (org-export-numbered-headline-p el info) + (1+ (length (org-export-get-previous-element + el info t))))))) ;; Combine item numbers from both the listified headlines and ;; regular list items. @@ -2715,11 +2656,11 @@ Return nil, otherwise." (and ;; Test if destination is a numbered headline. (org-export-numbered-headline-p destination info) - (loop for el in (cons destination genealogy) - when (and (eq (org-element-type el) 'headline) - (not (org-export-low-level-p el info)) - (org-export-numbered-headline-p el info)) - return el)))) + (cl-loop for el in (cons destination genealogy) + when (and (eq (org-element-type el) 'headline) + (not (org-export-low-level-p el info)) + (org-export-numbered-headline-p el info)) + return el)))) ;; We found one. (when headline (format "<text:bookmark-ref text:reference-format=\"chapter\" text:ref-name=\"OrgXref.%s\">%s</text:bookmark-ref>" @@ -2728,10 +2669,10 @@ Return nil, otherwise." headline info) ".")))) ;; Case 4: Locate a regular headline in the hierarchy. Display ;; its title. - (let ((headline (loop for el in (cons destination genealogy) - when (and (eq (org-element-type el) 'headline) - (not (org-export-low-level-p el info))) - return el))) + (let ((headline (cl-loop for el in (cons destination genealogy) + when (and (eq (org-element-type el) 'headline) + (not (org-export-low-level-p el info))) + return el))) ;; We found one. (when headline (format "<text:bookmark-ref text:reference-format=\"text\" text:ref-name=\"OrgXref.%s\">%s</text:bookmark-ref>" @@ -2763,12 +2704,11 @@ INFO is a plist holding contextual information. See ;; Link type is handled by a special function. ((org-export-custom-protocol-maybe link desc 'odt)) ;; Image file. - ((and (not desc) (org-export-inline-image-p - link (plist-get info :odt-inline-image-rules))) - (org-odt-link--inline-image link info)) + ((and (not desc) imagep) (org-odt-link--inline-image link info)) ;; Formula file. - ((and (not desc) (org-export-inline-image-p - link (plist-get info :odt-inline-formula-rules))) + ((and (not desc) + (org-export-inline-image-p + link (plist-get info :odt-inline-formula-rules))) (org-odt-link--inline-formula link info)) ;; Radio target: Transcode target's contents and use them as ;; link's description. @@ -2785,7 +2725,7 @@ INFO is a plist holding contextual information. See (let ((destination (if (string= type "fuzzy") (org-export-resolve-fuzzy-link link info) (org-export-resolve-id-link link info)))) - (case (org-element-type destination) + (cl-case (org-element-type destination) ;; Fuzzy link points to a headline. If there's ;; a description, create a hyperlink. Otherwise, try to ;; provide a meaningful description. @@ -2862,7 +2802,7 @@ INFO is a plist holding contextual information. See ;;;; Node Property -(defun org-odt-node-property (node-property contents info) +(defun org-odt-node-property (node-property _contents _info) "Transcode a NODE-PROPERTY element from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." @@ -2881,7 +2821,7 @@ Style is a symbol among `quoted', `centered' and nil." (while (and (setq up (org-element-property :parent up)) (not (memq (org-element-type up) '(center-block quote-block section))))) - (case (org-element-type up) + (cl-case (org-element-type up) (center-block 'centered) (quote-block 'quoted)))) @@ -2893,7 +2833,7 @@ a plist used as a communication channel. DEFAULT, CENTER and QUOTE are, respectively, style to use when paragraph belongs to no special environment, a center block, or a quote block." (format "\n<text:p text:style-name=\"%s\">%s</text:p>" - (case (org-odt--paragraph-style paragraph) + (cl-case (org-odt--paragraph-style paragraph) (quoted quote) (centered center) (otherwise default)) @@ -2919,13 +2859,13 @@ the plist used as a communication channel." ;;;; Plain List -(defun org-odt-plain-list (plain-list contents info) +(defun org-odt-plain-list (plain-list contents _info) "Transcode a PLAIN-LIST element from Org to ODT. CONTENTS is the contents of the list. INFO is a plist holding contextual information." (format "\n<text:list text:style-name=\"%s\" %s>\n%s</text:list>" ;; Choose style based on list type. - (case (org-element-property :type plain-list) + (cl-case (org-element-property :type plain-list) (ordered "OrgNumberedList") (unordered "OrgBulletedList") (descriptive-1 "OrgDescriptionList") @@ -2954,10 +2894,8 @@ contextual information." line)) (defun org-odt--encode-plain-text (text &optional no-whitespace-filling) - (mapc - (lambda (pair) - (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t))) - '(("&" . "&") ("<" . "<") (">" . ">"))) + (dolist (pair '(("&" . "&") ("<" . "<") (">" . ">"))) + (setq text (replace-regexp-in-string (car pair) (cdr pair) text t t))) (if no-whitespace-filling text (org-odt--encode-tabs-and-spaces text))) @@ -2974,11 +2912,9 @@ contextual information." (setq output (org-export-activate-smart-quotes output :utf-8 info text))) ;; Convert special strings. (when (plist-get info :with-special-strings) - (mapc - (lambda (pair) - (setq output - (replace-regexp-in-string (car pair) (cdr pair) output t nil))) - org-odt-special-string-regexps)) + (dolist (pair org-odt-special-string-regexps) + (setq output + (replace-regexp-in-string (car pair) (cdr pair) output t nil)))) ;; Handle break preservation if required. (when (plist-get info :preserve-breaks) (setq output (replace-regexp-in-string @@ -3018,7 +2954,7 @@ channel." ;;;; Property Drawer -(defun org-odt-property-drawer (property-drawer contents info) +(defun org-odt-property-drawer (_property-drawer contents _info) "Transcode a PROPERTY-DRAWER element from Org to ODT. CONTENTS holds the contents of the drawer. INFO is a plist holding contextual information." @@ -3029,7 +2965,7 @@ holding contextual information." ;;;; Quote Block -(defun org-odt-quote-block (quote-block contents info) +(defun org-odt-quote-block (_quote-block contents _info) "Transcode a QUOTE-BLOCK element from Org to ODT. CONTENTS holds the contents of the block. INFO is a plist holding contextual information." @@ -3046,7 +2982,7 @@ holding contextual information." text))) -(defun org-odt-section (section contents info) ; FIXME +(defun org-odt-section (_section contents _info) ; FIXME "Transcode a SECTION element from Org to ODT. CONTENTS holds the contents of the section. INFO is a plist holding contextual information." @@ -3137,25 +3073,24 @@ and prefix with \"OrgSrc\". For example, (cons style-name style))) (defun org-odt-htmlfontify-string (line) - (let* ((hfy-html-quote-regex "\\([<\"&> ]\\)") + (let* ((hfy-html-quote-regex "\\([<\"&> \t]\\)") (hfy-html-quote-map '(("\"" """) ("<" "<") ("&" "&") (">" ">") (" " "<text:s/>") - (" " "<text:tab/>"))) + ("\t" "<text:tab/>"))) (hfy-face-to-css 'org-odt-hfy-face-to-css) (hfy-optimizations-1 (copy-sequence hfy-optimizations)) - (hfy-optimizations (add-to-list 'hfy-optimizations-1 - 'body-text-only)) + (hfy-optimizations (cl-pushnew 'body-text-only hfy-optimizations-1)) (hfy-begin-span-handler - (lambda (style text-block text-id text-begins-block-p) + (lambda (style _text-block _text-id _text-begins-block-p) (insert (format "<text:span text:style-name=\"%s\">" style)))) - (hfy-end-span-handler (lambda nil (insert "</text:span>")))) - (org-no-warnings (htmlfontify-string line)))) + (hfy-end-span-handler (lambda () (insert "</text:span>")))) + (with-no-warnings (htmlfontify-string line)))) (defun org-odt-do-format-code - (code info &optional lang refs retain-labels num-start) + (code info &optional lang refs retain-labels num-start) (let* ((lang (or (assoc-default lang org-src-lang-modes) lang)) (lang-mode (and lang (intern (format "%s-mode" lang)))) (code-lines (org-split-string code "\n")) @@ -3175,19 +3110,20 @@ and prefix with \"OrgSrc\". For example, (par-style (if use-htmlfontify-p "OrgSrcBlock" "OrgFixedWidthBlock")) (i 0)) - (assert (= code-length (length (org-split-string code "\n")))) + (cl-assert (= code-length (length (org-split-string code "\n")))) (setq code (org-export-format-code code (lambda (loc line-num ref) (setq par-style - (concat par-style (and (= (incf i) code-length) "LastLine"))) + (concat par-style (and (= (cl-incf i) code-length) + "LastLine"))) (setq loc (concat loc (and ref retain-labels (format " (%s)" ref)))) (setq loc (funcall fontifier loc)) (when ref (setq loc (org-odt--target loc (concat "coderef-" ref)))) - (assert par-style) + (cl-assert par-style) (setq loc (format "\n<text:p text:style-name=\"%s\">%s</text:p>" par-style loc)) (if (not line-num) loc @@ -3213,19 +3149,15 @@ and prefix with \"OrgSrc\". For example, ;; Does the src block contain labels? (retain-labels (org-element-property :retain-labels element)) ;; Does it have line numbers? - (num-start (case (org-element-property :number-lines element) - (continued (org-export-get-loc element info)) - (new 0)))) + (num-start (org-export-get-loc element info))) (org-odt-do-format-code code info lang refs retain-labels num-start))) -(defun org-odt-src-block (src-block contents info) +(defun org-odt-src-block (src-block _contents info) "Transcode a SRC-BLOCK element from Org to ODT. CONTENTS holds the contents of the item. INFO is a plist holding contextual information." - (let* ((lang (org-element-property :language src-block)) - (attributes (org-export-read-attribute :attr_odt src-block)) - (captions (org-odt-format-label src-block info 'definition)) - (caption (car captions)) (short-caption (cdr captions))) + (let* ((attributes (org-export-read-attribute :attr_odt src-block)) + (caption (car (org-odt-format-label src-block info 'definition)))) (concat (and caption (format "\n<text:p text:style-name=\"%s\">%s</text:p>" @@ -3239,7 +3171,7 @@ contextual information." ;;;; Statistics Cookie -(defun org-odt-statistics-cookie (statistics-cookie contents info) +(defun org-odt-statistics-cookie (statistics-cookie _contents _info) "Transcode a STATISTICS-COOKIE object from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." (let ((cookie-value (org-element-property :value statistics-cookie))) @@ -3249,7 +3181,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Strike-Through -(defun org-odt-strike-through (strike-through contents info) +(defun org-odt-strike-through (_strike-through contents _info) "Transcode STRIKE-THROUGH from Org to ODT. CONTENTS is the text with strike-through markup. INFO is a plist holding contextual information." @@ -3259,7 +3191,7 @@ holding contextual information." ;;;; Subscript -(defun org-odt-subscript (subscript contents info) +(defun org-odt-subscript (_subscript contents _info) "Transcode a SUBSCRIPT object from Org to ODT. CONTENTS is the contents of the object. INFO is a plist holding contextual information." @@ -3269,7 +3201,7 @@ contextual information." ;;;; Superscript -(defun org-odt-superscript (superscript contents info) +(defun org-odt-superscript (_superscript contents _info) "Transcode a SUPERSCRIPT object from Org to ODT. CONTENTS is the contents of the object. INFO is a plist holding contextual information." @@ -3324,23 +3256,23 @@ styles congruent with the ODF-1.2 specification." (cell-style-selectors (nth 2 style-spec)) (cell-type (cond - ((and (cdr (assoc 'use-first-column-styles cell-style-selectors)) + ((and (cdr (assq 'use-first-column-styles cell-style-selectors)) (= c 0)) "FirstColumn") - ((and (cdr (assoc 'use-last-column-styles cell-style-selectors)) + ((and (cdr (assq 'use-last-column-styles cell-style-selectors)) (= (1+ c) (cdr table-dimensions))) "LastColumn") - ((and (cdr (assoc 'use-first-row-styles cell-style-selectors)) + ((and (cdr (assq 'use-first-row-styles cell-style-selectors)) (= r 0)) "FirstRow") - ((and (cdr (assoc 'use-last-row-styles cell-style-selectors)) + ((and (cdr (assq 'use-last-row-styles cell-style-selectors)) (= (1+ r) (car table-dimensions))) "LastRow") - ((and (cdr (assoc 'use-banding-rows-styles cell-style-selectors)) + ((and (cdr (assq 'use-banding-rows-styles cell-style-selectors)) (= (% r 2) 1)) "EvenRow") - ((and (cdr (assoc 'use-banding-rows-styles cell-style-selectors)) + ((and (cdr (assq 'use-banding-rows-styles cell-style-selectors)) (= (% r 2) 0)) "OddRow") - ((and (cdr (assoc 'use-banding-columns-styles cell-style-selectors)) + ((and (cdr (assq 'use-banding-columns-styles cell-style-selectors)) (= (% c 2) 1)) "EvenColumn") - ((and (cdr (assoc 'use-banding-columns-styles cell-style-selectors)) + ((and (cdr (assq 'use-banding-columns-styles cell-style-selectors)) (= (% c 2) 0)) "OddColumn") (t "")))) (concat template-name cell-type))))) @@ -3398,17 +3330,16 @@ channel." (1+ horiz-span)))))) (unless contents (setq contents "")) (concat - (assert paragraph-style) + (cl-assert paragraph-style) (format "\n<table:table-cell%s>\n%s\n</table:table-cell>" cell-attributes (let ((table-cell-contents (org-element-contents table-cell))) - (if (memq (org-element-type (car table-cell-contents)) - org-element-all-elements) + (if (eq (org-element-class (car table-cell-contents)) 'element) contents (format "\n<text:p text:style-name=\"%s\">%s</text:p>" paragraph-style contents)))) (let (s) - (dotimes (i horiz-span s) + (dotimes (_ horiz-span s) (setq s (concat s "\n<table:covered-table-cell/>")))) "\n"))) @@ -3459,7 +3390,7 @@ communication channel." "Transcode a TABLE element from Org to ODT. CONTENTS is the contents of the table. INFO is a plist holding contextual information." - (case (org-element-property :type table) + (cl-case (org-element-property :type table) ;; Case 1: table.el doesn't support export to OD format. Strip ;; such tables from export. (table.el @@ -3476,20 +3407,19 @@ contextual information." (attributes (org-export-read-attribute :attr_odt table)) (custom-table-style (nth 1 (org-odt-table-style-spec table info))) (table-column-specs - (function - (lambda (table info) - (let* ((table-style (or custom-table-style "OrgTable")) - (column-style (format "%sColumn" table-style))) - (mapconcat - (lambda (table-cell) - (let ((width (1+ (or (org-export-table-cell-width - table-cell info) 0))) - (s (format - "\n<table:table-column table:style-name=\"%s\"/>" - column-style)) - out) - (dotimes (i width out) (setq out (concat s out))))) - (org-odt-table-first-row-data-cells table info) "\n")))))) + (lambda (table info) + (let* ((table-style (or custom-table-style "OrgTable")) + (column-style (format "%sColumn" table-style))) + (mapconcat + (lambda (table-cell) + (let ((width (1+ (or (org-export-table-cell-width + table-cell info) 0))) + (s (format + "\n<table:table-column table:style-name=\"%s\"/>" + column-style)) + out) + (dotimes (_ width out) (setq out (concat s out))))) + (org-odt-table-first-row-data-cells table info) "\n"))))) (concat ;; caption. (when caption @@ -3518,84 +3448,84 @@ contextual information. Use `org-odt--table' to typeset the table. Handle details pertaining to indentation here." (let* ((--element-preceded-by-table-p - (function - (lambda (element info) - (loop for el in (org-export-get-previous-element element info t) - thereis (eq (org-element-type el) 'table))))) + (lambda (element info) + (cl-loop for el in (org-export-get-previous-element element info t) + thereis (eq (org-element-type el) 'table)))) (--walk-list-genealogy-and-collect-tags - (function - (lambda (table info) - (let* ((genealogy (org-element-lineage table)) - (list-genealogy - (when (eq (org-element-type (car genealogy)) 'item) - (loop for el in genealogy - when (memq (org-element-type el) - '(item plain-list)) - collect el))) - (llh-genealogy - (apply 'nconc - (loop for el in genealogy - when (and (eq (org-element-type el) 'headline) - (org-export-low-level-p el info)) - collect - (list el - (assq 'headline - (org-element-contents - (org-export-get-parent el))))))) - parent-list) - (nconc - ;; Handle list genealogy. - (loop for el in list-genealogy collect - (case (org-element-type el) - (plain-list - (setq parent-list el) - (cons "</text:list>" - (format "\n<text:list text:style-name=\"%s\" %s>" - (case (org-element-property :type el) - (ordered "OrgNumberedList") - (unordered "OrgBulletedList") - (descriptive-1 "OrgDescriptionList") - (descriptive-2 "OrgDescriptionList")) - "text:continue-numbering=\"true\""))) - (item - (cond - ((not parent-list) - (if (funcall --element-preceded-by-table-p table info) - '("</text:list-header>" . "<text:list-header>") - '("</text:list-item>" . "<text:list-header>"))) - ((funcall --element-preceded-by-table-p - parent-list info) - '("</text:list-header>" . "<text:list-header>")) - (t '("</text:list-item>" . "<text:list-item>")))))) - ;; Handle low-level headlines. - (loop for el in llh-genealogy - with step = 'item collect - (case step - (plain-list - (setq step 'item) ; Flip-flop - (setq parent-list el) - (cons "</text:list>" - (format "\n<text:list text:style-name=\"%s\" %s>" - (if (org-export-numbered-headline-p - el info) - "OrgNumberedList" - "OrgBulletedList") - "text:continue-numbering=\"true\""))) - (item - (setq step 'plain-list) ; Flip-flop - (cond - ((not parent-list) - (if (funcall --element-preceded-by-table-p table info) - '("</text:list-header>" . "<text:list-header>") - '("</text:list-item>" . "<text:list-header>"))) - ((let ((section? (org-export-get-previous-element - parent-list info))) - (and section? - (eq (org-element-type section?) 'section) - (assq 'table (org-element-contents section?)))) - '("</text:list-header>" . "<text:list-header>")) - (t - '("</text:list-item>" . "<text:list-item>"))))))))))) + (lambda (table info) + (let* ((genealogy (org-element-lineage table)) + (list-genealogy + (when (eq (org-element-type (car genealogy)) 'item) + (cl-loop for el in genealogy + when (memq (org-element-type el) + '(item plain-list)) + collect el))) + (llh-genealogy + (apply #'nconc + (cl-loop + for el in genealogy + when (and (eq (org-element-type el) 'headline) + (org-export-low-level-p el info)) + collect + (list el + (assq 'headline + (org-element-contents + (org-export-get-parent el))))))) + parent-list) + (nconc + ;; Handle list genealogy. + (cl-loop + for el in list-genealogy collect + (cl-case (org-element-type el) + (plain-list + (setq parent-list el) + (cons "</text:list>" + (format "\n<text:list text:style-name=\"%s\" %s>" + (cl-case (org-element-property :type el) + (ordered "OrgNumberedList") + (unordered "OrgBulletedList") + (descriptive-1 "OrgDescriptionList") + (descriptive-2 "OrgDescriptionList")) + "text:continue-numbering=\"true\""))) + (item + (cond + ((not parent-list) + (if (funcall --element-preceded-by-table-p table info) + '("</text:list-header>" . "<text:list-header>") + '("</text:list-item>" . "<text:list-header>"))) + ((funcall --element-preceded-by-table-p + parent-list info) + '("</text:list-header>" . "<text:list-header>")) + (t '("</text:list-item>" . "<text:list-item>")))))) + ;; Handle low-level headlines. + (cl-loop for el in llh-genealogy + with step = 'item collect + (cl-case step + (plain-list + (setq step 'item) ; Flip-flop + (setq parent-list el) + (cons "</text:list>" + (format "\n<text:list text:style-name=\"%s\" %s>" + (if (org-export-numbered-headline-p + el info) + "OrgNumberedList" + "OrgBulletedList") + "text:continue-numbering=\"true\""))) + (item + (setq step 'plain-list) ; Flip-flop + (cond + ((not parent-list) + (if (funcall --element-preceded-by-table-p table info) + '("</text:list-header>" . "<text:list-header>") + '("</text:list-item>" . "<text:list-header>"))) + ((let ((section? (org-export-get-previous-element + parent-list info))) + (and section? + (eq (org-element-type section?) 'section) + (assq 'table (org-element-contents section?)))) + '("</text:list-header>" . "<text:list-header>")) + (t + '("</text:list-item>" . "<text:list-item>")))))))))) (close-open-tags (funcall --walk-list-genealogy-and-collect-tags table info))) ;; OpenDocument schema does not permit table to occur within a @@ -3641,7 +3571,7 @@ pertaining to indentation here." ;; ;; - Description lists are simulated as plain lists. ;; - Low-level headlines can be listified. - ;; - In Org-mode, a table can occur not only as a regular list + ;; - In Org mode, a table can occur not only as a regular list ;; item, but also within description lists and low-level ;; headlines. @@ -3663,7 +3593,7 @@ pertaining to indentation here." ;;;; Target -(defun org-odt-target (target contents info) +(defun org-odt-target (target _contents info) "Transcode a TARGET object from Org to ODT. CONTENTS is nil. INFO is a plist holding contextual information." @@ -3672,16 +3602,15 @@ information." ;;;; Timestamp -(defun org-odt-timestamp (timestamp contents info) +(defun org-odt-timestamp (timestamp _contents info) "Transcode a TIMESTAMP object from Org to ODT. CONTENTS is nil. INFO is a plist used as a communication channel." - (let* ((raw-value (org-element-property :raw-value timestamp)) - (type (org-element-property :type timestamp))) + (let ((type (org-element-property :type timestamp))) (if (not (plist-get info :odt-use-date-fields)) (let ((value (org-odt-plain-text (org-timestamp-translate timestamp) info))) - (case (org-element-property :type timestamp) + (cl-case (org-element-property :type timestamp) ((active active-range) (format "<text:span text:style-name=\"%s\">%s</text:span>" "OrgActiveTimestamp" value)) @@ -3689,7 +3618,7 @@ channel." (format "<text:span text:style-name=\"%s\">%s</text:span>" "OrgInactiveTimestamp" value)) (otherwise value))) - (case type + (cl-case type (active (format "<text:span text:style-name=\"%s\">%s</text:span>" "OrgActiveTimestamp" @@ -3719,7 +3648,7 @@ channel." ;;;; Underline -(defun org-odt-underline (underline contents info) +(defun org-odt-underline (_underline contents _info) "Transcode UNDERLINE from Org to ODT. CONTENTS is the text with underline markup. INFO is a plist holding contextual information." @@ -3729,7 +3658,7 @@ holding contextual information." ;;;; Verbatim -(defun org-odt-verbatim (verbatim contents info) +(defun org-odt-verbatim (verbatim _contents _info) "Transcode a VERBATIM object from Org to ODT. CONTENTS is nil. INFO is a plist used as a communication channel." @@ -3740,7 +3669,7 @@ channel." ;;;; Verse Block -(defun org-odt-verse-block (verse-block contents info) +(defun org-odt-verse-block (_verse-block contents _info) "Transcode a VERSE-BLOCK element from Org to ODT. CONTENTS is verse block contents. INFO is a plist holding contextual information." @@ -3760,13 +3689,13 @@ contextual information." ;;;; LaTeX fragments -(defun org-odt--translate-latex-fragments (tree backend info) +(defun org-odt--translate-latex-fragments (tree _backend info) (let ((processing-type (plist-get info :with-latex)) (count 0)) ;; Normalize processing-type to one of dvipng, mathml or verbatim. ;; If the desired converter is not available, force verbatim ;; processing. - (case processing-type + (cl-case processing-type ((t mathml) (if (and (fboundp 'org-format-latex-mathml-available-p) (org-format-latex-mathml-available-p)) @@ -3792,18 +3721,18 @@ contextual information." (when (memq processing-type '(mathml dvipng imagemagick)) (org-element-map tree '(latex-fragment latex-environment) (lambda (latex-*) - (incf count) + (cl-incf count) (let* ((latex-frag (org-element-property :value latex-*)) (input-file (plist-get info :input-file)) (cache-dir (file-name-directory input-file)) (cache-subdir (concat - (case processing-type + (cl-case processing-type ((dvipng imagemagick) "ltxpng/") (mathml "ltxmathml/")) (file-name-sans-extension (file-name-nondirectory input-file)))) (display-msg - (case processing-type + (cl-case processing-type ((dvipng imagemagick) (format "Creating LaTeX Image %d..." count)) (mathml (format "Creating MathML snippet %d..." count)))) @@ -3817,7 +3746,7 @@ contextual information." nil processing-type) (buffer-substring-no-properties (point-min) (point-max))))) - (if (org-string-match-p "file:\\([^]]*\\)" link) link + (if (string-match-p "file:\\([^]]*\\)" link) link (message "LaTeX Conversion failed.") nil)))) (when org-link @@ -3828,7 +3757,7 @@ contextual information." (org-element-parse-secondary-string org-link '(link)) 'link #'identity info t)) (replacement - (case (org-element-type latex-*) + (cl-case (org-element-type latex-*) ;; Case 1: LaTeX environment. Mimic ;; a "standalone image or formula" by ;; enclosing the `link' in a `paragraph'. @@ -3864,7 +3793,7 @@ contextual information." ;; This translator is necessary to handle indented tables in a uniform ;; manner. See comment in `org-odt--table'. -(defun org-odt--translate-description-lists (tree backend info) +(defun org-odt--translate-description-lists (tree _backend info) ;; OpenDocument has no notion of a description list. So simulate it ;; using plain lists. Description lists in the exported document ;; are typeset in the same manner as they are in a typical HTML @@ -3897,7 +3826,7 @@ contextual information." ;; (org-element-map tree 'plain-list (lambda (el) - (when (equal (org-element-property :type el) 'descriptive) + (when (eq (org-element-property :type el) 'descriptive) (org-element-set-element el (apply 'org-element-adopt-elements @@ -3960,7 +3889,7 @@ contextual information." ;; Translate lists to tables -(defun org-odt--translate-list-tables (tree backend info) +(defun org-odt--translate-list-tables (tree _backend info) (org-element-map tree 'plain-list (lambda (l1-list) (when (org-export-read-attribute :attr_odt l1-list :list-table) @@ -4021,42 +3950,38 @@ contextual information." (insert "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\" manifest:version=\"1.2\">\n") - (mapc - (lambda (file-entry) - (let* ((version (nth 2 file-entry)) - (extra (if (not version) "" - (format " manifest:version=\"%s\"" version)))) - (insert - (format org-odt-manifest-file-entry-tag - (nth 0 file-entry) (nth 1 file-entry) extra)))) - org-odt-manifest-file-entries) + (dolist (file-entry org-odt-manifest-file-entries) + (let* ((version (nth 2 file-entry)) + (extra (if (not version) "" + (format " manifest:version=\"%s\"" version)))) + (insert + (format org-odt-manifest-file-entry-tag + (nth 0 file-entry) (nth 1 file-entry) extra)))) (insert "\n</manifest:manifest>")))) (defmacro org-odt--export-wrap (out-file &rest body) `(let* ((--out-file ,out-file) (out-file-type (file-name-extension --out-file)) (org-odt-xml-files '("META-INF/manifest.xml" "content.xml" - "meta.xml" "styles.xml")) + "meta.xml" "styles.xml")) ;; Initialize temporary workarea. All files that end up in ;; the exported document get parked/created here. (org-odt-zip-dir (file-name-as-directory - (make-temp-file (format "%s-" out-file-type) t))) + (make-temp-file (format "%s-" out-file-type) t))) (org-odt-manifest-file-entries nil) (--cleanup-xml-buffers - (function - (lambda nil - ;; Kill all XML buffers. - (mapc (lambda (file) - (let ((buf (find-buffer-visiting - (concat org-odt-zip-dir file)))) - (when buf - (with-current-buffer buf - (set-buffer-modified-p nil) - (kill-buffer buf))))) - org-odt-xml-files) - ;; Delete temporary directory and also other embedded - ;; files that get copied there. - (delete-directory org-odt-zip-dir t))))) + (lambda () + ;; Kill all XML buffers. + (dolist (file org-odt-xml-files) + (let ((buf (find-buffer-visiting + (concat org-odt-zip-dir file)))) + (when buf + (with-current-buffer buf + (set-buffer-modified-p nil) + (kill-buffer buf))))) + ;; Delete temporary directory and also other embedded + ;; files that get copied there. + (delete-directory org-odt-zip-dir t)))) (condition-case err (progn (unless (executable-find "zip") @@ -4079,16 +4004,15 @@ contextual information." ;; Write out the manifest entries before zipping (org-odt-write-manifest-file) ;; Save all XML files. - (mapc (lambda (file) - (let ((buf (find-buffer-visiting - (concat org-odt-zip-dir file)))) - (when buf - (with-current-buffer buf - ;; Prettify output if needed. - (when org-odt-prettify-xml - (indent-region (point-min) (point-max))) - (save-buffer 0))))) - org-odt-xml-files) + (dolist (file org-odt-xml-files) + (let ((buf (find-buffer-visiting + (concat org-odt-zip-dir file)))) + (when buf + (with-current-buffer buf + ;; Prettify output if needed. + (when org-odt-prettify-xml + (indent-region (point-min) (point-max))) + (save-buffer 0))))) ;; Run zip. (let* ((target --out-file) (target-name (file-name-nondirectory target)) @@ -4106,19 +4030,17 @@ contextual information." ;; directory. (with-current-buffer (find-file-noselect (concat org-odt-zip-dir "content.xml") t) - (mapc - (lambda (cmd) - (message "Running %s" (mapconcat 'identity cmd " ")) - (setq err-string - (with-output-to-string - (setq exitcode - (apply 'call-process (car cmd) - nil standard-output nil (cdr cmd))))) - (or (zerop exitcode) - (error (concat "Unable to create OpenDocument file." - " Zip failed with error (%s)") - err-string))) - cmds))) + (dolist (cmd cmds) + (message "Running %s" (mapconcat 'identity cmd " ")) + (setq err-string + (with-output-to-string + (setq exitcode + (apply 'call-process (car cmd) + nil standard-output nil (cdr cmd))))) + (or (zerop exitcode) + (error (concat "Unable to create OpenDocument file." + " Zip failed with error (%s)") + err-string))))) ;; Move the zip file from temporary work directory to ;; user-mandated location. (rename-file (concat org-odt-zip-dir target-name) target) @@ -4162,9 +4084,9 @@ MathML source to kill ring depending on the value of (setq frag (and (setq frag (and (region-active-p) (buffer-substring (region-beginning) (region-end)))) - (loop for e in org-latex-regexps - thereis (when (string-match (nth 1 e) frag) - (match-string (nth 2 e) frag))))) + (cl-loop for e in org-latex-regexps + thereis (when (string-match (nth 1 e) frag) + (match-string (nth 2 e) frag))))) (read-string "LaTeX Fragment: " frag nil frag)) ,(let ((odf-filename (expand-file-name (concat @@ -4292,12 +4214,12 @@ Return output file's name." (when out-fmt-spec (throw 'done (cons (car e) out-fmt-spec)))))))) -(defun org-odt-do-convert (in-file out-fmt &optional prefix-arg) +(defun org-odt-do-convert (in-file out-fmt &optional open) "Workhorse routine for `org-odt-convert'." (require 'browse-url) - (let* ((in-file (expand-file-name (or in-file buffer-file-name))) - (dummy (or (file-readable-p in-file) - (error "Cannot read %s" in-file))) + (let* ((in-file (let ((f (expand-file-name (or in-file buffer-file-name)))) + (if (file-readable-p f) f + (error "Cannot read %s" in-file)))) (in-fmt (file-name-extension in-file)) (out-fmt (or out-fmt (error "Output format unspecified"))) (how (or (org-odt-reachable-p in-fmt out-fmt) @@ -4327,7 +4249,7 @@ Return output file's name." (cond ((file-exists-p out-file) (message "Exported to %s" out-file) - (when prefix-arg + (when open (message "Opening %s..." out-file) (org-open-file out-file 'system)) out-file) @@ -4360,12 +4282,10 @@ form (CONVERTER-PROCESS . OUTPUT-FMT-ALIST). See (defun org-odt-reachable-formats (in-fmt) "Return list of formats to which IN-FMT can be converted. The list of the form (OUTPUT-FMT-1 OUTPUT-FMT-2 ...)." - (let (l) - (mapc (lambda (e) (add-to-list 'l e)) - (apply 'append (mapcar - (lambda (e) (mapcar 'car (cdr e))) - (org-odt-do-reachable-formats in-fmt)))) - l)) + (copy-sequence + (apply #'append (mapcar + (lambda (e) (mapcar #'car (cdr e))) + (org-odt-do-reachable-formats in-fmt))))) (defun org-odt-convert-read-params () "Return IN-FILE and OUT-FMT params for `org-odt-do-convert'. @@ -4385,25 +4305,23 @@ This is a helper routine for interactive use." (list in-file out-fmt))) ;;;###autoload -(defun org-odt-convert (&optional in-file out-fmt prefix-arg) +(defun org-odt-convert (&optional in-file out-fmt open) "Convert IN-FILE to format OUT-FMT using a command line converter. IN-FILE is the file to be converted. If unspecified, it defaults to variable `buffer-file-name'. OUT-FMT is the desired output -format. Use `org-odt-convert-process' as the converter. -If PREFIX-ARG is non-nil then the newly converted file is opened -using `org-open-file'." +format. Use `org-odt-convert-process' as the converter. If OPEN +is non-nil then the newly converted file is opened using +`org-open-file'." (interactive (append (org-odt-convert-read-params) current-prefix-arg)) - (org-odt-do-convert in-file out-fmt prefix-arg)) + (org-odt-do-convert in-file out-fmt open)) ;;; Library Initializations -(mapc - (lambda (desc) - ;; Let Emacs open all OpenDocument files in archive mode - (add-to-list 'auto-mode-alist - (cons (concat "\\." (car desc) "\\'") 'archive-mode))) - org-odt-file-extensions) +(dolist (desc org-odt-file-extensions) + ;; Let Emacs open all OpenDocument files in archive mode. + (add-to-list 'auto-mode-alist + (cons (concat "\\." (car desc) "\\'") 'archive-mode))) (provide 'ox-odt) |