Changes
[emacs.git] / .emacs.d / elisp / org / ox-ascii.el
index 4a6696e..42495e2 100644 (file)
@@ -1,6 +1,6 @@
 ;;; ox-ascii.el --- ASCII Back-End for Org Export Engine
 
-;; Copyright (C) 2012-2014 Free Software Foundation, Inc.
+;; Copyright (C) 2012-2015 Free Software Foundation, Inc.
 
 ;; Author: Nicolas Goaziou <n.goaziou at gmail dot com>
 ;; Keywords: outlines, hypermedia, calendar, wp
@@ -49,8 +49,6 @@
     (center-block . org-ascii-center-block)
     (clock . org-ascii-clock)
     (code . org-ascii-code)
-    (comment . (lambda (&rest args) ""))
-    (comment-block . (lambda (&rest args) ""))
     (drawer . org-ascii-drawer)
     (dynamic-block . org-ascii-dynamic-block)
     (entity . org-ascii-entity)
     (latex-fragment . org-ascii-latex-fragment)
     (line-break . org-ascii-line-break)
     (link . org-ascii-link)
+    (node-property . org-ascii-node-property)
     (paragraph . org-ascii-paragraph)
     (plain-list . org-ascii-plain-list)
     (plain-text . org-ascii-plain-text)
     (planning . org-ascii-planning)
+    (property-drawer . org-ascii-property-drawer)
     (quote-block . org-ascii-quote-block)
-    (quote-section . org-ascii-quote-section)
     (radio-target . org-ascii-radio-target)
     (section . org-ascii-section)
     (special-block . org-ascii-special-block)
                   (:filter-parse-tree org-ascii-filter-paragraph-spacing
                                       org-ascii-filter-comment-spacing)
                   (:filter-section . org-ascii-filter-headline-blank-lines))
-  :options-alist '((:ascii-charset nil nil org-ascii-charset)))
+  :options-alist
+  '((:ascii-bullets nil nil org-ascii-bullets)
+    (:ascii-caption-above nil nil org-ascii-caption-above)
+    (:ascii-charset nil nil org-ascii-charset)
+    (:ascii-global-margin nil nil org-ascii-global-margin)
+    (:ascii-format-drawer-function nil nil org-ascii-format-drawer-function)
+    (:ascii-format-inlinetask-function
+     nil nil org-ascii-format-inlinetask-function)
+    (:ascii-headline-spacing nil nil org-ascii-headline-spacing)
+    (:ascii-indented-line-width nil nil org-ascii-indented-line-width)
+    (:ascii-inlinetask-width nil nil org-ascii-inlinetask-width)
+    (:ascii-inner-margin nil nil org-ascii-inner-margin)
+    (:ascii-links-to-notes nil nil org-ascii-links-to-notes)
+    (:ascii-list-margin nil nil org-ascii-list-margin)
+    (:ascii-paragraph-spacing nil nil org-ascii-paragraph-spacing)
+    (:ascii-quote-margin nil nil org-ascii-quote-margin)
+    (:ascii-table-keep-all-vertical-lines
+     nil nil org-ascii-table-keep-all-vertical-lines)
+    (:ascii-table-use-ascii-art nil nil org-ascii-table-use-ascii-art)
+    (:ascii-table-widen-columns nil nil org-ascii-table-widen-columns)
+    (:ascii-text-width nil nil org-ascii-text-width)
+    (:ascii-underline nil nil org-ascii-underline)
+    (:ascii-verbatim-format nil nil org-ascii-verbatim-format)))
 
 
 \f
@@ -162,6 +183,15 @@ This margin is applied on both sides of the text."
   :package-version '(Org . "8.0")
   :type 'integer)
 
