branch: externals/tomelr commit 3362213172237f40ff0d9aa3ddf12b4bb00a3564 Author: Kaushal Modi <kaushal.m...@gmail.com> Commit: Kaushal Modi <kaushal.m...@gmail.com>
feat: Add option for indenting multi-line strings New defvar `tomelr-indent-multi-line-strings`. --- test/all-tests.el | 1 + test/tstring.el | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tomelr.el | 34 +++++++++++++++-- 3 files changed, 143 insertions(+), 4 deletions(-) diff --git a/test/all-tests.el b/test/all-tests.el index 03f614f844..a100e46ba7 100644 --- a/test/all-tests.el +++ b/test/all-tests.el @@ -26,6 +26,7 @@ (require 'tkey) (require 'tscalar) +(require 'tstring) (require 'tnil) (require 'tarray) (require 'ttable) diff --git a/test/tstring.el b/test/tstring.el new file mode 100644 index 0000000000..0998f2efbf --- /dev/null +++ b/test/tstring.el @@ -0,0 +1,112 @@ +;; -*- lexical-binding: t; -*- + +;; Authors: Kaushal Modi <kaushal.m...@gmail.com> + +;; This file is not part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; Test TOML strings. + +;;; Code: +(require 'tomelr) + +;;;; Multi-line strings without indentation +(ert-deftest test-mls-no-indent () + (let ((tomelr-indent-multi-line-strings nil) + (inp '( + ((key . "abc\ndef")) + ((table . ((key . "abc\ndef")))) + ((table_array . (((key . "abc\ndef")) + ((key . "klm\nxyz"))))) + )) + (ref '( + "key = \"\"\" +abc +def\"\"\"" + "[table] + key = \"\"\" +abc +def\"\"\"" + "[[table_array]] + key = \"\"\" +abc +def\"\"\" +[[table_array]] + key = \"\"\" +klm +xyz\"\"\"" + )) + out) + (dolist (el inp) + (push (tomelr-encode el) out)) + (should (equal ref (nreverse out))))) + +;;;; Multi-line strings with indentation +(ert-deftest test-mls-with-indent () + (let ((tomelr-indent-multi-line-strings t) + (inp '( + ((key . "abc\ndef")) + ((table . ((key . "abc\ndef")))) + ((table_array . (((key . "abc\ndef")) + ((key . "klm\nxyz"))))) + ((table_array . (((key . "abc\n\ndef"))))) + ((table_array . (((key . "abc\n\n\ndef\n\nfoo\nbar"))))) + )) + (ref '( + "key = \"\"\" + abc + def + \"\"\"" + "[table] + key = \"\"\" + abc + def + \"\"\"" + "[[table_array]] + key = \"\"\" + abc + def + \"\"\" +[[table_array]] + key = \"\"\" + klm + xyz + \"\"\"" + "[[table_array]] + key = \"\"\" + abc + + def + \"\"\"" + "[[table_array]] + key = \"\"\" + abc + + + def + + foo + bar + \"\"\"" + )) + out) + (dolist (el inp) + (push (tomelr-encode el) out)) + (should (equal ref (nreverse out))))) + + +(provide 'tstring) diff --git a/tomelr.el b/tomelr.el index 7359edaaeb..d4d32c9b25 100644 --- a/tomelr.el +++ b/tomelr.el @@ -51,6 +51,16 @@ For example, if this list contains `boolean' and if a string value is exactly \"true\", it will coerce to TOML boolean `true'.") +(defvar tomelr-indent-multi-line-strings nil + "Indent the multi-line TOML strings when non-nil. + +This option injects spaces after each newline to present the +multi-line strings in a more readable format. + +*Note: This option should be set to non-nil only if the TOML +string data is insensitive to horizontal space. Good examples of +this would be Org, Markdown or HTML strings.") + ;;;; Internal Variables (defvar tomelr--print-indentation-prefix "\n" "String used to start indentation during encoding.") @@ -148,12 +158,13 @@ Return the same STRING passed as input." (?f . ?\f) ;U+000C (?\\ . ?\\))) (special-chars-re (rx (in ?\" ?\\ cntrl ?\u007F))) ;cntrl is same as (?\u0000 . ?\u001F) + ;; Use multi-line string quotation if the string contains a " + ;; char or a newline - """STRING""". + (multi-line (string-match-p "\n\\|\"" string)) begin-q end-q) (cond - ;; Use multi-line string quotation if the string contains a " - ;; char or a newline - """STRING""". - ((string-match-p "\n\\|\"" string) + (multi-line ;; From https://toml.io/en/v1.0.0#string, Any Unicode ;; character may be used except those that must be escaped: ;; backslash and the control characters other than tab, line @@ -164,8 +175,23 @@ Return the same STRING passed as input." ?\u000B ?\u000C (?\u000E . ?\u001F) ?\u007F))) + (setq begin-q "\"\"\"\n") - (setq end-q "\"\"\"")) + (setq end-q "\"\"\"") + (when tomelr-indent-multi-line-strings + (let ((indentation (let ((tmp "")) + (dotimes (_ (1+ tomelr--print-indentation-depth)) + (setq tmp (concat tmp tomelr-encoding-default-indentation))) + tmp))) + (setq string + (concat + indentation ;Indent the first line in the multi-line string + (replace-regexp-in-string + "\\(\n\\)\\([^\n]\\)" ;Don't indent blank lines + (format "\\1%s\\2" indentation) + string) + "\n" indentation ;Indent the closing """ at the end of the multi-line string + ))))) (t ;Basic quotation "STRING" (push '(?\" . ?\") special-chars) (push '(?t . ?\t) special-chars) ;U+0009