From 30b260e0971e99ba54f4aff77bd8f36f6c649a9e Mon Sep 17 00:00:00 2001 From: Daniel Weschke Date: Fri, 2 Jan 2026 14:08:48 +0100 Subject: [PATCH] add math label and untabify --- lisp/ox-rst/ox-rst.el | 983 ++++++++++++++++++++++-------------------- 1 file changed, 517 insertions(+), 466 deletions(-) diff --git a/lisp/ox-rst/ox-rst.el b/lisp/ox-rst/ox-rst.el index 26d78313..d037d1a4 100644 --- a/lisp/ox-rst/ox-rst.el +++ b/lisp/ox-rst/ox-rst.el @@ -89,8 +89,8 @@ (latex-math-block . org-rst-math-block)) :menu-entry '(?r "Export to reStructuredText" - ((?R "As reStructuredText buffer" org-rst-export-as-rst) - (?r "As reStructuredText file" org-rst-export-to-rst))) + ((?R "As reStructuredText buffer" org-rst-export-as-rst) + (?r "As reStructuredText file" org-rst-export-to-rst))) :options-alist '((:subtitle "SUBTITLE" nil nil parse) (:rst-head "RST_HEAD" nil org-rst-head newline) @@ -98,11 +98,13 @@ (:rst-metadata nil "rst-metadata" org-rst-metadata) (:rst-metadata-format nil nil org-rst-metadata-format) (:rst-metadata-timestamp-format nil nil org-rst-metadata-timestamp-format) + (:rst-equation-reference-format "RST_EQUATION_REFERENCE_FORMAT" nil org-rst-equation-reference-format t) (:rst-inline-images nil nil org-rst-inline-images) (:rst-inline-image-rules nil nil org-rst-inline-image-rules) (:rst-link-org-files-as-rst nil nil org-rst-link-org-files-as-rst) (:rst-link-home "RST_LINK_HOME" nil org-rst-link-home) (:rst-link-use-ref-role nil nil org-rst-link-use-ref-role) + (:rst-prefer-user-labels nil nil org-rst-prefer-user-labels) (:rst-extension nil nil org-rst-extension) (:rst-file-link-use-ref-role nil nil org-rst-file-link-use-ref-role) (:rst-text-markup-alist nil nil org-rst-text-markup-alist) @@ -116,13 +118,17 @@ (:rst-pygments-langs nil nil org-rst-pygments-langs)) :filters-alist '((:filter-options . org-rst-math-block-options-filter) (:filter-headline . org-rst-filter-headline-blank-lines) - (:filter-parse-tree . (org-rst-math-block-tree-filter + (:filter-parse-tree . (org-rst-math-block-tree-filter org-rst-separate-elements - org-rst-filter-paragraph-spacing)))) + org-rst-filter-paragraph-spacing)))) ;;; Internal Variables +(defvar org-rst--id-attr-prefix "ID-" + "Prefix to use in ID attributes. +This affects IDs that are determined from the ID property.") + ;;; User Configurable Variables @@ -218,10 +224,10 @@ Usage: " :group 'org-export-rst :type '(choice (const :tag "No postamble" nil) - (const :tag "Auto postamble" auto) - (const :tag "Default formatting string" t) - (string :tag "Custom formatting string") - (function :tag "Function (must return a string)"))) + (const :tag "Auto postamble" auto) + (const :tag "Default formatting string" t) + (string :tag "Custom formatting string") + (function :tag "Function (must return a string)"))) (defcustom org-rst-metadata-format " @@ -238,8 +244,7 @@ contain these elements: %a stands for the author's name. %e stands for the author's email. %d stands for the date. - %c will be replaced by `org-html-creator-string'. - %v will be replaced by `org-html-validation-link'. + %c will be replaced by `org-rst-creator-string'. %T will be replaced by the export time. %C will be replaced by the last modification time. @@ -288,7 +293,7 @@ to consider, and value is a regexp that will be matched against link's path." :group 'org-export-rst :type '(alist :key-type (string :tag "Type") - :value-type (regexp :tag "Path"))) + :value-type (regexp :tag "Path"))) (defcustom org-rst-link-use-ref-role nil "Non-nil means export internal links using :ref: role." @@ -301,9 +306,9 @@ link's path." :type 'boolean) (defcustom org-rst-text-markup-alist '((bold . "**%s**") - (code . verb) - (italic . "*%s*") - (verbatim . verb)) + (code . verb) + (italic . "*%s*") + (verbatim . verb)) "Alist of reStructredText expressions to convert text markup. The key must be a symbol among `bold', `code', `italic', @@ -338,10 +343,10 @@ A nil value replicates the number of blank lines found in the original Org buffer at the same place." :group 'org-export-rst :type '(choice - (const :tag "Replicate original spacing" nil) - (cons :tag "Set a uniform spacing" - (integer :tag "Number of blank lines before contents") - (integer :tag "Number of blank lines after contents")))) + (const :tag "Replicate original spacing" nil) + (cons :tag "Set a uniform spacing" + (integer :tag "Number of blank lines before contents") + (integer :tag "Number of blank lines after contents")))) (defcustom org-rst-paragraph-spacing 'auto @@ -351,8 +356,8 @@ between contiguous paragraphs. If is it the symbol `auto', keep the same number of blank lines as in the original document." :group 'org-export-rst :type '(choice - (integer :tag "Number of blank lines") - (const :tag "Preserve original spacing" auto))) + (integer :tag "Number of blank lines") + (const :tag "Preserve original spacing" auto))) (defcustom org-rst-headline-underline-characters '(?- ?~ ?^ ?: ?' ?\ ?_) @@ -380,6 +385,25 @@ in order to mimic default behaviour: :group 'org-export-rst :type 'function) +;;;; RST-specific + +(defcustom org-rst-prefer-user-labels nil + "When non-nil use user-defined names and ID over internal ones. + +By default, Org generates its own internal ID values during RST +export. This process ensures that these values are unique and +valid, but the keys are not available in advance of the export +process, and not so readable. + +When this variable is non-nil, Org will use NAME keyword, or the +real name of the target to create the ID attribute. + +Independently of this variable, however, CUSTOM_ID are always +used as a reference." + :group 'org-export-rst + :type 'boolean + :safe #'booleanp) + ;;;; Inlinetasks @@ -399,6 +423,26 @@ The function should return the string to be exported." :type 'function) +;;;; LaTeX + +(defcustom org-rst-equation-reference-format "\\eqref{%s}" + "The MathJax command to use when referencing equations. + +This is a format control string that expects a single string argument +specifying the label that is being referenced. The argument is +generated automatically on export. + +The default is to wrap equations in parentheses (using \"\\eqref{%s}\)\". + +Most common values are: + + \\eqref{%s} Wrap the equation in parentheses + \\ref{%s} Do not wrap the equation in parentheses" + :group 'org-export-rst + :type 'string + :safe #'stringp) + + ;;;; Src blocks (defcustom org-rst-code-block 'code @@ -427,9 +471,9 @@ listings name are the same, the language does not need an entry in this list - but it does not hurt if it is present." :group 'org-export-rst :type '(repeat - (list - (symbol :tag "Major mode ") - (string :tag "Pygments language")))) + (list + (symbol :tag "Major mode ") + (string :tag "Pygments language")))) (defcustom org-rst-metadata-timestamp-format "%Y-%m-%d %a %H:%M" "Format used for timestamps in metadata. @@ -450,12 +494,12 @@ HOW determines the type of justification: it can be `left', (insert s) (goto-char (point-min)) (let ((fill-column text-width) - ;; Disable `adaptive-fill-mode' so it doesn't prevent - ;; filling lines matching `adaptive-fill-regexp'. - (adaptive-fill-mode nil)) + ;; Disable `adaptive-fill-mode' so it doesn't prevent + ;; filling lines matching `adaptive-fill-regexp'. + (adaptive-fill-mode nil)) (while (< (point) (point-max)) - (justify-current-line how) - (forward-line))) + (justify-current-line how) + (forward-line))) (buffer-string))) @@ -477,8 +521,8 @@ attributes with a nil value will be omitted from the result." ((symbolp item) (push (substring (symbol-name item) 1) output)) (t (let ((key (org-trim (car output))) (value (replace-regexp-in-string "\"" "\\\"" - (replace-regexp-in-string - "\\\\" "\\\\" (org-trim item))))) + (replace-regexp-in-string + "\\\\" "\\\\" (org-trim item))))) (setcar output (format " :%s: %s" key value)))))))) @@ -499,51 +543,51 @@ the title. When optional argument TOC is non-nil, use optional title if possible. It doesn't apply to `inlinetask' elements." (let* ((headlinep (org-element-type-p element 'headline)) - (numbers - ;; Numbering is specific to headlines. - (and headlinep (org-export-numbered-headline-p element info) - ;; All tests passed: build numbering string. - (concat - (mapconcat - 'number-to-string - (org-export-get-headline-number element info) ".") - " "))) - (text - (org-trim - (org-export-data - (if (and toc headlinep) (org-export-get-alt-title element info) - (org-element-property :title element)) - info))) - (todo - (and (plist-get info :with-todo-keywords) - (let ((todo (org-element-property :todo-keyword element))) - (and todo (concat (org-export-data todo info) " "))))) - (tags (and (not notags) - (plist-get info :with-tags) - (let ((tag-list (org-export-get-tags element info))) - (and tag-list + (numbers + ;; Numbering is specific to headlines. + (and headlinep (org-export-numbered-headline-p element info) + ;; All tests passed: build numbering string. + (concat + (mapconcat + 'number-to-string + (org-export-get-headline-number element info) ".") + " "))) + (text + (org-trim + (org-export-data + (if (and toc headlinep) (org-export-get-alt-title element info) + (org-element-property :title element)) + info))) + (todo + (and (plist-get info :with-todo-keywords) + (let ((todo (org-element-property :todo-keyword element))) + (and todo (concat (org-export-data todo info) " "))))) + (tags (and (not notags) + (plist-get info :with-tags) + (let ((tag-list (org-export-get-tags element info))) + (and tag-list (org-make-tag-string tag-list))))) - (priority - (and (plist-get info :with-priority) - (let ((char (org-element-property :priority element))) - (and char (format "(#%c) " char))))) - (first-part (concat numbers todo priority text))) + (priority + (and (plist-get info :with-priority) + (let ((char (org-element-property :priority element))) + (and char (format "(#%c) " char))))) + (first-part (concat numbers todo priority text))) (concat first-part ;; Align tags, if any. (when tags (format - (format " %%%ds" (string-width tags)) - tags)) + (format " %%%ds" (string-width tags)) + tags)) ;; Maybe underline text, if ELEMENT type is `headline' and an ;; underline character has been defined. (when (and underline headlinep) (let ((under-char - (nth (1- (org-export-get-relative-level element info)) - org-rst-headline-underline-characters))) - (and under-char - (concat "\n" - (make-string (string-width first-part) under-char)))))))) + (nth (1- (org-export-get-relative-level element info)) + org-rst-headline-underline-characters))) + (and under-char + (concat "\n" + (make-string (string-width first-part) under-char)))))))) (defun org-rst--text-markup (text markup info) @@ -559,17 +603,17 @@ See `org-rst-text-markup-alist' for details." ;; special chars and use "\\" escape. ((eq 'verb fmt) (let ((rtn "") - char) - (while (string-match "\\`*" text) - (setq char (match-string 0 text)) - (when (> (match-beginning 0) 0) - (setq rtn (concat rtn (substring text 0 (match-beginning 0))))) - (setq text (substring text (1+ (match-beginning 0)))) - (setq char (concat "\\" char) - rtn (concat rtn char))) - (setq text (concat rtn text) - fmt "``%s``") - (format fmt text))) + char) + (while (string-match "\\`*" text) + (setq char (match-string 0 text)) + (when (> (match-beginning 0) 0) + (setq rtn (concat rtn (substring text 0 (match-beginning 0))))) + (setq text (substring text (1+ (match-beginning 0)))) + (setq char (concat "\\" char) + rtn (concat rtn char))) + (setq text (concat rtn text) + fmt "``%s``") + (format fmt text))) ;; Else use format string. (t (format fmt text))))) @@ -577,15 +621,15 @@ See `org-rst-text-markup-alist' for details." (defun org-rst--checkbox (item _info) "Return checkbox string for ITEM or nil. INFO is a plist used as a communication channel." - ;(let ((utf8p (eq (plist-get info :ascii-charset) 'utf-8))) - ; (case (org-element-property :checkbox item) - ; (on (if utf8p "☑ " "[X] ")) - ; (off (if utf8p "☐ " "[ ] ")) - ; (trans (if utf8p "☒ " "[-] "))))) + ;; (let ((utf8p (eq (plist-get info :ascii-charset) 'utf-8))) + ;; (case (org-element-property :checkbox item) + ;; (on (if utf8p "☑ " "[X] ")) + ;; (off (if utf8p "☐ " "[ ] ")) + ;; (trans (if utf8p "☒ " "[-] "))))) (cl-case (org-element-property :checkbox item) - (on "☑ ") - (off "☐ ") - (trans "☒ "))) + (on "☑ ") + (off "☐ ") + (trans "☒ "))) @@ -594,47 +638,46 @@ INFO is a plist used as a communication channel." (defun org-rst-format-spec (info) "Return format specification for metadata. INFO is a plist used as a communication channel." - ;; (timestamp-format (plist-get info :html-metadata-timestamp-format)) ;; org-export-date-timestamp-format (let ((timestamp-format (plist-get info :rst-metadata-timestamp-format))) `((?t . ,(org-export-data (plist-get info :title) info)) (?s . ,(org-export-data (plist-get info :subtitle) info)) (?d . ,(org-export-data (org-export-get-date info timestamp-format) - info)) + info)) (?T . ,(format-time-string timestamp-format)) (?a . ,(org-export-data (plist-get info :author) info)) (?e . ,(mapconcat - (lambda (e) (format "%s" e e)) - (split-string (plist-get info :email) ",+ *") - ", ")) + (lambda (e) (format "%s" e e)) + (split-string (plist-get info :email) ",+ *") + ", ")) (?c . ,(plist-get info :creator)) (?C . ,(let ((file (plist-get info :input-file))) - (format-time-string timestamp-format - (and file (file-attribute-modification-time - (file-attributes file))))))))) + (format-time-string timestamp-format + (and file (file-attribute-modification-time + (file-attributes file))))))))) (defun org-rst-template--document-title (info) "Return document title, as a string. INFO is a plist used as a communication channel." (let* (;; Links in the title will not be resolved later, so we make - ;; sure their path is located right after them. + ;; sure their path is located right after them. (with-title (plist-get info :with-title)) - (title (if with-title + (title (if with-title (org-export-data (plist-get info :title) info) "")) - (subtitle (if with-title + (subtitle (if with-title (org-export-data (plist-get info :subtitle) info) "")) - (head (org-element-normalize-string (plist-get info :rst-head))) - (spec (org-rst-format-spec info)) - (metadata (plist-get info :rst-metadata)) - (author (and (plist-get info :with-author) - (let ((auth (plist-get info :author))) - (and auth (org-export-data auth info))))) - (email (and (plist-get info :with-email) - (org-export-data (plist-get info :email) info))) - (date (and (plist-get info :with-date) - (org-export-data (org-export-get-date info) info))) + (head (org-element-normalize-string (plist-get info :rst-head))) + (spec (org-rst-format-spec info)) + (metadata (plist-get info :rst-metadata)) + (author (and (plist-get info :with-author) + (let ((auth (plist-get info :author))) + (and auth (org-export-data auth info))))) + (email (and (plist-get info :with-email) + (org-export-data (plist-get info :email) info))) + (date (and (plist-get info :with-date) + (org-export-data (org-export-get-date info) info))) (titleline (make-string (string-width title) ?=)) (subtitleline (make-string (string-width subtitle) ?-)) (title (if (not (string= title "")) @@ -648,10 +691,10 @@ INFO is a plist used as a communication channel." (concat (when head (concat head "\n")) (unless (string= title "") - (concat - title - subtitle - "\n")) + (concat + title + subtitle + "\n")) (cond ((eq metadata 'auto) (org-element-normalize-string @@ -661,17 +704,17 @@ INFO is a plist used as a communication channel." (concat (format-spec (org-element-normalize-string org-rst-metadata-format) - spec))) + spec))) ((functionp metadata) (concat (format-spec (org-element-normalize-string (funcall metadata info)) - spec))) + spec))) ((stringp metadata) (concat (format-spec (org-element-normalize-string metadata) - spec))))))) + spec))))))) (defun org-rst-template (contents info) @@ -682,9 +725,9 @@ holding export options." ;; Build title block. (concat (org-rst-template--document-title info) "\n" - ;; 2. Table of contents. - (let ((depth (plist-get info :with-toc))) - (when depth ".. contents::\n\n"))) + ;; 2. Table of contents. + (let ((depth (plist-get info :with-toc))) + (when depth ".. contents::\n\n"))) ;; Document's body. contents ;; Creator. Justify it to the bottom right. @@ -722,13 +765,13 @@ holding contextual information." CONTENTS is nil. INFO is a plist holding contextual information." (concat org-clock-string " " - (org-timestamp-translate (org-element-property :value clock)) - (let ((time (org-element-property :duration clock))) - (and time - (concat " => " - (apply 'format - "%2s:%02s" - (org-split-string time ":"))))))) + (org-timestamp-translate (org-element-property :value clock)) + (let ((time (org-element-property :duration clock))) + (and time + (concat " => " + (apply 'format + "%2s:%02s" + (org-split-string time ":"))))))) ;;;; Code @@ -747,8 +790,8 @@ channel." CONTENTS holds the contents of the block. INFO is a plist holding contextual information." (funcall (plist-get info :rst-format-drawer-function) - (org-element-property :drawer-name drawer) - contents)) + (org-element-property :drawer-name drawer) + contents)) ;;;; Dynamic Block @@ -779,18 +822,18 @@ contextual information." CONTENTS is nil. INFO is a plist holding contextual information." (let* ((example (org-remove-indentation - (org-element-property :value example-block))) - (label (org-element-property :name example-block)) - (attributes - (org-export-read-attribute :attr_rst example-block)) - (class (plist-get attributes :class))) - (when example - (concat - "::\n" - (when class (format " :class: %s\n" class)) - (when label (format " :name: %s\n" label)) - "\n" - (org-rst--indent-string example org-rst-quote-margin))))) + (org-element-property :value example-block))) + (label (org-element-property :name example-block)) + (attributes + (org-export-read-attribute :attr_rst example-block)) + (class (plist-get attributes :class))) + (when example + (concat + "::\n" + (when class (format " :class: %s\n" class)) + (when label (format " :name: %s\n" label)) + "\n" + (org-rst--indent-string example org-rst-quote-margin))))) ;;;; Export Block @@ -798,7 +841,8 @@ information." (defun org-rst-export-block (export-block _contents _info) "Transcode a EXPORT-BLOCK element from Org to reStructuredText. CONTENTS is nil. INFO is a plist holding contextual information." - (when (member (org-element-property :type export-block) '("RST" "REST" "RESTRUCTUREDTEXT")) + (when (member (org-element-property :type export-block) + '("RST" "REST" "RESTRUCTUREDTEXT")) (org-element-property :value export-block))) @@ -813,13 +857,13 @@ CONTENTS is nil. INFO is a plist holding contextual information." ;;;; Footnote Definition -;(defun org-rst-footnote-definition (footnote-definition contents info) -; "Transcode a FOOTNOTE-DEFINITION element from Org to reStructuredText. -;CONTENTS is nil. INFO is a plist holding contextual information." -; (replace-regexp-in-string -; "^" ".. " -; (org-remove-indentation -; (org-element-property :value footnote-definition)))) +;; (defun org-rst-footnote-definition (footnote-definition contents info) +;; "Transcode a FOOTNOTE-DEFINITION element from Org to reStructuredText. +;; CONTENTS is nil. INFO is a plist holding contextual information." +;; (replace-regexp-in-string +;; "^" ".. " +;; (org-remove-indentation +;; (org-element-property :value footnote-definition)))) ;;;; Footnote Reference @@ -881,30 +925,30 @@ contextual information." CONTENTS holds the contents of the block. INFO is a plist holding contextual information." (let ((title (org-export-data (org-element-property :title inlinetask) info)) - (todo (and (plist-get info :with-todo-keywords) - (let ((todo (org-element-property :todo-keyword inlinetask))) - (and todo (org-export-data todo info))))) - (todo-type (org-element-property :todo-type inlinetask)) - (tags (and (plist-get info :with-tags) - (org-export-get-tags inlinetask info))) - (priority (and (plist-get info :with-priority) - (org-element-property :priority inlinetask)))) + (todo (and (plist-get info :with-todo-keywords) + (let ((todo (org-element-property :todo-keyword inlinetask))) + (and todo (org-export-data todo info))))) + (todo-type (org-element-property :todo-type inlinetask)) + (tags (and (plist-get info :with-tags) + (org-export-get-tags inlinetask info))) + (priority (and (plist-get info :with-priority) + (org-element-property :priority inlinetask)))) ;; If `org-rst-format-inlinetask-function' is provided, call it ;; with appropriate arguments. (if (functionp org-rst-format-inlinetask-function) - (funcall org-rst-format-inlinetask-function - todo todo-type priority title tags contents) + (funcall org-rst-format-inlinetask-function + todo todo-type priority title tags contents) ;; Otherwise, use a default template. - (let ((full-title - (concat - (when todo (format "%s" todo)) - (when priority (format "\#%c " priority)) - title - (when tags (format ":%s:" - (mapconcat 'identity tags ":")))))) - (format (concat "%s\n\n" - "%s\n") - full-title contents))))) + (let ((full-title + (concat + (when todo (format "%s" todo)) + (when priority (format "\#%c " priority)) + title + (when tags (format ":%s:" + (mapconcat 'identity tags ":")))))) + (format (concat "%s\n\n" + "%s\n") + full-title contents))))) ;;;; Inner template @@ -915,26 +959,26 @@ CONTENTS is the transcoded contents string. INFO is a plist holding export options." (org-element-normalize-string (concat - ;; 1. Document's body. - contents - ;; 2. Footnote definitions. - (let ((definitions (org-export-collect-footnote-definitions info))) - (when definitions - (concat - "\n\n" - (mapconcat - (lambda (ref) - (let* ((id (format ".. [%s] " (car ref))) + ;; 1. Document's body. + contents + ;; 2. Footnote definitions. + (let ((definitions (org-export-collect-footnote-definitions info))) + (when definitions + (concat + "\n\n" + (mapconcat + (lambda (ref) + (let* ((id (format ".. [%s] " (car ref))) (def (nth 2 ref)) (lines (split-string (org-export-data def info) "\n+[ \t\n]*")) (fntext (concat (car lines) "\n" (apply 'concat (mapcar #'(lambda (x) (if (> (length x) 0) - (concat (org-rst--indent-string x org-rst-quote-margin) "\n"))) - (cdr lines))))) + (concat (org-rst--indent-string x org-rst-quote-margin) "\n"))) + (cdr lines))))) ) - (concat id fntext))) - definitions "\n"))))))) + (concat id fntext))) + definitions "\n"))))))) ;;;; Italic @@ -953,38 +997,38 @@ contextual information." CONTENTS is the item contents. INFO is a plist used as a communication channel." (let* ((checkbox (org-rst--checkbox item info)) - (list-type (org-element-property :type (org-element-parent item))) - (tag (let - ((tag (org-element-property :tag item))) - (and tag (concat (org-export-data tag info) checkbox)))) - (bullet - ;; First parent of ITEM is always the plain-list. Get - ;; `:type' property from it. - (org-list-bullet-string - (cond - ((eq list-type 'ordered) - ;; Return correct number for ITEM, paying attention to - ;; counters. - (let* ((struct (org-element-property :structure item)) - (bul (org-element-property :bullet item)) - (num (number-to-string - (car (last (org-list-get-item-number - (org-element-begin item) - struct - (org-list-prevs-alist struct) - (org-list-parents-alist struct))))))) - (replace-regexp-in-string "[0-9]+" num bul))) - (tag "") - (t "-")))) - (width (if tag 4 (string-width bullet))) - ) + (list-type (org-element-property :type (org-element-parent item))) + (tag (let + ((tag (org-element-property :tag item))) + (and tag (concat (org-export-data tag info) checkbox)))) + (bullet + ;; First parent of ITEM is always the plain-list. Get + ;; `:type' property from it. + (org-list-bullet-string + (cond + ((eq list-type 'ordered) + ;; Return correct number for ITEM, paying attention to + ;; counters. + (let* ((struct (org-element-property :structure item)) + (bul (org-element-property :bullet item)) + (num (number-to-string + (car (last (org-list-get-item-number + (org-element-begin item) + struct + (org-list-prevs-alist struct) + (org-list-parents-alist struct))))))) + (replace-regexp-in-string "[0-9]+" num bul))) + (tag "") + (t "-")))) + (width (if tag 4 (string-width bullet))) + ) (concat (if tag tag (concat bullet checkbox)) (let ((contents (org-rst--indent-string contents width))) (if (and (not tag) - (org-element-type-p (car (org-element-contents item)) 'paragraph)) - (org-trim contents) - (concat "\n" contents)))))) + (org-element-type-p (car (org-element-contents item)) 'paragraph)) + (org-trim contents) + (concat "\n" contents)))))) ;;;; Keyword @@ -993,7 +1037,7 @@ a communication channel." "Transcode a KEYWORD element from Org to reStructuredText. CONTENTS is nil. INFO is a plist holding contextual information." (let ((key (org-element-property :key keyword)) - (value (org-element-property :value keyword))) + (value (org-element-property :value keyword))) (cond ((string= key "RST") value)))) @@ -1010,27 +1054,26 @@ When NAMED-ONLY is non-nil and DATUM has no NAME keyword, return nil. This doesn't apply to headlines, inline tasks, radio targets and targets." (let* ((type (org-element-type datum)) - (custom-id (and (memq type '(headline inlinetask)) - (org-element-property :CUSTOM_ID datum))) - (user-label - (or - custom-id - (and (memq type '(radio-target target)) - (org-element-property :value datum)) - (org-element-property :name datum) - (when-let* ((id (org-element-property :ID datum))) - (concat org-html--id-attr-prefix id))))) + (custom-id (and (memq type '(headline inlinetask)) + (org-element-property :CUSTOM_ID datum))) + (user-label + (or + custom-id + (and (memq type '(radio-target target)) + (org-element-property :value datum)) + (org-element-property :name datum) + (when-let* ((id (org-element-property :ID datum))) + (concat org-rst--id-attr-prefix id))))) (cond ((and user-label - (or ;; (plist-get info :html-prefer-user-labels) - nil - ;; Used CUSTOM_ID property unconditionally. - custom-id)) + (or (plist-get info :rst-prefer-user-labels) + ;; Used CUSTOM_ID property unconditionally. + custom-id)) user-label) ((and named-only - (not (memq type '(headline inlinetask radio-target target))) - (not user-label)) + (not (memq type '(headline inlinetask radio-target target))) + (not user-label)) nil) (t (org-export-get-reference datum info))))) @@ -1044,17 +1087,17 @@ caption and \"id\" attribute." (if (org-string-nw-p label) (format " :label: %s\n" label) "") ;; Caption. (if (not (org-string-nw-p caption)) "" - (format " :label:%s\n" caption)) + (format " :label: %s\n :nowrap:\n" caption)) ;; todo: flag for nowrap? ;; Contents. (format "\n%s\n" (org-rst--indent-string - (org-trim contents) org-rst-quote-margin)))) + (org-trim contents) org-rst-quote-margin)))) (defun org-rst--math-environment-p (element &optional _) "Non-nil when ELEMENT is a LaTeX math environment. Math environments match the regular expression defined in `org-latex-math-environments-re'. This function is meant to be used as a predicate for `org-export-get-ordinal' or a value to -`org-html-standalone-image-predicate'." +`org-rst-standalone-image-predicate'." (string-match-p org-latex-math-environments-re (org-element-property :value element))) @@ -1062,24 +1105,24 @@ used as a predicate for `org-export-get-ordinal' or a value to "Non-nil when ELEMENT is a numbered LaTeX math environment. Starred and \"displaymath\" environments are not numbered." (not (string-match-p "\\`[ \t]*\\\\begin{\\(.*\\*\\|displaymath\\)}" - (org-element-property :value element)))) + (org-element-property :value element)))) (defun org-rst-latex-environment (latex-environment _contents info) "Transcode a LATEX-ENVIRONMENT element from Org to reStructuredText. CONTENTS is nil. INFO is a plist holding contextual information." - (let ((processing-type (plist-get info :with-latex)) + (let ((processing-type t) ;; (plist-get info :with-latex) (latex-frag (org-remove-indentation - (org-element-property :value latex-environment))) + (org-element-property :value latex-environment))) (label (org-rst--reference latex-environment info t)) (caption (and (org-rst--latex-environment-numbered-p latex-environment) (org-rst--math-environment-p latex-environment) - (number-to-string - (org-export-get-ordinal - latex-environment info nil - (lambda (l _) - (and (org-html--math-environment-p l) - (org-html--latex-environment-numbered-p l)))))))) + (number-to-string + (org-export-get-ordinal + latex-environment info nil + (lambda (l _) + (and (org-rst--math-environment-p l) + (org-rst--latex-environment-numbered-p l)))))))) (when processing-type ;; latex-frag (org-rst--wrap-latex-environment latex-frag info caption label)))) @@ -1131,15 +1174,15 @@ if its description is a single link targeting an image file." (not (let ((link-count 0)) (org-element-map (org-element-contents link) - (cons 'plain-text org-element-all-objects) - (lambda (obj) - (cl-case (org-element-type obj) - (plain-text (org-string-nw-p obj)) - (link (if (= link-count 1) t - (cl-incf link-count) - (not (org-export-inline-image-p - obj (plist-get info :rst-inline-image-rules))))) - (otherwise t))) + (cons 'plain-text org-element-all-objects) + (lambda (obj) + (cl-case (org-element-type obj) + (plain-text (org-string-nw-p obj)) + (link (if (= link-count 1) t + (cl-incf link-count) + (not (org-export-inline-image-p + obj (plist-get info :rst-inline-image-rules))))) + (otherwise t))) info t))))) @@ -1150,7 +1193,7 @@ if its description is a single link targeting an image file." (mapc (lambda (rule) (if (string-match (cdr rule) link) - (throw 'exit t))) + (throw 'exit t))) rules) ;; Return nil if no rule matched. nil))) @@ -1162,57 +1205,57 @@ if its description is a single link targeting an image file." DESC is the description part of the link, or the empty string. INFO is a plist holding contextual information." (let* ((home (when (plist-get info :rst-link-home) - (org-trim (plist-get info :rst-link-home)))) - (use-abs-url (plist-get info :rst-link-use-abs-url)) - (link-org-files-as-rst-maybe - (function - (lambda (raw-path info) - "Treat links to `file.org' as links to `file.rst', if needed. - See `org-rst-link-org-files-as-rst'." - (cond - ((and (plist-get info :rst-link-org-files-as-rst) - (string= ".org" - (downcase (file-name-extension raw-path ".")))) - (concat (file-name-sans-extension raw-path) "." - (plist-get info :rst-extension))) - (t raw-path))))) - (type (org-element-property :type link)) - (search-option (org-element-property :search-option link)) - (raw-path (org-element-property :path link)) - ;; Ensure DESC really exists, or set it to nil. - (desc (and (not (string= desc "")) desc)) - (path (cond - ((string= type "file") - ;; Treat links to ".org" files as ".rst", if needed. - (setq raw-path - (funcall link-org-files-as-rst-maybe raw-path info)) - (cond ((and home use-abs-url) - (setq raw-path - (concat (file-name-as-directory home) raw-path))) + (org-trim (plist-get info :rst-link-home)))) + (use-abs-url (plist-get info :rst-link-use-abs-url)) + (link-org-files-as-rst-maybe + (function + (lambda (raw-path info) + ;; Treat links to `file.org' as links to `file.rst', if + ;; needed. See `org-rst-link-org-files-as-rst'. + (cond + ((and (plist-get info :rst-link-org-files-as-rst) + (string= ".org" + (downcase (file-name-extension raw-path ".")))) + (concat (file-name-sans-extension raw-path) "." + (plist-get info :rst-extension))) + (t raw-path))))) + (type (org-element-property :type link)) + (search-option (org-element-property :search-option link)) + (raw-path (org-element-property :path link)) + ;; Ensure DESC really exists, or set it to nil. + (desc (and (not (string= desc "")) desc)) + (path (cond + ((string= type "file") + ;; Treat links to ".org" files as ".rst", if needed. + (setq raw-path + (funcall link-org-files-as-rst-maybe raw-path info)) + (cond ((and home use-abs-url) + (setq raw-path + (concat (file-name-as-directory home) raw-path))) (t raw-path))) - (t (concat type ":" raw-path)))) - (attributes-plist - (org-combine-plists - ;; Extract attributes from parent's paragraph. HACK: Only - ;; do this for the first link in parent (inner image link - ;; for inline images). This is needed as long as - ;; attributes cannot be set on a per link basis. - (let* ((parent (org-element-parent-element link)) - (link (let ((container (org-element-parent link))) - (if (and (org-element-type-p container 'link) - (org-rst-inline-image-p link info)) - container - link)))) - (and (eq link (org-element-map parent 'link #'identity info t)) - (org-export-read-attribute :attr_rst parent))) - ;; Also add attributes from link itself. Currently, those - ;; need to be added programmatically before `org-rst-link' - ;; is invoked, for example, by backends building upon HTML - ;; export. - (org-export-read-attribute :attr_rst link))) - (attributes - (let ((attr (org-rst--make-attribute-string attributes-plist))) - (if (org-string-nw-p attr) (concat "\n" attr "\n") "")))) + (t (concat type ":" raw-path)))) + (attributes-plist + (org-combine-plists + ;; Extract attributes from parent's paragraph. HACK: Only + ;; do this for the first link in parent (inner image link + ;; for inline images). This is needed as long as + ;; attributes cannot be set on a per link basis. + (let* ((parent (org-element-parent-element link)) + (link (let ((container (org-element-parent link))) + (if (and (org-element-type-p container 'link) + (org-rst-inline-image-p link info)) + container + link)))) + (and (eq link (org-element-map parent 'link #'identity info t)) + (org-export-read-attribute :attr_rst parent))) + ;; Also add attributes from link itself. Currently, those + ;; need to be added programmatically before `org-rst-link' + ;; is invoked, for example, by backends building upon HTML + ;; export. + (org-export-read-attribute :attr_rst link))) + (attributes + (let ((attr (org-rst--make-attribute-string attributes-plist))) + (if (org-string-nw-p attr) (concat "\n" attr "\n") "")))) (cond ;; Link type is handled by a special function. ((org-export-custom-protocol-maybe link desc 'rst info)) @@ -1220,17 +1263,17 @@ INFO is a plist holding contextual information." ((and (plist-get info :rst-inline-images) (org-export-inline-image-p link (plist-get info :rst-inline-image-rules))) - (let* ((ipath (if (not (file-name-absolute-p raw-path)) raw-path - (expand-file-name raw-path))) + (let* ((ipath (if (not (file-name-absolute-p raw-path)) raw-path + (expand-file-name raw-path))) (caption (org-export-get-caption - (org-element-parent-element link))) + (org-element-parent-element link))) (linkname (org-element-property :name (org-element-parent-element link))) (label (if linkname (format ".. _%s:\n\n" linkname) ""))) - (if caption (format "%s.. figure:: %s%s\n\n %s\n" + (if caption (format "%s.. figure:: %s%s\n\n %s\n" label ipath attributes - (org-export-data caption info)) - (format "%s.. image:: %s%s\n" label ipath attributes)))) + (org-export-data caption info)) + (format "%s.. image:: %s%s\n" label ipath attributes)))) ((and (plist-get info :rst-inline-images) desc (my-org-export-inline-image-p @@ -1240,45 +1283,53 @@ INFO is a plist holding contextual information." ;; description. ((string= type "radio") (let ((destination (org-export-resolve-radio-link link info))) - (when destination - (format "`%s <%s>`_" - path - (org-export-data (org-element-contents destination) info))))) + (when destination + (format "`%s <%s>`_" + path + (org-export-data (org-element-contents destination) info))))) ;; Links pointing to a headline: Find destination and build ;; appropriate referencing command. ((member type '("custom-id" "fuzzy" "id")) (let ((destination (if (string= type "fuzzy") - (org-export-resolve-fuzzy-link link info) - (org-export-resolve-id-link link info)))) - (cl-case (org-element-type destination) - ;; Id link points to an external file. - (plain-text - (if desc (format "`%s <%s>`_" desc destination) - (format "`%s`_" destination))) - ;; Fuzzy link points nowhere. - ;; ('nil - ;; (let ((rawlink - ;; (org-export-data (org-element-property :raw-link link) info))) - ;; (if desc (format "`%s <%s>`_" desc rawlink) - ;; (format "`%s`_" rawlink)))) - ;; LINK points to a headline. - (headline - (if (member type '("custom-id" "id")) - (if (plist-get info :rst-link-use-ref-role) - (if desc (format " :ref:`%s <%s>`" desc raw-path) - (format " :ref:`%s`" raw-path)) - (if desc (format "`<%s>`_" raw-path) ;; desc cannot be used w/o a :role: - (format "`%s`_" raw-path))) - (format "`%s`_" (org-rst--build-title destination info nil)))) + (org-export-resolve-fuzzy-link link info) + (org-export-resolve-id-link link info)))) + (cl-case (org-element-type destination) + ;; Id link points to an external file. + (plain-text + (if desc (format "`%s <%s>`_" desc destination) + (format "`%s`_" destination))) + ;; Fuzzy link points nowhere. + ;; ('nil + ;; (let ((rawlink + ;; (org-export-data (org-element-property :raw-link link) info))) + ;; (if desc (format "`%s <%s>`_" desc rawlink) + ;; (format "`%s`_" rawlink)))) + ;; LINK points to a headline. + (headline + (if (member type '("custom-id" "id")) + (if (plist-get info :rst-link-use-ref-role) + (if desc (format " :ref:`%s <%s>`" desc raw-path) + (format " :ref:`%s`" raw-path)) + (if desc (format "`<%s>`_" raw-path) ;; desc cannot be used w/o a :role: + (format "`%s`_" raw-path))) + (format "`%s`_" (org-rst--build-title destination info nil)))) ;; Fuzzy link points to a target. - (otherwise - (if (not desc) (format "`%s`_" raw-path) - (format "`%s <%s>`_" desc raw-path)))))) + (otherwise + (if (and destination + (org-element-type-p destination 'latex-environment) + (eq 'math (org-latex--environment-type destination))) + ;; Caption and labels are introduced within LaTeX + ;; environment. Use "ref" or "eqref" macro, depending on user + ;; preference to refer to those in the document. + (format (plist-get info :rst-equation-reference-format) + (org-rst--reference destination info)) + (if (not desc) (format "`%s`_" raw-path) + (format "`%s <%s>`_" desc raw-path))))))) ;; Coderef: replace link with the reference name or the ;; equivalent line number. It is not supported in ReST. ((string= type "coderef") (format (org-export-get-coderef-format path desc) - (org-export-resolve-coderef path info))) + (org-export-resolve-coderef path info))) ((and (plist-get info :rst-file-link-use-ref-role) (string= type "file") search-option) @@ -1287,8 +1338,8 @@ INFO is a plist holding contextual information." (format ":ref:`%s <%s>`" desc ref) (format ":ref:`%s`" ref)))) ;; 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)) + ;; ((functionp (setq protocol (nth 2 (assoc type org-link-protocols)))) + ;; (funcall protocol (org-link-unescape path) desc 'latex)) ;; External link with a description part. ((and path desc) (format "`%s <%s>`_" desc path)) ;; External link without a description part. @@ -1361,18 +1412,18 @@ channel." (mapconcat 'identity (delq nil - (list (let ((closed (org-element-property :closed planning))) - (when closed - (concat org-closed-string " " - (org-timestamp-translate closed)))) - (let ((deadline (org-element-property :deadline planning))) - (when deadline - (concat org-deadline-string " " - (org-timestamp-translate deadline)))) - (let ((scheduled (org-element-property :scheduled planning))) - (when scheduled - (concat org-scheduled-string " " - (org-timestamp-translate scheduled)))))) + (list (let ((closed (org-element-property :closed planning))) + (when closed + (concat org-closed-string " " + (org-timestamp-translate closed)))) + (let ((deadline (org-element-property :deadline planning))) + (when deadline + (concat org-deadline-string " " + (org-timestamp-translate deadline)))) + (let ((scheduled (org-element-property :scheduled planning))) + (when scheduled + (concat org-scheduled-string " " + (org-timestamp-translate scheduled)))))) " ")) @@ -1383,9 +1434,9 @@ channel." CONTENTS holds the contents of the drawer. INFO is a plist holding contextual information." (when (org-string-nw-p contents) - (concat - "::\n\n" - (org-rst--indent-string contents org-rst-quote-margin)))) + (concat + "::\n\n" + (org-rst--indent-string contents org-rst-quote-margin)))) ;;;; Pseudo Object: LaTeX Math Block @@ -1449,7 +1500,7 @@ containing export options. Modify DATA by side-effect and return it." (defun org-rst-math-block-options-filter (info _backend) (dolist (prop '(:author :date :title) info) (plist-put info prop - (org-rst--wrap-latex-math-block (plist-get info prop) info)))) + (org-rst--wrap-latex-math-block (plist-get info prop) info)))) (defun org-rst-math-block (_math-block contents _info) "Transcode a MATH-BLOCK object from Org to reStructuredText. @@ -1471,36 +1522,36 @@ channel." CONTENTS holds the contents of the block. INFO is a plist holding contextual information." (let* ((attributes - (org-export-read-attribute :attr_rst quote-block)) - (directive (plist-get attributes :directive)) - (title (plist-get attributes :title)) - (subtitle (plist-get attributes :subtitle)) - (margin (plist-get attributes :margin)) - (class (plist-get attributes :class)) - (label (org-element-property :name quote-block))) - (cond ((and margin contents) - (org-rst--indent-string contents (string-to-number margin))) - (directive - (concat - (format ".. %s::" directive) - (when title (format " %s" title)) - "\n" - (when (and subtitle (string= "sidebar" directive)) - (format " :subtitle: %s\n" subtitle)) - (when (and class (not (string= "container" directive))) - (format " :class: %s\n" class)) - (when label (format " :name: %s\n" label)) - "\n" - (when contents - (org-rst--indent-string contents org-rst-quote-margin)))) - (t - (concat - "::\n" - (when class (format " :class: %s\n" class)) - (when label (format " :name: %s\n" label)) - "\n" - (when contents - (org-rst--indent-string contents org-rst-quote-margin))))))) + (org-export-read-attribute :attr_rst quote-block)) + (directive (plist-get attributes :directive)) + (title (plist-get attributes :title)) + (subtitle (plist-get attributes :subtitle)) + (margin (plist-get attributes :margin)) + (class (plist-get attributes :class)) + (label (org-element-property :name quote-block))) + (cond ((and margin contents) + (org-rst--indent-string contents (string-to-number margin))) + (directive + (concat + (format ".. %s::" directive) + (when title (format " %s" title)) + "\n" + (when (and subtitle (string= "sidebar" directive)) + (format " :subtitle: %s\n" subtitle)) + (when (and class (not (string= "container" directive))) + (format " :class: %s\n" class)) + (when label (format " :name: %s\n" label)) + "\n" + (when contents + (org-rst--indent-string contents org-rst-quote-margin)))) + (t + (concat + "::\n" + (when class (format " :class: %s\n" class)) + (when label (format " :name: %s\n" label)) + "\n" + (when contents + (org-rst--indent-string contents org-rst-quote-margin))))))) ;;;; Radio Target @@ -1529,11 +1580,11 @@ CONTENTS holds the contents of the block. INFO is a plist holding contextual information." (let* ((attributes (org-export-read-attribute :attr_rst special-block)) - (title (plist-get attributes :title)) + (title (plist-get attributes :title)) (class (plist-get attributes :class)) - (label (org-element-property :name special-block)) + (label (org-element-property :name special-block)) (type (org-element-property :type special-block)) - (attr-str-ignore '(:title)) + (attr-str-ignore '(:title)) (attr-str "")) ;; combine with `org-rst--make-attribute-string'? (cl-loop for (key value) on attributes by 'cddr @@ -1563,40 +1614,40 @@ contextual information." ;; code-block (or the alias sourcecode) are for a separate block (when (org-string-nw-p (org-element-property :value src-block)) (let* ((lang (org-element-property :language src-block)) - (caption (org-export-get-caption src-block)) - (label (org-element-property :name src-block)) - (value (org-remove-indentation - (org-element-property :value src-block))) + (caption (org-export-get-caption src-block)) + (label (org-element-property :name src-block)) + (value (org-remove-indentation + (org-element-property :value src-block))) (num-start (org-export-get-loc src-block info)) (codeblockd (plist-get info :rst-code-block)) - (attributes - (org-export-read-attribute :attr_rst src-block)) - (class (plist-get attributes :class))) + (attributes + (org-export-read-attribute :attr_rst src-block)) + (class (plist-get attributes :class))) (cond ;; Case 1. code-block directive. ((eq codeblockd 'code-block) - (let ((lst-lang - (or (cadr (assq (intern lang) org-rst-pygments-langs)) lang))) - (concat - (format ".. code-block:: %s\n" lst-lang) - (when num-start (format " :lineno-start: %s\n" (1+ num-start))) - (when class (format " :class: %s\n" class)) - (when label (format " :name: %s\n" label)) - (when caption (format " :caption: %s\n" (org-export-data caption info))) - "\n" - (org-rst--indent-string value org-rst-quote-margin)))) - ;; Case 2. code directive. - ((eq codeblockd 'code) - (let ((lst-lang - (or (cadr (assq (intern lang) org-rst-pygments-langs)) lang))) - (concat - (format ".. code:: %s\n" lst-lang) - (when num-start (format " :number-lines: %s\n" (1+ num-start))) - (when class (format " :class: %s\n" class)) - (when label (format " :name: %s\n" label)) - "\n" - (org-rst--indent-string value org-rst-quote-margin)))) - ;; Case 3. literal block. + (let ((lst-lang + (or (cadr (assq (intern lang) org-rst-pygments-langs)) lang))) + (concat + (format ".. code-block:: %s\n" lst-lang) + (when num-start (format " :lineno-start: %s\n" (1+ num-start))) + (when class (format " :class: %s\n" class)) + (when label (format " :name: %s\n" label)) + (when caption (format " :caption: %s\n" (org-export-data caption info))) + "\n" + (org-rst--indent-string value org-rst-quote-margin)))) + ;; Case 2. code directive. + ((eq codeblockd 'code) + (let ((lst-lang + (or (cadr (assq (intern lang) org-rst-pygments-langs)) lang))) + (concat + (format ".. code:: %s\n" lst-lang) + (when num-start (format " :number-lines: %s\n" (1+ num-start))) + (when class (format " :class: %s\n" class)) + (when label (format " :name: %s\n" label)) + "\n" + (org-rst--indent-string value org-rst-quote-margin)))) + ;; Case 3. literal block. (t (concat "::\n" @@ -1660,17 +1711,17 @@ INFO is a plist used as a communication channel." CONTENTS is the contents of the table. INFO is a plist holding contextual information." (let* ((caption (org-export-get-caption table)) - (attributes - (org-export-read-attribute :attr_rst table)) - (class (plist-get attributes :class)) - (label (org-element-property :name table))) + (attributes + (org-export-read-attribute :attr_rst table)) + (class (plist-get attributes :class)) + (label (org-element-property :name table))) (concat (if caption (format ".. table:: %s\n" (org-export-data caption info)) - ".. table::\n") - (when class (format " :class: %s\n" class)) - (when label (format " :name: %s\n" label)) - "\n" - (org-rst--indent-string contents org-rst-quote-margin)))) + ".. table::\n") + (when class (format " :class: %s\n" class)) + (when label (format " :name: %s\n" label)) + "\n" + (org-rst--indent-string contents org-rst-quote-margin)))) ;;;; Table Cell @@ -1684,37 +1735,37 @@ Width of a cell is determined either by a width cookie in the same column as the cell, or by the maximum cell's length in that column." (let* ((row (org-element-parent table-cell)) - (table (org-element-parent row)) - (col (let ((cells (org-element-contents row))) - (- (length cells) (length (memq table-cell cells))))) - (cache - (or (plist-get info :rst-table-cell-width-cache) - (plist-get (setq info - (plist-put info :rst-table-cell-width-cache - (make-hash-table :test 'equal))) - :rst-table-cell-width-cache))) - (key (cons table col))) + (table (org-element-parent row)) + (col (let ((cells (org-element-contents row))) + (- (length cells) (length (memq table-cell cells))))) + (cache + (or (plist-get info :rst-table-cell-width-cache) + (plist-get (setq info + (plist-put info :rst-table-cell-width-cache + (make-hash-table :test 'equal))) + :rst-table-cell-width-cache))) + (key (cons table col))) (or (gethash key cache) - (puthash - key - (let ((cookie-width (org-export-table-cell-width table-cell info))) - (or cookie-width - (let ((contents-width - (let ((max-width 0)) - (org-element-map table 'table-row - (lambda (row) - (setq max-width - (max (string-width - (org-export-data - (org-element-contents - (elt (org-element-contents row) col)) - info)) - max-width))) - info) - max-width))) - (cond ((not cookie-width) contents-width) - (t cookie-width))))) - cache)))) + (puthash + key + (let ((cookie-width (org-export-table-cell-width table-cell info))) + (or cookie-width + (let ((contents-width + (let ((max-width 0)) + (org-element-map table 'table-row + (lambda (row) + (setq max-width + (max (string-width + (org-export-data + (org-element-contents + (elt (org-element-contents row) col)) + info)) + max-width))) + info) + max-width))) + (cond ((not cookie-width) contents-width) + (t cookie-width))))) + cache)))) (defun org-rst-table-cell (table-cell contents info) @@ -1724,17 +1775,17 @@ a communication channel." (let ((width (org-rst--table-cell-width table-cell info))) ;; Align contents correctly within the cell. (let* ((indent-tabs-mode nil) - (data - (if contents - (org-rst--justify-lines - contents width - (org-export-table-cell-alignment table-cell info)) "\\"))) + (data + (if contents + (org-rst--justify-lines + contents width + (org-export-table-cell-alignment table-cell info)) "\\"))) (setq contents (concat data (make-string (max 0 (- width (string-width data))) ? )))) ;; Return cell. (concat (format " %s " contents) - (when (org-export-get-next-element table-cell info) "|")))) + (when (org-export-get-next-element table-cell info) "|")))) ;;;; Table Row @@ -1773,7 +1824,7 @@ a communication channel." (make-string (string-width table-cell) linebit)) (split-string contents "|")) - "+"))))) + "+"))))) (hline (format "+%s+" (mapconcat 'identity @@ -1874,11 +1925,11 @@ Assume BACKEND is `rst'." (org-element-map tree org-element-all-elements (lambda (elem) (unless (or (org-element-type-p elem 'org-data) - (org-element-type-p elem 'table-row)) - (org-element-put-property - elem :post-blank - (let ((post-blank (org-element-property :post-blank elem))) - (if (not post-blank) 1 (max 1 post-blank))))))) + (org-element-type-p elem 'table-row)) + (org-element-put-property + elem :post-blank + (let ((post-blank (org-element-property :post-blank elem))) + (if (not post-blank) 1 (max 1 post-blank))))))) ;; Return updated tree. tree) @@ -1906,10 +1957,10 @@ See `org-rst-paragraph-spacing' for information." (when (wholenump org-rst-paragraph-spacing) (org-element-map tree 'paragraph (lambda (p) - (when (org-element-type-p (org-export-get-next-element p info) - 'paragraph) - (org-element-put-property - p :post-blank org-rst-paragraph-spacing))))) + (when (org-element-type-p (org-export-get-next-element p info) + 'paragraph) + (org-element-put-property + p :post-blank org-rst-paragraph-spacing))))) tree)