+(defcustom org-ascii-list-margin 0
+  "Width of margin used for plain lists, in characters.
+This margin applies to top level list only, not to its
+sub-lists."
+  :group 'org-export-ascii
+  :version "25.1"
+  :package-version '(Org . "8.3")
+  :type 'integer)
+
 (defcustom org-ascii-inlinetask-width 30
   "Width of inline tasks, in number of characters.
 This number ignores any margin."
@@ -384,14 +414,18 @@ nil to ignore the inline task."
 
 ;; Internal functions fall into three categories.
 
-;; The first one is about text formatting.  The core function is
-;; `org-ascii--current-text-width', which determines the current
-;; text width allowed to a given element.  In other words, it helps
-;; keeping each line width within maximum text width defined in
-;; `org-ascii-text-width'.  Once this information is known,
-;; `org-ascii--fill-string', `org-ascii--justify-string',
-;; `org-ascii--box-string' and `org-ascii--indent-string' can
-;; operate on a given output string.
+;; The first one is about text formatting.  The core functions are
+;; `org-ascii--current-text-width' and
+;; `org-ascii--current-justification', which determine, respectively,
+;; the current text width allowed to a given element and its expected
+;; justification.  Once this information is known,
+;; `org-ascii--fill-string', `org-ascii--justify-lines',
+;; `org-ascii--justify-element' `org-ascii--box-string' and
+;; `org-ascii--indent-string' can operate on a given output string.
+;; In particular, justification happens at the regular (i.e.,
+;; non-greater) element level, which means that when the exporting
+;; process reaches a container (e.g., a center block) content are
+;; already justified.
 
 ;; The second category contains functions handling elements listings,
 ;; triggered by "#+TOC:" keyword.  As such, `org-ascii--build-toc'
@@ -420,23 +454,24 @@ a communication channel.
 Optional argument JUSTIFY can specify any type of justification
 among `left', `center', `right' or `full'.  A nil value is
 equivalent to `left'.  For a justification that doesn't also fill
-string, see `org-ascii--justify-string'.
+string, see `org-ascii--justify-lines' and
+`org-ascii--justify-block'.
 
 Return nil if S isn't a string."
-  ;; Don't fill paragraph when break should be preserved.
-  (cond ((not (stringp s)) nil)
-       ((plist-get info :preserve-breaks) s)
-       (t (let ((double-space-p sentence-end-double-space))
-            (with-temp-buffer
-              (let ((fill-column text-width)
-                    (use-hard-newlines t)
-                    (sentence-end-double-space double-space-p))
-                (insert s)
-                (fill-region (point-min) (point-max) justify))
-              (buffer-string))))))
-
-(defun org-ascii--justify-string (s text-width how)
-  "Justify string S.
+  (when (stringp s)
+    (let ((double-space-p sentence-end-double-space))
+      (with-temp-buffer
+       (let ((fill-column text-width)
+             (use-hard-newlines t)
+             (sentence-end-double-space double-space-p))
+         (insert (if (plist-get info :preserve-breaks)
+                     (replace-regexp-in-string "\n" hard-newline s)
+                   s))
+         (fill-region (point-min) (point-max) justify))
+       (buffer-string)))))
+
+(defun org-ascii--justify-lines (s text-width how)
+  "Justify all lines in string S.
 TEXT-WIDTH is an integer specifying maximum length of a line.
 HOW determines the type of justification: it can be `left',
 `right', `full' or `center'."
@@ -452,6 +487,48 @@ HOW determines the type of justification: it can be `left',
        (forward-line)))
     (buffer-string)))
 
+(defun org-ascii--justify-element (contents element info)
+  "Justify CONTENTS of ELEMENT.
+INFO is a plist used as a communication channel.  Justification
+is done according to the type of element.  More accurately,
+paragraphs are filled and other elements are justified as blocks,
+that is according to the widest non blank line in CONTENTS."
+  (if (not (org-string-nw-p contents)) contents
+    (let ((text-width (org-ascii--current-text-width element info))
+         (how (org-ascii--current-justification element)))
+      (cond
+       ((eq (org-element-type element) 'paragraph)
+       ;; Paragraphs are treated specially as they need to be filled.
+       (org-ascii--fill-string contents text-width info how))
+       ((eq how 'left) contents)
+       (t (with-temp-buffer
+           (insert contents)
+           (goto-char (point-min))
+           (catch 'exit
+             (let ((max-width 0))
+               ;; Compute maximum width.  Bail out if it is greater
+               ;; than page width, since no justification is
+               ;; possible.
+               (save-excursion
+                 (while (not (eobp))
+                   (unless (org-looking-at-p "[ \t]*$")
+                     (end-of-line)
+                     (let ((column (current-column)))
+                       (cond
+                        ((>= column text-width) (throw 'exit contents))
+                        ((> column max-width) (setq max-width column)))))
+                   (forward-line)))
+               ;; Justify every line according to TEXT-WIDTH and
+               ;; MAX-WIDTH.
+               (let ((offset (/ (- text-width max-width)
+                                (if (eq how 'right) 1 2))))
+                 (if (zerop offset) (throw 'exit contents)
+                   (while (not (eobp))
+                     (unless (org-looking-at-p "[ \t]*$")
+                       (org-indent-to-column offset))
+                     (forward-line)))))
+             (buffer-string))))))))
+
 (defun org-ascii--indent-string (s width)
   "Indent string S by WIDTH white spaces.
 Empty lines are not indented."
@@ -463,7 +540,7 @@ Empty lines are not indented."
   "Return string S with a partial box to its left.
 INFO is a plist used as a communication channel."
   (let ((utf8p (eq (plist-get info :ascii-charset) 'utf-8)))
-    (format (if utf8p "â\95­â\94\80â\94\80â\94\80â\94\80\n%s\nâ\95°────" ",----\n%s\n`----")
+    (format (if utf8p "â\94\8câ\94\80â\94\80â\94\80â\94\80\n%s\nâ\94\94────" ",----\n%s\n`----")
            (replace-regexp-in-string
             "^" (if utf8p "│ " "| ")
             ;; Remove last newline character.
@@ -474,24 +551,25 @@ INFO is a plist used as a communication channel."
 INFO is a plist used as a communication channel."
   (case (org-element-type element)
     ;; Elements with an absolute width: `headline' and `inlinetask'.
-    (inlinetask org-ascii-inlinetask-width)
+    (inlinetask (plist-get info :ascii-inlinetask-width))
     (headline
-     (- org-ascii-text-width
+     (- (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) org-ascii-global-margin))))
+         (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.
     (otherwise
-     (let* ((genealogy (cons element (org-export-get-genealogy element)))
+     (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 (loop for parent in genealogy
                       thereis (eq (org-element-type parent) 'inlinetask))
-                org-ascii-inlinetask-width
+                (plist-get info :ascii-inlinetask-width)
               ;; No inlinetask: Remove global margin from text width.
-              (- org-ascii-text-width
-                 org-ascii-global-margin
+              (- (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.
@@ -502,41 +580,66 @@ INFO is a plist used as a communication channel."
                        ;; low level headlines, since they've got their
                        ;; own indentation mechanism.
                        (if low-level-rank (* low-level-rank 2)
-                         org-ascii-inner-margin))))))))
+                         (plist-get info :ascii-inner-margin)))))))))
        (- total-width
-         ;; Each `quote-block', `quote-section' and `verse-block' above
-         ;; narrows text width by twice the standard margin size.
+         ;; Each `quote-block' and `verse-block' above narrows text
+         ;; width by twice the standard margin size.
          (+ (* (loop for parent in genealogy
                      when (memq (org-element-type parent)
-                                '(quote-block quote-section verse-block))
+                                '(quote-block verse-block))
                      count parent)
-               2 org-ascii-quote-margin)
+               2 (plist-get info :ascii-quote-margin))
+            ;; Apply list margin once per "top-level" plain-list
+            ;; containing current line
+            (* (let ((count 0))
+                 (dolist (e genealogy count)
+                   (and (eq (org-element-type e) 'plain-list)
+                        (not (eq (org-element-type (org-export-get-parent e))
+                                 'item))
+                        (incf count))))
+               (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 ((parent-item
+            (let ((item
                    (if (eq (org-element-type element) 'item) element
                      (loop for parent in genealogy
                            when (eq (org-element-type parent) 'item)
                            return parent))))
-              (if (not parent-item) 0
+              (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 parent-item))
-                      (beg-item (org-element-property :begin parent-item)))
+                (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 parent-item info)
+                     (string-width (or (org-ascii--checkbox item info)
                                        ""))
                      (string-width
-                      (or (org-list-get-tag beg-item struct)
-                          (org-list-get-bullet beg-item struct)))))))))))))
+                      (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)
+  "Return expected justification for ELEMENT's contents.
+Return value is a symbol among `left', `center', `right' and
+`full'."
+  (let (justification)
+    (while (and (not justification)
+               (setq element (org-element-property :parent element)))
+      (case (org-element-type element)
+       (center-block (setq justification 'center))
+       (special-block
+        (let ((name (org-element-property :type element)))
+          (cond ((string= name "JUSTIFYRIGHT") (setq justification 'right))
+                ((string= name "JUSTIFYLEFT") (setq justification 'left)))))))
+    (or justification 'left)))
 
 (defun org-ascii--build-title
   (element info text-width &optional underline notags toc)
@@ -601,7 +704,7 @@ possible.  It doesn't apply to `inlinetask' elements."
        (let ((under-char
              (nth (1- (org-export-get-relative-level element info))
                   (cdr (assq (plist-get info :ascii-charset)
-                             org-ascii-underline)))))
+                             (plist-get info :ascii-underline))))))
         (and under-char
              (concat "\n"
                      (make-string (/ (string-width first-part)
@@ -640,7 +743,7 @@ caption keyword."
                 (org-export-data caption info))
         (org-ascii--current-text-width element info) info)))))
 
