4

Say I have a table in an Org document looking like this: (Source)

+----------+-----------+----------+-------------------------------------------------------+
| Date     | Day       |    Pages | Content                                               |
+----------+-----------+----------+-------------------------------------------------------+
| 28 Aug   | Wednesday |  114-128 | - Freehold Society                                    |
|          |           |          | - Quakers                                             |
|          |           |          | - Early Immigrants                                    |
|          |           |          | - Religious Beliefs                                   |
|          |           |          | - Enlightenment in America                            |
+----------+-----------+----------+-------------------------------------------------------+
| 29 Aug   | Thursday  |  129-135 | - Great Awakening                                     |
|          |           |          | - Whitefield                                          |
|          |           |          | - Edwards                                             |
|          |           |          | - Old Lights                                          |
|          |           |          | - New Lights                                          |
+----------+-----------+----------+-------------------------------------------------------+
| 30 Aug   | Friday    |  135-140 | - French & Indian War                                 |
|          |           |          | - Pontiac's Uprising                                  |
|          |           |          | - Albany Plan of the Union                            |
|          |           |          | - Treaty of Paris (1763)                              |
+----------+-----------+----------+-------------------------------------------------------+
| 2 Sep    | Monday    |  140-143 | - Paxton Boys                                         |
|          |           |          | - Regulators                                          |
|          |           |          | - results of the French and Indian War                |
+----------+-----------+----------+-------------------------------------------------------+
| 3 Sep    | Tuesday   |  152-160 | - Proclamation of 1763                                |
|          |           |          | - Sugar Act                                           |
|          |           |          | - Stamp Act                                           |
|          |           |          | - Stamp Act Congress                                  |
|          |           |          | - Quartering Act                                      |
|          |           |          | - Sons of Liberty                                     |
|          |           |          | - Ideological Differences (3 total)                   |
|          |           |          | - John Dickinson                                      |
+----------+-----------+----------+-------------------------------------------------------+
| 4 Sep    | Wednesday |  160-167 | - Declatory Act                                       |
|          |           |          | - Townshend Acts                                      |
|          |           |          | - Sons of Liberty                                     |
|          |           |          | - Daughters of Liberty                                |
|          |           |          | - Boston Massacre                                     |
+----------+-----------+----------+-------------------------------------------------------+
| 5 Sep    | Thursday  |  168-179 | - Committees of correspondence                        |
|          |           |          | - Tea Act                                             |
|          |           |          | - Boston Tea Party                                    |
|          |           |          | - Intolerable or Coercive Acts                        |
|          |           |          | - Quebec Act                                          |
|          |           |          | - First Contintental Congress                         |
|          |           |          | - Loyalists                                           |
|          |           |          | - Olive Branch Petition                               |
|          |           |          | - Proclamation for Suppressing Rebellion and Sedition |
|          |           |          | - Prohibitory Act                                     |
|          |           |          | - /Common Sense/                                      |
|          |           |          | - Declaration of Independence                         |
+----------+-----------+----------+-------------------------------------------------------+

I'd expect the right most cells to become lists when exported, and in the case of Common Sense to format as italics. However, the table content gets exported as plaintext with a ton of no-break-spaces. (HTML Output)

How do I fix this so that these tables are properly exported with formatting?

Aly
  • 83
  • 10

1 Answers1

3

The following Elisp code modifies the html export backend so that it accepts an additional option HTML_TABLEEL_ORG. If you set this option to t or yes table cells in table.el-tables are rendered as org-mode strings.

You can copy the code into your init file if the first line of your init file contains the file-local setting lexical-binding: t as demonstrated in the code snippet. If you do not want to evaluate your init file with lexical binding you can copy-paste the code inclusively the first comment line into some new Elisp file in your load-path and require that file in your init file.

;; -*- lexical-binding: t -*-

