forked from mirrors/org-mode
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:
parent
7d3205a20f
commit
b7c1014353
|
@ -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))
|
||||||
|
|
Loading…
Reference in New Issue