emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Yasushi SHOJI <yashi@atmark-techno.com>
To: emacs-orgmode@gnu.org
Subject: [RFC] ox-ascii.el: fixing variable width character handling
Date: Sun, 10 Nov 2013 19:40:21 +0900	[thread overview]
Message-ID: <87zjpcsfoq.wl@dns1.atmark-techno.com> (raw)

Hi,

I've been trying to fix ASCII export back-end for variable width
chars. It is basically replacing `length' with `string-width', but the
behavior of those two functions differ when you give nil as an
argument; `length' returns 0, `string-width' yields a type error:
"eval: Wrong type argument: stringp, nil"

While I came up with the following experimental patch, I have a few
questions:

 - What is the lisp idiom to handle type error?  In the following
   patch, I've created a new wrapper function
   `org-ascii--string-width', it's a thin wrapper with if-then-else.
   I thought placing if-then-else clause in the original place clutter
   the code.

 - If wrapped string-width is good idea, would it be also a good idea
   to merge it with `org-string-width' in org.el?  Because it is not
   ox-ascii specific.  The current `org-string-width' does not handle
   nil, neither.

 - The width of the underline for headlines should be checked with
   string-width.

   As defined in Unicode Standard Annex #41[1], character width is
   environment dependent.  So, the calculation of character width at
   export time might not be sufficient enough.  We can check to see
   the exported document contains cjk chars more than some thresholds
   or not, I haven't gone that far.

 - Does anyone using ox-ascii.el depends on the clipped marker `=>'
   for fixed width columns?  I thought `...' would be much readable.

 - BTW, while looking at table handling, I noticed fixed column width
   doesn't work with the code at the current git HEAD.  That's because
   width calculation is mixed with `length' and `string-width', and
   pass out-of-range arguments to `add-text-properties'.


[1]: http://www.unicode.org/reports/tr41/

diff --git a/lisp/ox-ascii.el b/lisp/ox-ascii.el
index 8e75007..35d58fc 100644
--- a/lisp/ox-ascii.el
+++ b/lisp/ox-ascii.el
@@ -630,7 +630,8 @@ possible.  It doesn't apply to `inlinetask' elements."
 			      org-ascii-underline)))))
 	 (and under-char
 	      (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)
   "Non-nil when ELEMENT has a caption affiliated keyword.
@@ -1704,7 +1705,7 @@ are ignored."
 	       (org-element-map table 'table-row
 		 (lambda (row)
 		   (setq max-width
-			 (max (length
+			 (max (string-width
 			       (org-export-data
 				(org-element-contents
 				 (elt (org-element-contents row) col))
@@ -1714,6 +1715,11 @@ are ignored."
 	       max-width))
 	 cache))))
 
+(defun org-ascii--string-width (str)
+  (if str
+      (string-width str)
+    0))
+
 (defun org-ascii-table-cell (table-cell contents info)
   "Transcode a TABLE-CELL object from Org to ASCII.
 CONTENTS is the cell contents.  INFO is a plist used as
@@ -1724,16 +1730,18 @@ 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 (<= (length contents) width))
-      (setq contents (concat (substring contents 0 (- width 2)) "=>")))
+    (unless (or org-ascii-table-widen-columns
+		(<= (org-ascii--string-width contents) width))
+      (setq contents (truncate-string-to-width contents width nil ?. t)))
     ;; Align contents correctly within the cell.
     (let* ((indent-tabs-mode nil)
 	   (data
 	    (when contents
 	      (org-ascii--justify-string
 	       contents width
-	       (org-export-table-cell-alignment table-cell info)))))
-      (setq contents (concat data (make-string (- width (length data)) ? ))))
+	       (org-export-table-cell-alignment table-cell info))))
+	   (trailing-space (make-string (- width (org-ascii--string-width data)) ? )))
+      (setq contents (concat data trailing-space)))
     ;; Return cell.
     (concat (format " %s " contents)
 	    (when (memq 'right (org-export-table-cell-borders table-cell info))

             reply	other threads:[~2013-11-10 10:58 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-10 10:40 Yasushi SHOJI [this message]
2013-11-10 13:09 ` [RFC] ox-ascii.el: fixing variable width character handling Nicolas Goaziou
2014-01-03  7:55   ` Yasushi SHOJI
2014-01-03  9:34     ` Nicolas Goaziou
2014-01-04 11:18       ` Yasushi SHOJI
2014-01-04 19:34         ` Nicolas Goaziou
2014-01-16 15:25         ` Nicolas Goaziou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zjpcsfoq.wl@dns1.atmark-techno.com \
    --to=yashi@atmark-techno.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).