ox-ascii: Convert `length' to `string-width'

* lisp/ox-ascii.el (org-ascii--current-text-width): Convert `length'
  to `string-width'.
  (org-ascii--build-title, org-ascii--build-toc)
  (org-ascii--list-listings, org-ascii--list-tables)
  (org-ascii-template--document-title)
  (org-ascii-inner-template, org-ascii-format-inlinetask-default)
  (org-ascii-format-inlinetask-default, org-ascii-item
  (org-ascii--table-cell-width, org-ascii-table-cell)
  (org-ascii--current-text-width): Likewise.

I've checked all occurrences of the function `length' in ox-ascii.el.
It turns out that the most of them are calculating the width of given
string.  To support fullwidth characters, we better use `string-width'
instead of `length'.

Some characters in UCS are categorized as "East Asian Ambiguous"[1].
The return value of `string-width' with those characters depends on
how Emacs is setup.  We leave those ambiguous character handling to
Emacs.

Two usages of `length' in `ox-ascii.el' were left as-is, because those
were used for:

 - bullet depth calculation in `org-ascii-headline', and
 - cell position calculation in `org-ascii--table-cell-width'.

[1]: http://www.unicode.org/reports/tr11/#Ambiguous
This commit is contained in:
Yasushi SHOJI 2014-01-16 16:09:30 +01:00 committed by Nicolas Goaziou
parent 7d3205a20f
commit b7c1014353
1 changed files with 41 additions and 27 deletions

View File

@ -530,8 +530,9 @@ INFO is a plist used as a communication channel."
(+ (- (org-list-get-ind beg-item struct) (+ (- (org-list-get-ind beg-item struct)
(org-list-get-ind (org-list-get-ind
(org-list-get-top-point struct) struct)) (org-list-get-top-point struct) struct))
(length (org-ascii--checkbox parent-item info)) (string-width (or (org-ascii--checkbox parent-item info)
(length ""))
(string-width
(or (org-list-get-tag beg-item struct) (or (org-list-get-tag beg-item struct)
(org-list-get-bullet beg-item struct))))))))))))) (org-list-get-bullet beg-item struct)))))))))))))
@ -589,7 +590,8 @@ possible. It doesn't apply to `inlinetask' elements."
(when tags (when tags
(format (format
(format " %%%ds" (format " %%%ds"
(max (- text-width (1+ (length first-part))) (length tags))) (max (- text-width (1+ (string-width first-part)))
(string-width tags)))
tags)) tags))
;; Maybe underline text, if ELEMENT type is `headline' and an ;; Maybe underline text, if ELEMENT type is `headline' and an
;; underline character has been defined. ;; underline character has been defined.
@ -600,7 +602,9 @@ possible. It doesn't apply to `inlinetask' elements."
org-ascii-underline))))) org-ascii-underline)))))
(and under-char (and under-char
(concat "\n" (concat "\n"
(make-string (length first-part) under-char)))))))) (make-string (/ (string-width first-part)
(char-width under-char))
under-char))))))))
(defun org-ascii--has-caption-p (element info) (defun org-ascii--has-caption-p (element info)
"Non-nil when ELEMENT has a caption affiliated keyword. "Non-nil when ELEMENT has a caption affiliated keyword.
@ -647,7 +651,7 @@ which the table of contents generation has been initiated."
(let ((title (org-ascii--translate "Table of Contents" info))) (let ((title (org-ascii--translate "Table of Contents" info)))
(concat (concat
title "\n" title "\n"
(make-string (length title) (make-string (string-width title)
(if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)) (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
"\n\n" "\n\n"
(let ((text-width (let ((text-width
@ -674,7 +678,7 @@ generation. INFO is a plist used as a communication channel."
(let ((title (org-ascii--translate "List of Listings" info))) (let ((title (org-ascii--translate "List of Listings" info)))
(concat (concat
title "\n" title "\n"
(make-string (length title) (make-string (string-width title)
(if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)) (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
"\n\n" "\n\n"
(let ((text-width (let ((text-width
@ -688,9 +692,10 @@ generation. INFO is a plist used as a communication channel."
;; Store initial text so its length can be computed. This is ;; Store initial text so its length can be computed. This is
;; used to properly align caption right to it in case of ;; used to properly align caption right to it in case of
;; filling (like contents of a description list item). ;; filling (like contents of a description list item).
(let ((initial-text (let* ((initial-text
(format (org-ascii--translate "Listing %d:" info) (format (org-ascii--translate "Listing %d:" info)
(incf count)))) (incf count)))
(initial-width (string-width initial-text)))
(concat (concat
initial-text " " initial-text " "
(org-trim (org-trim
@ -700,8 +705,8 @@ generation. INFO is a plist used as a communication channel."
(let ((caption (or (org-export-get-caption src-block t) (let ((caption (or (org-export-get-caption src-block t)
(org-export-get-caption src-block)))) (org-export-get-caption src-block))))
(org-export-data caption info)) (org-export-data caption info))
(- text-width (length initial-text)) info) (- text-width initial-width) info)
(length initial-text)))))) initial-width)))))
(org-export-collect-listings info) "\n"))))) (org-export-collect-listings info) "\n")))))
(defun org-ascii--list-tables (keyword info) (defun org-ascii--list-tables (keyword info)
@ -712,7 +717,7 @@ generation. INFO is a plist used as a communication channel."
(let ((title (org-ascii--translate "List of Tables" info))) (let ((title (org-ascii--translate "List of Tables" info)))
(concat (concat
title "\n" title "\n"
(make-string (length title) (make-string (string-width title)
(if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)) (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))
"\n\n" "\n\n"
(let ((text-width (let ((text-width
@ -726,9 +731,10 @@ generation. INFO is a plist used as a communication channel."
;; Store initial text so its length can be computed. This is ;; Store initial text so its length can be computed. This is
;; used to properly align caption right to it in case of ;; used to properly align caption right to it in case of
;; filling (like contents of a description list item). ;; filling (like contents of a description list item).
(let ((initial-text (let* ((initial-text
(format (org-ascii--translate "Table %d:" info) (format (org-ascii--translate "Table %d:" info)
(incf count)))) (incf count)))
(initial-width (string-width initial-text)))
(concat (concat
initial-text " " initial-text " "
(org-trim (org-trim
@ -738,8 +744,8 @@ generation. INFO is a plist used as a communication channel."
(let ((caption (or (org-export-get-caption table t) (let ((caption (or (org-export-get-caption table t)
(org-export-get-caption table)))) (org-export-get-caption table))))
(org-export-data caption info)) (org-export-data caption info))
(- text-width (length initial-text)) info) (- text-width initial-width) info)
(length initial-text)))))) initial-width)))))
(org-export-collect-tables info) "\n"))))) (org-export-collect-tables info) "\n")))))
(defun org-ascii--unique-links (element info) (defun org-ascii--unique-links (element info)
@ -852,14 +858,16 @@ INFO is a plist used as a communication channel."
((and (org-string-nw-p date) (org-string-nw-p author)) ((and (org-string-nw-p date) (org-string-nw-p author))
(concat (concat
author author
(make-string (- text-width (length date) (length author)) ? ) (make-string (- text-width (string-width date) (string-width author))
?\s)
date date
(when (org-string-nw-p email) (concat "\n" email)) (when (org-string-nw-p email) (concat "\n" email))
"\n\n\n")) "\n\n\n"))
((and (org-string-nw-p date) (org-string-nw-p email)) ((and (org-string-nw-p date) (org-string-nw-p email))
(concat (concat
email email
(make-string (- text-width (length date) (length email)) ? ) (make-string (- text-width (string-width date) (string-width email))
?\s)
date "\n\n\n")) date "\n\n\n"))
((org-string-nw-p date) ((org-string-nw-p date)
(concat (concat
@ -879,7 +887,10 @@ INFO is a plist used as a communication channel."
(formatted-title (org-ascii--fill-string title title-len info)) (formatted-title (org-ascii--fill-string title title-len info))
(line (line
(make-string (make-string
(min (+ (max title-len (length author) (length email)) 2) (min (+ (max title-len
(string-width (or author ""))
(string-width (or email "")))
2)
text-width) (if utf8p ?━ ?_)))) text-width) (if utf8p ?━ ?_))))
(org-ascii--justify-string (org-ascii--justify-string
(concat line "\n" (concat line "\n"
@ -918,7 +929,7 @@ holding export options."
(concat (concat
title "\n" title "\n"
(make-string (make-string
(length title) (string-width title)
(if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_)))) (if (eq (plist-get info :ascii-charset) 'utf-8) ?─ ?_))))
"\n\n" "\n\n"
(let ((text-width (- org-ascii-text-width org-ascii-global-margin))) (let ((text-width (- org-ascii-text-width org-ascii-global-margin)))
@ -1195,7 +1206,7 @@ contextual information."
;;;; Inlinetask ;;;; Inlinetask
(defun org-ascii-format-inlinetask-default (defun org-ascii-format-inlinetask-default
(todo type priority name tags contents width inlinetask info) (todo type priority name tags contents width inlinetask info)
"Format an inline task element for ASCII export. "Format an inline task element for ASCII export.
See `org-ascii-format-inlinetask-function' for a description See `org-ascii-format-inlinetask-function' for a description
of the parameters." of the parameters."
@ -1208,7 +1219,7 @@ of the parameters."
(unless utf8p (concat (make-string width ? ) "\n")) (unless utf8p (concat (make-string width ? ) "\n"))
;; Add title. Fill it if wider than inlinetask. ;; Add title. Fill it if wider than inlinetask.
(let ((title (org-ascii--build-title inlinetask info width))) (let ((title (org-ascii--build-title inlinetask info width)))
(if (<= (length title) width) title (if (<= (string-width title) width) title
(org-ascii--fill-string title width info))) (org-ascii--fill-string title width info)))
"\n" "\n"
;; If CONTENTS is not empty, insert it along with ;; If CONTENTS is not empty, insert it along with
@ -1301,7 +1312,7 @@ contextual information."
;; 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 (length bullet)))) (let ((contents (org-ascii--indent-string contents (string-width bullet))))
(if (eq (org-element-type (car (org-element-contents item))) 'paragraph) (if (eq (org-element-type (car (org-element-contents item))) 'paragraph)
(org-trim contents) (org-trim contents)
(concat "\n" contents)))))) (concat "\n" contents))))))
@ -1652,7 +1663,7 @@ are ignored."
(org-element-map table 'table-row (org-element-map table 'table-row
(lambda (row) (lambda (row)
(setq max-width (setq max-width
(max (length (max (string-width
(org-export-data (org-export-data
(org-element-contents (org-element-contents
(elt (org-element-contents row) col)) (elt (org-element-contents row) col))
@ -1672,7 +1683,8 @@ a communication channel."
;; each cell in the column. ;; each cell in the column.
(let ((width (org-ascii--table-cell-width table-cell info))) (let ((width (org-ascii--table-cell-width table-cell info)))
;; When contents are too large, truncate them. ;; When contents are too large, truncate them.
(unless (or org-ascii-table-widen-columns (<= (length contents) width)) (unless (or org-ascii-table-widen-columns
(<= (string-width (or contents "")) width))
(setq contents (concat (substring contents 0 (- width 2)) "=>"))) (setq contents (concat (substring contents 0 (- width 2)) "=>")))
;; Align contents correctly within the cell. ;; Align contents correctly within the cell.
(let* ((indent-tabs-mode nil) (let* ((indent-tabs-mode nil)
@ -1681,7 +1693,9 @@ a communication channel."
(org-ascii--justify-string (org-ascii--justify-string
contents width contents width
(org-export-table-cell-alignment table-cell info))))) (org-export-table-cell-alignment table-cell info)))))
(setq contents (concat data (make-string (- width (length data)) ? )))) (setq contents
(concat data
(make-string (- width (string-width (or data ""))) ?\s))))
;; Return cell. ;; Return cell.
(concat (format " %s " contents) (concat (format " %s " contents)
(when (memq 'right (org-export-table-cell-borders table-cell info)) (when (memq 'right (org-export-table-cell-borders table-cell info))