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