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)))
@ -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))