ox-ascii: Fix descriptive lists

* lisp/ox-ascii.el (org-ascii-quote-margin): Update docstring.
(org-ascii--current-text-width): Properly handle width of text within
nested plain-list items.
(org-ascii-item): Always start a new line for description contents.
Indent them by `org-ascii-quote-margin' characters.
This commit is contained in:
Nicolas Goaziou 2017-11-06 14:27:45 +01:00
parent 271e58f2dd
commit 7000ed9ee0
1 changed files with 93 additions and 97 deletions

View File

@ -177,7 +177,8 @@ Inner margin is applied between each headline."
(defcustom org-ascii-quote-margin 6 (defcustom org-ascii-quote-margin 6
"Width of margin used for quoting text, in characters. "Width of margin used for quoting text, in characters.
This margin is applied on both sides of the text." This margin is applied on both sides of the text. It is also
applied on the left side of contents in descriptive lists."
:group 'org-export-ascii :group 'org-export-ascii
:version "24.4" :version "24.4"
:package-version '(Org . "8.0") :package-version '(Org . "8.0")
@ -551,79 +552,69 @@ INFO is a plist used as a communication channel."
(`inlinetask (plist-get info :ascii-inlinetask-width)) (`inlinetask (plist-get info :ascii-inlinetask-width))
(`headline (`headline
(- (plist-get info :ascii-text-width) (- (plist-get info :ascii-text-width)
(let ((low-level-rank (org-export-low-level-p element info))) (let ((low-level-rank (org-export-low-level-p element info)))
(if low-level-rank (* low-level-rank 2) (if low-level-rank (* low-level-rank 2)
(plist-get info :ascii-global-margin))))) (plist-get info :ascii-global-margin)))))
;; Elements with a relative width: store maximum text width in ;; Elements with a relative width: store maximum text width in
;; TOTAL-WIDTH. ;; TOTAL-WIDTH.
(_ (_
(let* ((genealogy (org-element-lineage element nil t)) (let* ((genealogy (org-element-lineage element nil t))
;; Total width is determined by the presence, or not, of an ;; Total width is determined by the presence, or not, of an
;; inline task among ELEMENT parents. ;; inline task among ELEMENT parents.
(total-width (total-width
(if (cl-some (lambda (parent) (if (cl-some (lambda (parent)
(eq (org-element-type parent) 'inlinetask)) (eq (org-element-type parent) 'inlinetask))
genealogy) genealogy)
(plist-get info :ascii-inlinetask-width) (plist-get info :ascii-inlinetask-width)
;; No inlinetask: Remove global margin from text width. ;; No inlinetask: Remove global margin from text width.
(- (plist-get info :ascii-text-width) (- (plist-get info :ascii-text-width)
(plist-get info :ascii-global-margin) (plist-get info :ascii-global-margin)
(let ((parent (org-export-get-parent-headline element))) (let ((parent (org-export-get-parent-headline element)))
;; Inner margin doesn't apply to text before first ;; Inner margin doesn't apply to text before first
;; headline. ;; headline.
(if (not parent) 0 (if (not parent) 0
(let ((low-level-rank (let ((low-level-rank
(org-export-low-level-p parent info))) (org-export-low-level-p parent info)))
;; Inner margin doesn't apply to contents of ;; Inner margin doesn't apply to contents of
;; low level headlines, since they've got their ;; low level headlines, since they've got their
;; own indentation mechanism. ;; own indentation mechanism.
(if low-level-rank (* low-level-rank 2) (if low-level-rank (* low-level-rank 2)
(plist-get info :ascii-inner-margin))))))))) (plist-get info :ascii-inner-margin)))))))))
(- total-width (- total-width
;; Each `quote-block' and `verse-block' above narrows text ;; Each `quote-block' and `verse-block' above narrows text
;; width by twice the standard margin size. ;; width by twice the standard margin size.
(+ (* (cl-count-if (lambda (parent) (+ (* (cl-count-if (lambda (parent)
(memq (org-element-type parent) (memq (org-element-type parent)
'(quote-block verse-block))) '(quote-block verse-block)))
genealogy) genealogy)
2 2
(plist-get info :ascii-quote-margin)) (plist-get info :ascii-quote-margin))
;; Apply list margin once per "top-level" plain-list ;; Apply list margin once per "top-level" plain-list
;; containing current line ;; containing current line
(* (cl-count-if (* (cl-count-if
(lambda (e) (lambda (e)
(and (eq (org-element-type e) 'plain-list) (and (eq (org-element-type e) 'plain-list)
(not (eq (org-element-type (org-export-get-parent e)) (not (eq (org-element-type (org-export-get-parent e))
'item)))) 'item))))
genealogy) genealogy)
(plist-get info :ascii-list-margin)) (plist-get info :ascii-list-margin))
;; Text width within a plain-list is restricted by ;; Compute indentation offset due to current list. It is
;; indentation of current item. If that's the case, ;; `org-ascii-quote-margin' per descriptive item in the
;; compute it with the help of `:structure' property from ;; genealogy, bullet's length otherwise.
;; parent item, if any. (let ((indentation 0))
(let ((item (dolist (e genealogy)
(if (eq (org-element-type element) 'item) element (cond
(cl-find-if (lambda (parent) ((not (eq 'item (org-element-type e))))
(eq (org-element-type parent) 'item)) ((eq (org-element-property :type (org-export-get-parent e))
genealogy)))) 'descriptive)
(if (not item) 0 (cl-incf indentation org-ascii-quote-margin))
;; Compute indentation offset of the current item, (t
;; that is the sum of the difference between its (cl-incf indentation
;; indentation and the indentation of the top item in (+ (string-width
;; the list and current item bullet's length. Also (or (org-ascii--checkbox e info) ""))
;; remove checkbox length, and tag length (for (string-width
;; description lists) or bullet length. (org-element-property :bullet e)))))))
(let ((struct (org-element-property :structure item)) indentation)))))))
(beg-item (org-element-property :begin item)))
(+ (- (org-list-get-ind beg-item struct)
(org-list-get-ind
(org-list-get-top-point struct) struct))
(string-width (or (org-ascii--checkbox item info)
""))
(string-width
(let ((tag (org-element-property :tag item)))
(if tag (org-export-data tag info)
(org-element-property :bullet item))))))))))))))
(defun org-ascii--current-justification (element) (defun org-ascii--current-justification (element)
"Return expected justification for ELEMENT's contents. "Return expected justification for ELEMENT's contents.
@ -1458,40 +1449,45 @@ contextual information."
(bullet (bullet
;; First parent of ITEM is always the plain-list. Get ;; First parent of ITEM is always the plain-list. Get
;; `:type' property from it. ;; `:type' property from it.
(org-list-bullet-string (pcase list-type
(pcase list-type (`descriptive
(`descriptive (concat checkbox
(concat checkbox (org-export-data (org-element-property :tag item)
(org-export-data (org-element-property :tag item) info) info)))
": ")) (`ordered
(`ordered ;; Return correct number for ITEM, paying attention to
;; Return correct number for ITEM, paying attention to ;; counters.
;; counters. (let* ((struct (org-element-property :structure item))
(let* ((struct (org-element-property :structure item)) (bul (org-list-bullet-string
(bul (org-element-property :bullet item)) (org-element-property :bullet item)))
(num (number-to-string (num (number-to-string
(car (last (org-list-get-item-number (car (last (org-list-get-item-number
(org-element-property :begin item) (org-element-property :begin item)
struct struct
(org-list-prevs-alist struct) (org-list-prevs-alist struct)
(org-list-parents-alist struct))))))) (org-list-parents-alist struct)))))))
(replace-regexp-in-string "[0-9]+" num bul))) (replace-regexp-in-string "[0-9]+" num bul)))
(_ (let ((bul (org-element-property :bullet item))) (_ (let ((bul (org-list-bullet-string
;; Change bullets into more visible form if UTF-8 is active. (org-element-property :bullet item))))
(if (not utf8p) bul ;; Change bullets into more visible form if UTF-8 is active.
(if (not utf8p) bul
(replace-regexp-in-string
"-" ""
(replace-regexp-in-string (replace-regexp-in-string
"-" "" "+" ""
(replace-regexp-in-string (replace-regexp-in-string "*" "" bul))))))))
"+" "" (indentation (if (eq list-type 'descriptive) org-ascii-quote-margin
(replace-regexp-in-string "*" "" bul)))))))))) (string-width bullet))))
(concat (concat
bullet bullet
(unless (eq list-type 'descriptive) checkbox) checkbox
;; Contents: Pay attention to indentation. Note: check-boxes are ;; Contents: Pay attention to indentation. Note: check-boxes are
;; already taken care of at the paragraph level so they don't ;; already taken care of at the paragraph level so they don't
;; interfere with indentation. ;; interfere with indentation.
(let ((contents (org-ascii--indent-string contents (string-width bullet)))) (let ((contents (org-ascii--indent-string contents indentation)))
(if (eq (org-element-type (car (org-element-contents item))) 'paragraph) (if (and (eq (org-element-type (car (org-element-contents item)))
'paragraph)
(not (eq list-type 'descriptive)))
(org-trim contents) (org-trim contents)
(concat "\n" contents)))))) (concat "\n" contents))))))