(defcustom org-html-tableel-org "no"
  "Export table.el cells as org code if set to \"t\" or \"yes\".
This is the default and can be changed per section with export option:
#+OPTIONS: HTML_TABLEEL_ORG: t"
  :type '(choice (const "no") (const "yes"))
  :group 'org-html)

(eval-after-load 'ox-html
  '(eval ;;< Avoid eager macro expansion before ox-html is loaded.
    '(cl-pushnew
      (list
       :html-tableel-org
       "HTML_TABLEEL_ORG" ;; keyword
       "html-tableel-org";; option for #+OPTIONS: line
       org-html-tableel-org ;; default value for the property
       t ;; handling of multiple keywords for the same property. (Replace old value with new one.)
       )
      (org-export-backend-options (org-export-get-backend 'html)))))

(defvar org-element-all-elements) ;; defined in "org-element"
(defun table-generate-orghtml-cell-contents (dest-buffer language cell info)
  "Generate and insert source cell contents of a CELL into DEST-BUFFER.
LANGUAGE must be 'orghtml."
  (cl-assert (eq language 'html) nil
             "Table cells with org content only working with html export")
  (let* ((cell-contents (extract-rectangle (car cell) (cdr cell)))
         (string (with-temp-buffer
                   (table--insert-rectangle cell-contents)
                   (table--remove-cell-properties (point-min) (point-max))
                   (goto-char (point-min))
                   (buffer-substring (point-min) (point-max)))))
    (with-current-buffer dest-buffer
      (let ((beg (point)))
        (insert (org-export-string-as string 'html t info))
        (indent-rigidly beg (point) 6)))))

(defun org-orghtml-table--table.el-table (fun table info)
  "Format table.el TABLE into HTML.
This is an advice for `org-html-table--table.el-table' as FUN.
INFO is a plist used as a communication channel."
  (if (assoc-string (plist-get info :html-tableel-org) '("t" "yes"))
      (cl-letf (((symbol-function 'table--generate-source-cell-contents)
                 (lambda (dest-buffer language cell)
                   (table-generate-orghtml-cell-contents dest-buffer language cell info))))
        (funcall fun table info))
    (funcall fun table info)))

(advice-add #'org-html-table--table.el-table :around #'org-orghtml-table--table.el-table)

The following reduced example demonstrates the usage:

#+HTML_HEAD_EXTRA: <style type="text/css"> td { padding: 0px 10px 0px 10px } </style>
#+OPTIONS: html-tableel-org:t
+----------+-----------+----------+-------------------------------------------------------+
| Date     | Day       |    Pages | Content                                               |
+----------+-----------+----------+-------------------------------------------------------+
| 28 Aug   | Wednesday |  114-128 | - Freehold Society                                    |
|          |           |          | - Quakers                                             |
|          |           |          | - Early Immigrants                                    |
|          |           |          | - Religious Beliefs                                   |
|          |           |          | - Enlightenment in *America*                          |
+----------+-----------+----------+-------------------------------------------------------+
| 29 Aug   | Thursday  |  129-135 | - Great Awakening                                     |
|          |           |          | - /Whitefield/                                        |
|          |           |          | - Edwards                                             |
+----------+-----------+----------+-------------------------------------------------------+

The exported html rendered by firefox:

Table.el rendered in Firefox

Tested with:

emacs-version: GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2019-09-16

table.el version: built-in

org-version: Org mode version 9.2.6

Tobias
  • 32,569
  • 1
  • 34
  • 75
  • How do I set this by default to `yes`? I assume just change the 2nd argument of `defcustom`? – Aly Nov 09 '19 at 19:31
  • @Soren There was a small bug in the backend options. I changed the widget type of `org-html-tableel-org` and replaced `nil` with `org-html-tableel-org ` in the `with-eval-after-load "ox-html"` form. If you adopt these changes you can customize the option `org-html-tableel-org` to `t` to export table.el tables with org code in cells by default. – Tobias Nov 09 '19 at 21:22
  • I'm getting the error: `Symbol's function definition is void: \(setf\ org-export-backend-options\)`. I saw you fixed this in one of your other Org questions, but I don't know how. See: https://gitlab.com/srnb/notes/-/jobs/457016698 – Aly Mar 03 '20 at 05:08
  • @Soren After the cause of the problem has been clarified in [the answer to my question about `with-eval-after-load` and `cl-pushnew`](https://emacs.stackexchange.com/q/55903/2370) I have corrected the code in this answer. It should run like expected now. – Tobias Mar 04 '20 at 07:09