diff options
author | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2019-05-30 14:59:10 +0200 |
---|---|---|
committer | Nicolas Goaziou <mail@nicolasgoaziou.fr> | 2019-05-30 14:59:10 +0200 |
commit | 967801e2b8427c734de40b38569801c22f7210f7 (patch) | |
tree | 759ab7139c76ffea624ec70bc6fc909267662d62 | |
parent | 24555a0c009a6fd24427109c881049ff73c096c3 (diff) | |
download | org-mode-967801e2b8427c734de40b38569801c22f7210f7.tar.gz |
ox: Make `org-export-table-cell-width' more robust
* lisp/ox.el (org-export-table-cell-width): Make
`org-export-table-cell-width' robust against malformed tables.
Reported-by: michael <m.schoenwaelder@posteo.de>
<http://lists.gnu.org/r/emacs-orgmode/2019-05/msg00215.html>
-rw-r--r-- | lisp/ox.el | 46 | ||||
-rw-r--r-- | testing/lisp/test-ox.el | 45 |
2 files changed, 46 insertions, 45 deletions
@@ -4916,26 +4916,32 @@ same column as TABLE-CELL, or nil." (plist-put info :table-cell-width-cache table) table))) (width-vector (or (gethash table cache) - (puthash table (make-vector columns 'empty) cache))) - (value (aref width-vector column))) - (if (not (eq value 'empty)) value - (let (cookie-width) - (dolist (row (org-element-contents table) - (aset width-vector column cookie-width)) - (when (org-export-table-row-is-special-p row info) - ;; In a special row, try to find a width cookie at COLUMN. - (let* ((value (org-element-contents - (elt (org-element-contents row) column))) - (cookie (car value))) - ;; The following checks avoid expanding unnecessarily - ;; the cell with `org-export-data'. - (when (and value - (not (cdr value)) - (stringp cookie) - (string-match "\\`<[lrc]?\\([0-9]+\\)?>\\'" cookie) - (match-string 1 cookie)) - (setq cookie-width - (string-to-number (match-string 1 cookie))))))))))) + (puthash table (make-vector columns 'empty) cache)))) + ;; Table may not have the same number of rows. Extend + ;; WIDTH-VECTOR appropriately if we encounter a row larger than + ;; expected. + (when (>= column (length width-vector)) + (setq width-vector + (vconcat width-vector + (make-list (- (1+ column) (length width-vector)) + 'empty))) + (puthash table width-vector cache)) + (pcase (aref width-vector column) + (`empty + (catch 'found + (dolist (row (org-element-contents table)) + (when (org-export-table-row-is-special-p row info) + ;; In a special row, try to find a width cookie at + ;; COLUMN. The following checks avoid expanding + ;; unnecessarily the cell with `org-export-data'. + (pcase (org-element-contents + (elt (org-element-contents row) column)) + (`(,(and (pred stringp) cookie)) + (when (string-match "\\`<[lrc]?\\([0-9]+\\)>\\'" cookie) + (let ((w (string-to-number (match-string 1 cookie)))) + (throw 'found (aset width-vector column w)))))))) + (aset width-vector column nil))) + (value value)))) (defun org-export-table-cell-alignment (table-cell info) "Return TABLE-CELL contents alignment. diff --git a/testing/lisp/test-ox.el b/testing/lisp/test-ox.el index 3bd2622..71a70bf 100644 --- a/testing/lisp/test-ox.el +++ b/testing/lisp/test-ox.el @@ -4148,33 +4148,28 @@ Another text. (ref:text) (ert-deftest test-org-export/table-cell-width () "Test `org-export-table-cell-width' specifications." - ;; 1. Width is primarily determined by width cookies. If no cookie - ;; is found, cell's width is nil. - (org-test-with-parsed-data " + ;; Width is primarily determined by width cookies. If no cookie is + ;; found, cell's width is nil. + (should + (equal '(nil 6 7) + (org-test-with-parsed-data " | / | <l> | <6> | <l7> | | | a | b | c |" - (should - (equal - '(nil 6 7) - (mapcar (lambda (cell) (org-export-table-cell-width cell info)) - (org-element-map tree 'table-cell 'identity info))))) - ;; 2. The last width cookie has precedence. - (org-test-with-parsed-data " -| <6> | -| <7> | -| a |" - (should - (equal - '(7) - (mapcar (lambda (cell) (org-export-table-cell-width cell info)) - (org-element-map tree 'table-cell 'identity info))))) - ;; 3. Valid width cookies must have a specific row. - (org-test-with-parsed-data "| <6> | cell |" - (should - (equal - '(nil nil) - (mapcar (lambda (cell) (org-export-table-cell-width cell info)) - (org-element-map tree 'table-cell 'identity)))))) + (mapcar (lambda (cell) (org-export-table-cell-width cell info)) + (org-element-map tree 'table-cell 'identity info))))) + ;; Valid width cookies must have a specific row. + (should + (equal '(nil nil) + (org-test-with-parsed-data "| <6> | cell |" + (mapcar (lambda (cell) (org-export-table-cell-width cell info)) + (org-element-map tree 'table-cell 'identity))))) + ;; Do not error on malformed tables. + (should + (org-test-with-parsed-data " +| a | +| b | c |" + (mapcar (lambda (cell) (org-export-table-cell-width cell info)) + (org-element-map tree 'table-cell 'identity info))))) (ert-deftest test-org-export/table-cell-alignment () "Test `org-export-table-cell-alignment' specifications." |