[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: configure separator in org-table-insert-hline

From: Vladimir Alexiev
Subject: Re: configure separator in org-table-insert-hline
Date: Fri, 21 Aug 2020 12:34:33 +0300

> That will not work without changing Org syntax. Markdown and Org table are incompatible.  

I guess you're right re support for formulas, table export, table input/output from code, etc.
But I don't expect any of that of Markdown tables. 
All I expect is that I can use table editing and alignment, and have proper markdown hlines.

Here's some code that works for me.
It overwrites 2 org table functions, changing just one line (see "FIXED").
Would be nice if this can be adopted in org; of course with a proper option etc.


;; Make org table minor mode (orgtbl-mode) support "|" as hline separator in markdown

(add-hook 'orgtbl-mode-hook
          (defun my-orgtbl-mode-hook ()
            (set (make-local-variable 'org-table-hline-separator)
                 (if (memq major-mode '(markdown-mode gfm-mode))
                     "|" "+"))))

(eval-after-load "org" '(fset 'org-table-align 'my-org-table-align))
(eval-after-load "org-table" '(fset 'org-table-insert-hline 'my-org-table-insert-hline))
(defun my-org-table-align ()
  "Align the table at point by aligning all vertical bars."
  (let ((beg (org-table-begin))
(end (copy-marker (org-table-end))))
     ;; Make sure invisible characters in the table are at the right
     ;; place since column widths take them into account.
     (org-font-lock-ensure beg end)
     (move-marker org-table-aligned-begin-marker beg)
     (move-marker org-table-aligned-end-marker end)
     (goto-char beg)
      (let* ((indent (progn (looking-at "[ \t]*") (match-string 0)))
    ;; Table's rows as lists of fields.  Rules are replaced
    ;; by nil.  Trailing spaces are removed.
    (fields (mapcar
     (lambda (l)
(and (not (string-match-p org-table-hline-regexp l))
    (org-split-string l "[ \t]*|[ \t]*")))
     (split-string (buffer-substring beg end) "\n" t)))
    ;; Compute number of columns.  If the table contains no
    ;; field, create a default table and bail out.
     (if fields (apply #'max (mapcar #'length fields))
(kill-region beg end)
(org-table-create org-table-default-size)
(user-error "Empty table - created default table")))
    (widths nil)
    (alignments nil))
;; Compute alignment and width for each column.
(dotimes (i columns-number)
 (let* ((max-width 1)
(fixed-align? nil)
(numbers 0)
(non-empty 0))
   (dolist (row fields)
     (let ((cell (or (nth i row) "")))
(setq max-width (max max-width (org-string-width cell)))
(cond (fixed-align? nil)
     ((equal cell "") nil)
     ((string-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
      (setq fixed-align? (match-string 1 cell)))
      (cl-incf non-empty)
      (when (string-match-p org-table-number-regexp cell)
(cl-incf numbers))))))
   (push max-width widths)
   (push (cond
  ((>= numbers (* org-table-number-fraction non-empty)) "r")
  (t "l"))
(setq widths (nreverse widths))
(setq alignments (nreverse alignments))
;; Store alignment of this table, for later editing of single
;; fields.
(setq org-table-last-alignment alignments)
(setq org-table-last-column-widths widths)
;; Build new table rows.  Only replace rows that actually
;; changed.
(dolist (row fields)
 (let ((previous (buffer-substring (point) (line-end-position)))
(format "%s|%s|"
(if (null row) ;horizontal rule
    (mapconcat (lambda (w) (make-string (+ 2 w) ?-))
org-table-hline-separator) ;; FIXED
  (let ((cells ;add missing fields
 (append row
 (make-list (- columns-number
(length row))
    (mapconcat #'identity
(cl-mapcar #'org-table--align-field
   (if (equal new previous)
     (insert new "\n")
     (delete-region (point) (line-beginning-position 2)))))
(set-marker end nil)
(when org-table-overlay-coordinates (org-table-overlay-coordinates))
(setq org-table-may-need-update nil))))))

(defun my-org-table-insert-hline (&optional above)
  "Insert a horizontal-line below the current line into the table.
With prefix ABOVE, insert above the current line."
  (interactive "P")
  (unless (org-at-table-p) (user-error "Not at a table"))
  (when (eobp) (save-excursion (insert "\n")))
  (unless (string-match-p "|[ \t]*$" (org-current-line-string))
   (let ((line (org-table-clean-line
(buffer-substring (point-at-bol) (point-at-eol))))
(col (current-column)))
     (while (string-match "|\\( +\\)|" line)
       (setq line (replace-match
  (concat org-table-hline-separator ;; FIXED
                           (make-string (- (match-end 1) (match-beginning 1)) ?-)
                           "|") t t line)))
     (and (string-match "\\+" line) (setq line (replace-match "|" t t line)))
     (beginning-of-line (if above 1 2))
     (insert line "\n")
     (beginning-of-line (if above 1 -1))
     (org-move-to-column col)
     (when org-table-overlay-coordinates (org-table-align)))))

reply via email to

[Prev in Thread] Current Thread [Next in Thread]