From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp2 ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms11 with LMTPS id eDcNG1WVP1+qHAAA0tVLHw (envelope-from ) for ; Fri, 21 Aug 2020 09:35:17 +0000 Received: from aspmx1.migadu.com ([2001:41d0:2:4a6f::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp2 with LMTPS id ABYZF1WVP19aDAAAB5/wlQ (envelope-from ) for ; Fri, 21 Aug 2020 09:35:17 +0000 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 9230D940414 for ; Fri, 21 Aug 2020 09:35:16 +0000 (UTC) Received: from localhost ([::1]:53004 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1k93S6-0003Zo-E1 for larch@yhetil.org; Fri, 21 Aug 2020 05:35:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49774) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1k93Rh-0003ZP-0a for emacs-orgmode@gnu.org; Fri, 21 Aug 2020 05:34:49 -0400 Received: from mail-ot1-x32c.google.com ([2607:f8b0:4864:20::32c]:46781) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1k93Re-0003vK-HE for emacs-orgmode@gnu.org; Fri, 21 Aug 2020 05:34:48 -0400 Received: by mail-ot1-x32c.google.com with SMTP id v6so1073219ota.13 for ; Fri, 21 Aug 2020 02:34:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ontotext.com; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=s/dYiSYkluPmZpsKoE7QHgB8W4TSO3A6O4Wz3i5hOyU=; b=kHqFua8GDgYA0rFbSrXFXc54rkgrDWcp9eWMrBLIftw2tQmC+S2Ea4hoMMuI/HeTP5 K0BH0FBqIaC2CinqXME580GXZC+m4SxLP2LEogCrVmSPLvAgXYh1L9Scnf9b+w+zBjja OwL8MENRkH/DeEejGgjr0/WTdrZnZG6OxZQVQJvDWcnyAZuOkINsAuwoBTfAO+JbvMZt fubmq4Vn8UAsD0DgGqayWViJiFiD75Ckq7rkwEKrZ1g5F9sb8FYPae0Wf+/+6G74jhgg QE7QLjIFqUUsiFRqekgDLmN6j9iaBDvwg9408nzz7EhNXoTewc6lmJ0N0et9pdnsG6bG lwew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=s/dYiSYkluPmZpsKoE7QHgB8W4TSO3A6O4Wz3i5hOyU=; b=LRTEVEaRUA8uj0zahxqGHKuCCx2weNWMJuP8507C4SYneSGeBpRUczDO7/nH33pT4H KQoDb/NsNdEMQuSsrpfN2OcUTBQ5SBMyGgi8O8J/hiIG9siD90z8NSNMIp2vn9gohjQY m8+w8A3CMPDLac70oSOu++E46/dGnsGzM2vOSzVkmQV7Eql60y1RjH/4wLLlBbho3QHn DRLUVRqQOMvu39LgeZXGfjmMXvxPfgOPD1GI0eQrc0kfKBwquNnsfTotz9qbF9gsSh9C VGl35ELtT7W7sJvC6jD/iGGj7JhPII57JRe8r3JtQUj/auktPM18OpIYv+1YJ1jsJHhF pqQw== X-Gm-Message-State: AOAM530tEjpbp7fs9YPireELqCzFfIPRYzrvONZNFNuDgHsXDQyGrtV9 geTHXeW3svDPajtTfDy8XUgUrrQBY4mo1D/mlfb7gys/U2vOojzS X-Google-Smtp-Source: ABdhPJys4idv0vmb6ioZ2WKPrwnd9PofvHEIICv9TRftXYgdsxfI0Nf2Qpgfu28C3LGMjNF9oLItQWBu/NP3mJ75LLM= X-Received: by 2002:a05:6830:1456:: with SMTP id w22mr1284082otp.336.1598002483991; Fri, 21 Aug 2020 02:34:43 -0700 (PDT) MIME-Version: 1.0 References: <87wo1scqer.fsf@nicolasgoaziou.fr> In-Reply-To: <87wo1scqer.fsf@nicolasgoaziou.fr> From: Vladimir Alexiev Date: Fri, 21 Aug 2020 12:34:33 +0300 Message-ID: Subject: Re: configure separator in org-table-insert-hline To: emacs-orgmode@gnu.org Content-Type: multipart/alternative; boundary="00000000000068ad5405ad5ff287" Received-SPF: softfail client-ip=2607:f8b0:4864:20::32c; envelope-from=vladimir.alexiev@ontotext.com; helo=mail-ot1-x32c.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -13 X-Spam_score: -1.4 X-Spam_bar: - X-Spam_report: (-1.4 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_SOFTFAIL=0.665, URIBL_BLOCKED=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Scanner: scn0 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=ontotext.com header.s=google header.b=kHqFua8G; dmarc=none; spf=pass (aspmx1.migadu.com: domain of emacs-orgmode-bounces@gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=emacs-orgmode-bounces@gnu.org X-Spam-Score: -1.21 X-TUID: RFnk046jNYAS --00000000000068ad5405ad5ff287 Content-Type: text/plain; charset="UTF-8" > 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. Cheers! ;; 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." (interactive) (let ((beg (org-table-begin)) (end (copy-marker (org-table-end)))) (org-table-save-field ;; 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) (org-table-with-shrunk-columns (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. (columns-number (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))) (t (cl-incf non-empty) (when (string-match-p org-table-number-regexp cell) (cl-incf numbers)))))) (push max-width widths) (push (cond (fixed-align?) ((>= numbers (* org-table-number-fraction non-empty)) "r") (t "l")) alignments))) (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))) (new (format "%s|%s|" indent (if (null row) ;horizontal rule (mapconcat (lambda (w) (make-string (+ 2 w) ?-)) widths 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 cells widths alignments) "|")))))) (if (equal new previous) (forward-line) (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)) (org-table-align)) (org-table-with-shrunk-columns (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))))) --00000000000068ad5405ad5ff287 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
> That will not work without changing = Org syntax. Markdown and Org table are incompatible.=C2=A0=C2=A0
<= div dir=3D"ltr">
I guess you're right re support for form= ulas, table export, table input/output from code, etc.
But I don&= #39;t expect any of that of Markdown tables.=C2=A0
All I expect i= s that I can use table editing and alignment, and have proper markdown hlin= es.

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

Cheers!

;; Make org table minor= mode (orgtbl-mode) support "|" as hline separator in markdown
(add-hook 'orgtbl-mode-hook
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = (defun my-orgtbl-mode-hook ()
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = (set (make-local-variable 'org-table-hline-separator)
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(if (memq major-mode '(= markdown-mode gfm-mode))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"|" "+"))))

(eval= -after-load "org" '(fset 'org-table-align 'my-org-tab= le-align))
(eval-after-load "org-table" '(fset 'org-ta= ble-insert-hline 'my-org-table-insert-hline))
=C2=A0
(defun my-o= rg-table-align ()
=C2=A0 "Align the table at point by aligning all = vertical bars."
=C2=A0 (interactive)
=C2=A0 (let ((beg (org-tabl= e-begin))
(end (copy-marker (org-table-end))))
=C2=A0 =C2=A0 (org-ta= ble-save-field
=C2=A0 =C2=A0 =C2=A0;; Make sure invisible characters in = the table are at the right
=C2=A0 =C2=A0 =C2=A0;; place since column wid= ths take them into account.
=C2=A0 =C2=A0 =C2=A0(org-font-lock-ensure be= g end)
=C2=A0 =C2=A0 =C2=A0(move-marker org-table-aligned-begin-marker b= eg)
=C2=A0 =C2=A0 =C2=A0(move-marker org-table-aligned-end-marker end)=C2=A0 =C2=A0 =C2=A0(goto-char beg)
=C2=A0 =C2=A0 =C2=A0(org-table-wit= h-shrunk-columns
=C2=A0 =C2=A0 =C2=A0 (let* ((indent (progn (looking-at = "[ \t]*") (match-string 0)))
=C2=A0 =C2=A0 ;; Table's ro= ws as lists of fields.=C2=A0 Rules are replaced
=C2=A0 =C2=A0 ;; by ni= l.=C2=A0 Trailing spaces are removed.
=C2=A0 =C2=A0 (fields (mapcar =C2=A0 =C2=A0 =C2=A0(lambda (l)
(and (not (string-match-p org-tab= le-hline-regexp l))
=C2=A0 =C2=A0 (org-split-string l "[ \t]*|[= \t]*")))
=C2=A0 =C2=A0 =C2=A0(split-string (buffer-substring be= g end) "\n" t)))
=C2=A0 =C2=A0 ;; Compute number of columns.= =C2=A0 If the table contains no
=C2=A0 =C2=A0 ;; field, create a defau= lt table and bail out.
=C2=A0 =C2=A0 (columns-number
=C2=A0 =C2= =A0 =C2=A0(if fields (apply #'max (mapcar #'length fields))
(k= ill-region beg end)
(org-table-create org-table-default-size)
(us= er-error "Empty table - created default table")))
=C2=A0 =C2= =A0 (widths nil)
=C2=A0 =C2=A0 (alignments nil))
;; Compute alignm= ent and width for each column.
(dotimes (i columns-number)
=C2=A0(= let* ((max-width 1)
(fixed-align? nil)
(numbers 0)
(non-e= mpty 0))
=C2=A0 =C2=A0(dolist (row fields)
=C2=A0 =C2=A0 =C2=A0(l= et ((cell (or (nth i row) "")))
(setq max-width (max max-wid= th (org-string-width cell)))
(cond (fixed-align? nil)
=C2=A0 =C2= =A0 =C2=A0((equal cell "") nil)
=C2=A0 =C2=A0 =C2=A0((strin= g-match "\\`<\\([lrc]\\)[0-9]*>\\'" cell)
=C2=A0 = =C2=A0 =C2=A0 (setq fixed-align? (match-string 1 cell)))
=C2=A0 =C2= =A0 =C2=A0(t
=C2=A0 =C2=A0 =C2=A0 (cl-incf non-empty)
=C2=A0 = =C2=A0 =C2=A0 (when (string-match-p org-table-number-regexp cell)
(c= l-incf numbers))))))
=C2=A0 =C2=A0(push max-width widths)
=C2=A0 = =C2=A0(push (cond
=C2=A0 (fixed-align?)
=C2=A0 ((>=3D number= s (* org-table-number-fraction non-empty)) "r")
=C2=A0 (t &= quot;l"))
=C2=A0alignments)))
(setq widths (nreverse widths)= )
(setq alignments (nreverse alignments))
;; Store alignment of thi= s table, for later editing of single
;; fields.
(setq org-table-las= t-alignment alignments)
(setq org-table-last-column-widths widths)
= ;; Build new table rows.=C2=A0 Only replace rows that actually
;; chang= ed.
(dolist (row fields)
=C2=A0(let ((previous (buffer-substring (= point) (line-end-position)))
(new
(format "%s|%s|"
= indent
(if (null row) ;horizontal rule
=C2=A0 =C2=A0 (map= concat (lambda (w) (make-string (+ 2 w) ?-))
widths
org-tab= le-hline-separator) ;; FIXED
=C2=A0 (let ((cells ;add missing fields=
=C2=A0(append row
=C2=A0(make-list (- columns-number
= (length row))
=C2=A0 =C2=A0 ""))))
=C2=A0 = =C2=A0 (mapconcat #'identity
(cl-mapcar #'org-table--align-= field
=C2=A0 cells
=C2=A0 widths
=C2=A0 align= ments)
"|"))))))
=C2=A0 =C2=A0(if (equal new previou= s)
(forward-line)
=C2=A0 =C2=A0 =C2=A0(insert new "\n")=
=C2=A0 =C2=A0 =C2=A0(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))))))<= br>
(defun my-org-table-insert-hline (&optional above)
=C2=A0 &qu= ot;Insert a horizontal-line below the current line into the table.
With = prefix ABOVE, insert above the current line."
=C2=A0 (interactive &= quot;P")
=C2=A0 (unless (org-at-table-p) (user-error "Not at a= table"))
=C2=A0 (when (eobp) (save-excursion (insert "\n"= ;)))
=C2=A0 (unless (string-match-p "|[ \t]*$" (org-current-li= ne-string))
=C2=A0 =C2=A0 (org-table-align))
=C2=A0 (org-table-with-s= hrunk-columns
=C2=A0 =C2=A0(let ((line (org-table-clean-line
(buffe= r-substring (point-at-bol) (point-at-eol))))
(col (current-column)))=C2=A0 =C2=A0 =C2=A0(while (string-match "|\\( +\\)|" line)
= =C2=A0 =C2=A0 =C2=A0 =C2=A0(setq line (replace-match
=C2=A0 (concat o= rg-table-hline-separator ;; FIXED
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(make-string = (- (match-end 1) (match-beginning 1)) ?-)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"= |") t t line)))
=C2=A0 =C2=A0 =C2=A0(and (string-match "\\+&qu= ot; line) (setq line (replace-match "|" t t line)))
=C2=A0 =C2= =A0 =C2=A0(beginning-of-line (if above 1 2))
=C2=A0 =C2=A0 =C2=A0(insert= line "\n")
=C2=A0 =C2=A0 =C2=A0(beginning-of-line (if above 1= -1))
=C2=A0 =C2=A0 =C2=A0(org-move-to-column col)
=C2=A0 =C2=A0 =C2= =A0(when org-table-overlay-coordinates (org-table-align)))))

<= div class=3D"gmail_quote">

<= /div> --00000000000068ad5405ad5ff287--