-(defun org-ascii--build-toc (info &optional n keyword)
+(defun org-ascii--build-toc (info &optional n keyword local)
   "Return a table of contents.
 
 INFO is a plist used as a communication channel.
@@ -649,28 +752,34 @@ Optional argument N, when non-nil, is an integer specifying the
 depth of the table.
 
 Optional argument KEYWORD specifies the TOC keyword, if any, from
-which the table of contents generation has been initiated."
-  (let ((title (org-ascii--translate "Table of Contents" info)))
-    (concat
-     title "\n"
-     (make-string (string-width title)
-                 (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
-     "\n\n"
-     (let ((text-width
-           (if keyword (org-ascii--current-text-width keyword info)
-             (- org-ascii-text-width org-ascii-global-margin))))
-       (mapconcat
-       (lambda (headline)
-         (let* ((level (org-export-get-relative-level headline info))
-                (indent (* (1- level) 3)))
-           (concat
-            (unless (zerop indent) (concat (make-string (1- indent) ?.) " "))
-            (org-ascii--build-title
-             headline info (- text-width indent) nil
-             (or (not (plist-get info :with-tags))
-                 (eq (plist-get info :with-tags) 'not-in-toc))
-             'toc))))
-       (org-export-collect-headlines info n) "\n")))))
+which the table of contents generation has been initiated.
+
+When optional argument LOCAL is non-nil, build a table of
+contents according to the current headline."
+  (concat
+   (unless local
+     (let ((title (org-ascii--translate "Table of Contents" info)))
+       (concat title "\n"
+              (make-string
+               (string-width title)
+               (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
+              "\n\n")))
+   (let ((text-width
+         (if keyword (org-ascii--current-text-width keyword info)
+           (- (plist-get info :ascii-text-width)
+              (plist-get info :ascii-global-margin)))))
+     (mapconcat
+      (lambda (headline)
+       (let* ((level (org-export-get-relative-level headline info))
+              (indent (* (1- level) 3)))
+         (concat
+          (unless (zerop indent) (concat (make-string (1- indent) ?.) " "))
+          (org-ascii--build-title
+           headline info (- text-width indent) nil
+           (or (not (plist-get info :with-tags))
+               (eq (plist-get info :with-tags) 'not-in-toc))
+           'toc))))
+      (org-export-collect-headlines info n (and local keyword)) "\n"))))
 
 (defun org-ascii--list-listings (keyword info)
   "Return a list of listings.
@@ -685,7 +794,8 @@ generation.  INFO is a plist used as a communication channel."
      "\n\n"
      (let ((text-width
            (if keyword (org-ascii--current-text-width keyword info)
-             (- org-ascii-text-width org-ascii-global-margin)))
+             (- (plist-get info :ascii-text-width)
+                (plist-get info :ascii-global-margin))))
           ;; Use a counter instead of retrieving ordinal of each
           ;; src-block.
           (count 0))
@@ -724,7 +834,8 @@ generation.  INFO is a plist used as a communication channel."
      "\n\n"
      (let ((text-width
            (if keyword (org-ascii--current-text-width keyword info)
-             (- org-ascii-text-width org-ascii-global-margin)))
+             (- (plist-get info :ascii-text-width)
+                (plist-get info :ascii-global-margin))))
           ;; Use a counter instead of retrieving ordinal of each
           ;; src-block.
           (count 0))
@@ -812,13 +923,22 @@ channel."
              (if (not dest) (org-ascii--translate "Unknown reference" info)
                (format
                 (org-ascii--translate "See section %s" info)
-                (mapconcat 'number-to-string
-                           (org-export-get-headline-number dest info) "."))))
+                (if (org-export-numbered-headline-p dest info)
+                    (mapconcat #'number-to-string
+                               (org-export-get-headline-number dest info) ".")
+                  (org-export-data (org-element-property :title dest) info)))))
             width info) "\n\n")))
        ;; Do not add a link that cannot be resolved and doesn't have
        ;; any description: destination is already visible in the
        ;; paragraph.
        ((not (org-element-contents link)) nil)
+       ;; Do not add a link already handled by custom export
+       ;; functions.
+       ((let ((protocol (nth 2 (assoc type org-link-protocols)))
+              (path (org-element-property :path link)))
+          (and (functionp protocol)
+               (funcall protocol (org-link-unescape path) anchor 'ascii)))
+        nil)
        (t
         (concat
          (org-ascii--fill-string
@@ -843,11 +963,13 @@ INFO is a plist used as a communication channel."
 (defun org-ascii-template--document-title (info)
   "Return document title, as a string.
 INFO is a plist used as a communication channel."
-  (let* ((text-width org-ascii-text-width)
+  (let* ((text-width (plist-get info :ascii-text-width))
         ;; Links in the title will not be resolved later, so we make
         ;; sure their path is located right after them.
-        (org-ascii-links-to-notes nil)
-        (title (org-export-data (plist-get info :title) info))
+        (info (org-combine-plists info '(:ascii-links-to-notes nil)))
+        (title (if (plist-get info :with-title)
+                   (org-export-data (plist-get info :title) info)
+                 ""))
         (author (and (plist-get info :with-author)
                      (let ((auth (plist-get info :author)))
                        (and auth (org-export-data auth info)))))
@@ -878,7 +1000,7 @@ INFO is a plist used as a communication channel."
           date "\n\n\n"))
         ((org-string-nw-p date)
          (concat
-          (org-ascii--justify-string date text-width 'right)
+          (org-ascii--justify-lines date text-width 'right)
           "\n\n\n"))
         ((and (org-string-nw-p author) (org-string-nw-p email))
          (concat author "\n" email "\n\n\n"))
@@ -899,17 +1021,15 @@ INFO is a plist used as a communication channel."
                            (string-width (or email "")))
                       2)
                    text-width) (if utf8p ?━ ?_))))
-       (org-ascii--justify-string
+       (org-ascii--justify-lines
         (concat line "\n"
                 (unless utf8p "\n")
                 (upcase formatted-title)
                 (cond
                  ((and (org-string-nw-p author) (org-string-nw-p email))
-                  (concat (if utf8p "\n\n\n" "\n\n") author "\n" email))
-                 ((org-string-nw-p author)
-                  (concat (if utf8p "\n\n\n" "\n\n") author))
-                 ((org-string-nw-p email)
-                  (concat (if utf8p "\n\n\n" "\n\n") email)))
+                  (concat "\n\n" author "\n" email))
+                 ((org-string-nw-p author) (concat "\n\n" author))
+                 ((org-string-nw-p email) (concat "\n\n" email)))
                 "\n" line
                 (when (org-string-nw-p date) (concat "\n\n\n" date))
                 "\n\n\n") text-width 'center)))))
@@ -919,81 +1039,82 @@ INFO is a plist used as a communication channel."
 CONTENTS is the transcoded contents string.  INFO is a plist
 holding export options."
   (org-element-normalize-string
-   (org-ascii--indent-string
-    (concat
-     ;; 1. Document's body.
-     contents
-     ;; 2. Footnote definitions.
-     (let ((definitions (org-export-collect-footnote-definitions
-                        (plist-get info :parse-tree) info))
-          ;; Insert full links right inside the footnote definition
-          ;; as they have no chance to be inserted later.
-          (org-ascii-links-to-notes nil))
-       (when definitions
-        (concat
-         "\n\n\n"
-         (let ((title (org-ascii--translate "Footnotes" info)))
-           (concat
-            title "\n"
-            (make-string
-             (string-width title)
-             (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))))
-         "\n\n"
-         (let ((text-width (- org-ascii-text-width org-ascii-global-margin)))
-           (mapconcat
-            (lambda (ref)
-              (let ((id (format "[%s] " (car ref))))
-                ;; Distinguish between inline definitions and
-                ;; full-fledged definitions.
-                (org-trim
-                 (let ((def (nth 2 ref)))
-                   (if (eq (org-element-type def) 'org-data)
-                       ;; Full-fledged definition: footnote ID is
-                       ;; inserted inside the first parsed paragraph
-                       ;; (FIRST), if any, to be sure filling will
-                       ;; take it into consideration.
-                       (let ((first (car (org-element-contents def))))
-                         (if (not (eq (org-element-type first) 'paragraph))
-                             (concat id "\n" (org-export-data def info))
-                           (push id (nthcdr 2 first))
-                           (org-export-data def info)))
-                     ;; Fill paragraph once footnote ID is inserted
-                     ;; in order to have a correct length for first
-                     ;; line.
-                     (org-ascii--fill-string
-                      (concat id (org-export-data def info))
-                      text-width info))))))
-            definitions "\n\n"))))))
-    org-ascii-global-margin)))
+   (let ((global-margin (plist-get info :ascii-global-margin)))
+     (org-ascii--indent-string
+      (concat
+       ;; 1. Document's body.
+       contents
+       ;; 2. Footnote definitions.
+       (let ((definitions (org-export-collect-footnote-definitions info))
+            ;; Insert full links right inside the footnote definition
+            ;; as they have no chance to be inserted later.
+            (info (org-combine-plists info '(:ascii-links-to-notes nil))))
+        (when definitions
+          (concat
+           "\n\n\n"
+           (let ((title (org-ascii--translate "Footnotes" info)))
+             (concat
+              title "\n"
+              (make-string
+               (string-width title)
+               (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))))
+           "\n\n"
+           (let ((text-width (- (plist-get info :ascii-text-width)
+                                global-margin)))
+             (mapconcat
+              (lambda (ref)
+                (let ((id (format "[%s] " (car ref))))
+                  ;; Distinguish between inline definitions and
+                  ;; full-fledged definitions.
+                  (org-trim
+                   (let ((def (nth 2 ref)))
+                     (if (eq (org-element-type def) 'org-data)
+                         ;; Full-fledged definition: footnote ID is
+                         ;; inserted inside the first parsed
+                         ;; paragraph (FIRST), if any, to be sure
+                         ;; filling will take it into consideration.
+                         (let ((first (car (org-element-contents def))))
+                           (if (not (eq (org-element-type first) 'paragraph))
+                               (concat id "\n" (org-export-data def info))
+                             (push id (nthcdr 2 first))
+                             (org-export-data def info)))
+                       ;; Fill paragraph once footnote ID is inserted
+                       ;; in order to have a correct length for first
+                       ;; line.
+                       (org-ascii--fill-string
+                        (concat id (org-export-data def info))
+                        text-width info))))))
+              definitions "\n\n"))))))
+      global-margin))))
 
 (defun org-ascii-template (contents info)
   "Return complete document string after ASCII conversion.
 CONTENTS is the transcoded contents string.  INFO is a plist
 holding export options."
-  (concat
-   ;; 1. Build title block.
-   (org-ascii--indent-string
-    (concat (org-ascii-template--document-title info)
-           ;; 2. Table of contents.
-           (let ((depth (plist-get info :with-toc)))
-             (when depth
-               (concat
-                (org-ascii--build-toc info (and (wholenump depth) depth))
-                "\n\n\n"))))
-    org-ascii-global-margin)
-   ;; 3. Document's body.
-   contents
-   ;; 4. Creator.  Ignore `comment' value as there are no comments in
-   ;;    ASCII.  Justify it to the bottom right.
-   (org-ascii--indent-string
-    (let ((creator-info (plist-get info :with-creator))
-         (text-width (- org-ascii-text-width org-ascii-global-margin)))
-      (unless (or (not creator-info) (eq creator-info 'comment))
-       (concat
-        "\n\n\n"
-        (org-ascii--fill-string
-         (plist-get info :creator) text-width info 'right))))
-    org-ascii-global-margin)))
+  (let ((global-margin (plist-get info :ascii-global-margin)))
+    (concat
+     ;; Build title block.
+     (org-ascii--indent-string
+      (concat (org-ascii-template--document-title info)
+             ;; 2. Table of contents.
+             (let ((depth (plist-get info :with-toc)))
+               (when depth
+                 (concat
+                  (org-ascii--build-toc info (and (wholenump depth) depth))
+                  "\n\n\n"))))
+      global-margin)
+     ;; Document's body.
+     contents
+     ;; Creator.  Justify it to the bottom right.
+     (and (plist-get info :with-creator)
+         (org-ascii--indent-string
+          (let ((text-width
+                 (- (plist-get info :ascii-text-width) global-margin)))
+            (concat
+             "\n\n\n"
+             (org-ascii--fill-string
+              (plist-get info :creator) text-width info 'right)))
+          global-margin)))))
 
 (defun org-ascii--translate (s info)
   "Translate string S according to specified language and charset.
@@ -1020,8 +1141,9 @@ contextual information."
   "Transcode a CENTER-BLOCK element from Org to ASCII.
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
-  (org-ascii--justify-string
-   contents (org-ascii--current-text-width center-block info) 'center))
+  ;; Center has already been taken care of at a lower level, so
+  ;; there's nothing left to do.
+  contents)
 
 
 ;;;; Clock
@@ -1030,16 +1152,16 @@ holding contextual information."
   "Transcode a CLOCK object from Org to ASCII.
 CONTENTS is nil.  INFO is a plist holding contextual
 information."
-  (concat org-clock-string " "
-         (org-translate-time
-          (org-element-property :raw-value
-                                (org-element-property :value clock)))
-         (let ((time (org-element-property :duration clock)))
-           (and time
-                (concat " => "
-                        (apply 'format
-                               "%2s:%02s"
-                               (org-split-string time ":")))))))
+  (org-ascii--justify-element
+   (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 ":"))))))
+   clock info))
 
 
 ;;;; Code
@@ -1048,7 +1170,8 @@ information."
   "Return a CODE object from Org to ASCII.
 CONTENTS is nil.  INFO is a plist holding contextual
 information."
-  (format org-ascii-verbatim-format (org-element-property :value code)))
+  (format (plist-get info :ascii-verbatim-format)
+         (org-element-property :value code)))
 
 
 ;;;; Drawer
@@ -1059,7 +1182,8 @@ CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
   (let ((name (org-element-property :drawer-name drawer))
        (width (org-ascii--current-text-width drawer info)))
-    (funcall org-ascii-format-drawer-function name contents width)))
+    (funcall (plist-get info :ascii-format-drawer-function)
+            name contents width)))
 
 
 ;;;; Dynamic Block
@@ -1087,8 +1211,10 @@ contextual information."
 (defun org-ascii-example-block (example-block contents info)
   "Transcode a EXAMPLE-BLOCK element from Org to ASCII.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (org-ascii--box-string
-   (org-export-format-code-default example-block info) info))
+  (org-ascii--justify-element
+   (org-ascii--box-string
+    (org-export-format-code-default example-block info) info)
+   example-block info))
 
 
 ;;;; Export Snippet
@@ -1106,7 +1232,8 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
   "Transcode a EXPORT-BLOCK element from Org to ASCII.
 CONTENTS is nil.  INFO is a plist holding contextual information."
   (when (string= (org-element-property :type export-block) "ASCII")
-    (org-remove-indentation (org-element-property :value export-block))))
+    (org-ascii--justify-element
+     (org-element-property :value export-block) export-block info)))
 
 
 ;;;; Fixed Width
@@ -1114,9 +1241,11 @@ CONTENTS is nil.  INFO is a plist holding contextual information."
 (defun org-ascii-fixed-width (fixed-width contents info)
   "Transcode a FIXED-WIDTH element from Org to ASCII.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (org-ascii--box-string
-   (org-remove-indentation
-    (org-element-property :value fixed-width)) info))
+  (org-ascii--justify-element
+   (org-ascii--box-string
+    (org-remove-indentation
+     (org-element-property :value fixed-width)) info)
+   fixed-width info))
 
 
 ;;;; Footnote Definition
@@ -1149,8 +1278,9 @@ holding contextual information."
           ;; original buffer's spacing.
           (pre-blanks
            (make-string
-            (if org-ascii-headline-spacing (car org-ascii-headline-spacing)
-              (org-element-property :pre-blank headline)) ?\n))
+            (or (car (plist-get info :ascii-headline-spacing))
+                (org-element-property :pre-blank headline))
+            ?\n))
           ;; Even if HEADLINE has no section, there might be some
           ;; links in its title that we shouldn't forget to describe.
           (links
@@ -1164,7 +1294,7 @@ holding contextual information."
          (concat
           ;; Bullet.
           (let ((bullets (cdr (assq (plist-get info :ascii-charset)
-                                    org-ascii-bullets))))
+                                    (plist-get info :ascii-bullets)))))
             (char-to-string
              (nth (mod (1- low-level-rank) (length bullets)) bullets)))
           " "
@@ -1192,7 +1322,7 @@ information."
   (let ((text-width (org-ascii--current-text-width horizontal-rule info))
        (spec-width
         (org-export-read-attribute :attr_ascii horizontal-rule :width)))
-    (org-ascii--justify-string
+    (org-ascii--justify-lines
      (make-string (if (and spec-width (string-match "^[0-9]+$" spec-width))
                      (string-to-number spec-width)
                    text-width)
@@ -1206,7 +1336,7 @@ information."
   "Transcode an INLINE-SRC-BLOCK element from Org to ASCII.
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
-  (format org-ascii-verbatim-format
+  (format (plist-get info :ascii-verbatim-format)
          (org-element-property :value inline-src-block)))
 
 
@@ -1218,7 +1348,7 @@ contextual information."
 See `org-ascii-format-inlinetask-function' for a description
 of the parameters."
   (let* ((utf8p (eq (plist-get info :ascii-charset) 'utf-8))
-        (width (or width org-ascii-inlinetask-width)))
+        (width (or width (plist-get info :ascii-inlinetask-width))))
     (org-ascii--indent-string
      (concat
       ;; Top line, with an additional blank line if not in UTF-8.
@@ -1236,9 +1366,9 @@ of the parameters."
       ;; Bottom line.
       (make-string width (if utf8p ?━ ?_)))
      ;; Flush the inlinetask to the right.
-     (- org-ascii-text-width org-ascii-global-margin
+     (- (plist-get info :ascii-text-width) (plist-get info :ascii-global-margin)
        (if (not (org-export-get-parent-headline inlinetask)) 0
-         org-ascii-inner-margin)
+         (plist-get info :ascii-inner-margin))
        (org-ascii--current-text-width inlinetask info)))))
 
 (defun org-ascii-inlinetask (inlinetask contents info)
@@ -1246,7 +1376,7 @@ of the parameters."
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
   (let ((width (org-ascii--current-text-width inlinetask info)))
-    (funcall org-ascii-format-inlinetask-function
+    (funcall (plist-get info :ascii-format-inlinetask-function)
             ;; todo.
             (and (plist-get info :with-todo-keywords)
                  (let ((todo (org-element-property
@@ -1334,20 +1464,21 @@ information."
   (let ((key (org-element-property :key keyword))
        (value (org-element-property :value keyword)))
     (cond
-     ((string= key "ASCII") value)
+     ((string= key "ASCII") (org-ascii--justify-element value keyword info))
      ((string= key "TOC")
-      (let ((value (downcase value)))
-       (cond
-        ((string-match "\\<headlines\\>" value)
-         (let ((depth (or (and (string-match "[0-9]+" value)
-                               (string-to-number (match-string 0 value)))
-                          (plist-get info :with-toc))))
-           (org-ascii--build-toc
-            info (and (wholenump depth) depth) keyword)))
-        ((string= "tables" value)
-         (org-ascii--list-tables keyword info))
-        ((string= "listings" value)
-         (org-ascii--list-listings keyword info))))))))
+      (org-ascii--justify-element
+       (let ((case-fold-search t))
+        (cond
+         ((org-string-match-p "\\<headlines\\>" value)
+          (let ((depth (and (string-match "\\<[0-9]+\\>" value)
+                            (string-to-number (match-string 0 value))))
+                (localp (org-string-match-p "\\<local\\>" value)))
+            (org-ascii--build-toc info depth keyword localp)))
+         ((org-string-match-p "\\<tables\\>" value)
+          (org-ascii--list-tables keyword info))
+         ((org-string-match-p "\\<listings\\>" value)
+          (org-ascii--list-listings keyword info))))
+       keyword info)))))
 
 
 ;;;; Latex Environment
@@ -1357,7 +1488,9 @@ information."
 CONTENTS is nil.  INFO is a plist holding contextual
 information."
   (when (plist-get info :with-latex)
-    (org-remove-indentation (org-element-property :value latex-environment))))
+    (org-ascii--justify-element
+     (org-remove-indentation (org-element-property :value latex-environment))
+     latex-environment info)))
 
 
 ;;;; Latex Fragment
@@ -1385,9 +1518,9 @@ CONTENTS is nil.  INFO is a plist holding contextual
 
 DESC is the description part of the link, or the empty string.
 INFO is a plist holding contextual information."
-  (let ((raw-link (org-element-property :raw-link link))
-       (type (org-element-property :type link)))
+  (let ((type (org-element-property :type link)))
     (cond
+     ((org-export-custom-protocol-maybe link desc 'ascii))
      ((string= type "coderef")
       (let ((ref (org-element-property :path link)))
        (format (org-export-get-coderef-format ref desc)
@@ -1404,14 +1537,33 @@ INFO is a plist holding contextual information."
            (let ((number
                   (org-export-get-ordinal
                    destination info nil 'org-ascii--has-caption-p)))
-             (when number
-               (if (atom number) (number-to-string number)
-                 (mapconcat 'number-to-string number "."))))))))
+             (if number
+                 (if (atom number) (number-to-string number)
+                   (mapconcat #'number-to-string number "."))
+               ;; Unnumbered headline.
+               (when (eq 'headline (org-element-type destination))
+                 (format "[%s]"
+                         (org-export-data
+                          (org-element-property :title destination)
+                          info)))))))))
      (t
-      (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
-       (concat
-        (format "[%s]" desc)
-        (unless org-ascii-links-to-notes (format " (%s)" raw-link))))))))
+      (let ((raw-link (org-element-property :raw-link link)))
+       (if (not (org-string-nw-p desc)) (format "[%s]" raw-link)
+         (concat (format "[%s]" desc)
+                 (and (not (plist-get info :ascii-links-to-notes))
+                      (format " (%s)" raw-link)))))))))
+
+
+;;;; Node Properties
+
+(defun org-ascii-node-property (node-property contents info)
+  "Transcode a NODE-PROPERTY element from Org to ASCII.
+CONTENTS is nil.  INFO is a plist holding contextual
+information."
+  (format "%s:%s"
+          (org-element-property :key node-property)
+          (let ((value (org-element-property :value node-property)))
+            (if value (concat " " value) ""))))
 
 
 ;;;; Paragraph
@@ -1420,16 +1572,17 @@ INFO is a plist holding contextual information."
   "Transcode a PARAGRAPH element from Org to ASCII.
 CONTENTS is the contents of the paragraph, as a string.  INFO is
 the plist used as a communication channel."
-  (org-ascii--fill-string
-   (if (not (wholenump org-ascii-indented-line-width)) contents
-     (concat
-      ;; Do not indent first paragraph in a section.
-      (unless (and (not (org-export-get-previous-element paragraph info))
-                  (eq (org-element-type (org-export-get-parent paragraph))
-                      'section))
-       (make-string org-ascii-indented-line-width ?\s))
-      (replace-regexp-in-string "\\`[ \t]+" "" contents)))
-   (org-ascii--current-text-width paragraph info) info))
+  (org-ascii--justify-element
+   (let ((indented-line-width (plist-get info :ascii-indented-line-width)))
+     (if (not (wholenump indented-line-width)) contents
+       (concat
+       ;; Do not indent first paragraph in a section.
+       (unless (and (not (org-export-get-previous-element paragraph info))
+                    (eq (org-element-type (org-export-get-parent paragraph))
+                        'section))
+         (make-string indented-line-width ?\s))
+       (replace-regexp-in-string "\\`[ \t]+" "" contents))))
+   paragraph info))
 
 
 ;;;; Plain List
@@ -1438,7 +1591,11 @@ the plist used as a communication channel."
   "Transcode a PLAIN-LIST element from Org to ASCII.
 CONTENTS is the contents of the list.  INFO is a plist holding
 contextual information."
-  contents)
+  (let ((margin (plist-get info :ascii-list-margin)))
+    (if (or (< margin 1)
+           (eq (org-element-type (org-export-get-parent plain-list)) 'item))
+       contents
+      (org-ascii--indent-string contents margin))))
 
 
 ;;;; Plain Text
@@ -1466,25 +1623,34 @@ INFO is a plist used as a communication channel."
   "Transcode a PLANNING element from Org to ASCII.
 CONTENTS is nil.  INFO is a plist used as a communication
 channel."
-  (mapconcat
-   'identity
-   (delq nil
-        (list (let ((closed (org-element-property :closed planning)))
-                (when closed
-                  (concat org-closed-string " "
-                          (org-translate-time
-                           (org-element-property :raw-value closed)))))
-              (let ((deadline (org-element-property :deadline planning)))
-                (when deadline
-                  (concat org-deadline-string " "
-                          (org-translate-time
-                           (org-element-property :raw-value deadline)))))
-              (let ((scheduled (org-element-property :scheduled planning)))
-                (when scheduled
-                  (concat org-scheduled-string " "
-                          (org-translate-time
-                           (org-element-property :raw-value scheduled)))))))
-   " "))
+  (org-ascii--justify-element
+   (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))))))
+    " ")
+   planning info))
+
+
+;;;; Property Drawer
+
+(defun org-ascii-property-drawer (property-drawer contents info)
+  "Transcode a PROPERTY-DRAWER element from Org to ASCII.
+CONTENTS holds the contents of the drawer.  INFO is a plist
+holding contextual information."
+  (and (org-string-nw-p contents)
+       (org-ascii--justify-element contents property-drawer info)))
 
 
 ;;;; Quote Block
@@ -1493,26 +1659,7 @@ channel."
   "Transcode a QUOTE-BLOCK element from Org to ASCII.
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
-  (org-ascii--indent-string contents org-ascii-quote-margin))
-
-
-;;;; Quote Section
-
-(defun org-ascii-quote-section (quote-section contents info)
-  "Transcode a QUOTE-SECTION element from Org to ASCII.
-CONTENTS is nil.  INFO is a plist holding contextual information."
-  (let ((width (org-ascii--current-text-width quote-section info))
-       (value
-        (org-export-data
-         (org-remove-indentation (org-element-property :value quote-section))
-         info)))
-    (org-ascii--indent-string
-     value
-     (+ org-ascii-quote-margin
-       ;; Don't apply inner margin if parent headline is low level.
-       (let ((headline (org-export-get-parent-headline quote-section)))
-         (if (org-export-low-level-p headline info) 0
-           org-ascii-inner-margin))))))
+  (org-ascii--indent-string contents (plist-get info :ascii-quote-margin)))
 
 
 ;;;; Radio Target
@@ -1533,7 +1680,7 @@ contextual information."
   (org-ascii--indent-string
    (concat
     contents
-    (when org-ascii-links-to-notes
+    (when (plist-get info :ascii-links-to-notes)
       ;; Add list of links at the end of SECTION.
       (let ((links (org-ascii--describe-links
                    (org-ascii--unique-links section info)
@@ -1543,7 +1690,7 @@ contextual information."
    ;; Do not apply inner margin if parent headline is low level.
    (let ((headline (org-export-get-parent-headline section)))
      (if (or (not headline) (org-export-low-level-p headline info)) 0
-       org-ascii-inner-margin))))
+       (plist-get info :ascii-inner-margin)))))
 
 
 ;;;; Special Block
@@ -1552,6 +1699,9 @@ contextual information."
   "Transcode a SPECIAL-BLOCK element from Org to ASCII.
 CONTENTS holds the contents of the block.  INFO is a plist
 holding contextual information."
+  ;; "JUSTIFYLEFT" and "JUSTFYRIGHT" have already been taken care of
+  ;; at a lower level.  There is no other special block type to
+  ;; handle.
   contents)
 
 
@@ -1562,13 +1712,15 @@ holding contextual information."
 CONTENTS holds the contents of the item.  INFO is a plist holding
 contextual information."
   (let ((caption (org-ascii--build-caption src-block info))
+       (caption-above-p (plist-get info :ascii-caption-above))
        (code (org-export-format-code-default src-block info)))
     (if (equal code "") ""
-      (concat
-       (when (and caption org-ascii-caption-above) (concat caption "\n"))
-       (org-ascii--box-string code info)
-       (when (and caption (not org-ascii-caption-above))
-        (concat "\n" caption))))))
+      (org-ascii--justify-element
+       (concat
+       (and caption caption-above-p (concat caption "\n"))
+       (org-ascii--box-string code info)
+       (and caption (not caption-above-p) (concat "\n" caption)))
+       src-block info))))
 
 
 ;;;; Statistics Cookie
@@ -1616,26 +1768,29 @@ holding contextual information."
   "Transcode a TABLE element from Org to ASCII.
 CONTENTS is the contents of the table.  INFO is a plist holding
 contextual information."
-  (let ((caption (org-ascii--build-caption table info)))
-    (concat
-     ;; Possibly add a caption string above.
-     (when (and caption org-ascii-caption-above) (concat caption "\n"))
-     ;; Insert table.  Note: "table.el" tables are left unmodified.
-     (cond ((eq (org-element-property :type table) 'org) contents)
-          ((and org-ascii-table-use-ascii-art
-                (eq (plist-get info :ascii-charset) 'utf-8)
-                (require 'ascii-art-to-unicode nil t))
-           (with-temp-buffer
-             (insert (org-remove-indentation
-                      (org-element-property :value table)))
-             (goto-char (point-min))
-             (aa2u)
-             (goto-char (point-max))
-             (skip-chars-backward " \r\t\n")
-             (buffer-substring (point-min) (point))))
-          (t (org-remove-indentation (org-element-property :value table))))
-     ;; Possible add a caption string below.
-     (and (not org-ascii-caption-above) caption))))
+  (let ((caption (org-ascii--build-caption table info))
+       (caption-above-p (plist-get info :ascii-caption-above)))
+    (org-ascii--justify-element
+     (concat
+      ;; Possibly add a caption string above.
+      (and caption caption-above-p (concat caption "\n"))
+      ;; Insert table.  Note: "table.el" tables are left unmodified.
+      (cond ((eq (org-element-property :type table) 'org) contents)
+           ((and (plist-get info :ascii-table-use-ascii-art)
+                 (eq (plist-get info :ascii-charset) 'utf-8)
+                 (require 'ascii-art-to-unicode nil t))
+            (with-temp-buffer
+              (insert (org-remove-indentation
+                       (org-element-property :value table)))
+              (goto-char (point-min))
+              (aa2u)
+              (goto-char (point-max))
+              (skip-chars-backward " \r\t\n")
+              (buffer-substring (point-min) (point))))
+           (t (org-remove-indentation (org-element-property :value table))))
+      ;; Possible add a caption string below.
+      (and (not caption-above-p) caption))
+     table info)))
 
 
 ;;;; Table Cell
@@ -1661,12 +1816,13 @@ are ignored."
                               (plist-put info :ascii-table-cell-width-cache
                                          (make-hash-table :test 'equal)))
                         :ascii-table-cell-width-cache)))
-        (key (cons table col)))
+        (key (cons table col))
+        (widenp (plist-get info :ascii-table-widen-columns)))
     (or (gethash key cache)
        (puthash
         key
         (let ((cookie-width (org-export-table-cell-width table-cell info)))
-          (or (and (not org-ascii-table-widen-columns) cookie-width)
+          (or (and (not widenp) cookie-width)
               (let ((contents-width
                      (let ((max-width 0))
                        (org-element-map table 'table-row
@@ -1681,8 +1837,7 @@ are ignored."
                          info)
                        max-width)))
                 (cond ((not cookie-width) contents-width)
-                      (org-ascii-table-widen-columns
-                       (max cookie-width contents-width))
+                      (widenp (max cookie-width contents-width))
                       (t cookie-width)))))
         cache))))
 
@@ -1696,14 +1851,14 @@ a communication channel."
   ;; each cell in the column.
   (let ((width (org-ascii--table-cell-width table-cell info)))
     ;; When contents are too large, truncate them.
-    (unless (or org-ascii-table-widen-columns
+    (unless (or (plist-get info :ascii-table-widen-columns)
                (<= (string-width (or contents "")) width))
       (setq contents (concat (substring contents 0 (- width 2)) "=>")))
     ;; Align contents correctly within the cell.
     (let* ((indent-tabs-mode nil)
           (data
            (when contents
-             (org-ascii--justify-string
+             (org-ascii--justify-lines
               contents width
               (org-export-table-cell-alignment table-cell info)))))
       (setq contents
@@ -1790,7 +1945,7 @@ holding contextual information."
 (defun org-ascii-verbatim (verbatim contents info)
   "Return a VERBATIM object from Org to ASCII.
 CONTENTS is nil.  INFO is a plist holding contextual information."
-  (format org-ascii-verbatim-format
+  (format (plist-get info :ascii-verbatim-format)
          (org-element-property :value verbatim)))
 
 
@@ -1802,8 +1957,8 @@ CONTENTS is verse block contents.  INFO is a plist holding
 contextual information."
   (let ((verse-width (org-ascii--current-text-width verse-block info)))
     (org-ascii--indent-string
-     (org-ascii--justify-string contents verse-width 'left)
-     org-ascii-quote-margin)))
+     (org-ascii--justify-element contents verse-block info)
+     (plist-get info :ascii-quote-margin))))
 
 
 \f
@@ -1818,9 +1973,10 @@ plist containing the communication channel.
 
 This function only applies to `ascii' back-end.  See
 `org-ascii-headline-spacing' for information."
-  (if (not org-ascii-headline-spacing) headline
-    (let ((blanks (make-string (1+ (cdr org-ascii-headline-spacing)) ?\n)))
-      (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline))))
+  (let ((headline-spacing (plist-get info :ascii-headline-spacing)))
+    (if (not headline-spacing) headline
+      (let ((blanks (make-string (1+ (cdr headline-spacing)) ?\n)))
+       (replace-regexp-in-string "\n\\(?:\n[ \t]*\\)*\\'" blanks headline)))))
 
 (defun org-ascii-filter-paragraph-spacing (tree back-end info)
   "Filter controlling number of blank lines between paragraphs.
@@ -1830,13 +1986,13 @@ back-end used for export.  INFO is a plist used as
 a communication channel.
 
 See `org-ascii-paragraph-spacing' for information."
-  (when (wholenump org-ascii-paragraph-spacing)
-    (org-element-map tree 'paragraph
-      (lambda (p)
-       (when (eq (org-element-type (org-export-get-next-element p info))
-                 'paragraph)
-         (org-element-put-property
-          p :post-blank org-ascii-paragraph-spacing)))))
+  (let ((paragraph-spacing (plist-get info :ascii-paragraph-spacing)))
+    (when (wholenump paragraph-spacing)
+      (org-element-map tree 'paragraph
+       (lambda (p)
+         (when (eq (org-element-type (org-export-get-next-element p info))
+                   'paragraph)
+           (org-element-put-property p :post-blank paragraph-spacing))))))
   tree)
 
 (defun org-ascii-filter-comment-spacing (tree backend info)