diff options
author | Thijs Schreijer <thijs@thijsschreijer.nl> | 2022-01-02 11:49:23 +0300 |
---|---|---|
committer | Thijs Schreijer <thijs@thijsschreijer.nl> | 2022-01-03 11:07:32 +0300 |
commit | a9fe87952a4986388e1ca02940302cc06c71eb69 (patch) | |
tree | dbfe3aede8fc588436b5aff57321b5a6c2ac9f22 | |
parent | 1cff8458f90472aa62c176c9e52e1a1eea75ff51 (diff) |
fix(text) dedent now handles declining indents and empty lines
Also adds two tests for indent/dedent regaring newlines added
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | lua/pl/text.lua | 34 | ||||
-rw-r--r-- | spec/text_spec.lua | 26 |
3 files changed, 58 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ae62df..c21a1a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ see [CONTRIBUTING.md](CONTRIBUTING.md#release-instructions-for-a-new-version) fo [#387](https://github.com/lunarmodules/Penlight/pull/387) - fix: `xml.maptags` would hang if it encountered text-nodes [#396](https://github.com/lunarmodules/Penlight/pull/396) + - fix: `text.dedent` didn't handle declining indents nor empty lines + [#402](https://github.com/lunarmodules/Penlight/pull/402) ## 1.11.0 (2021-08-18) diff --git a/lua/pl/text.lua b/lua/pl/text.lua index 1ebdd29..35232c8 100644 --- a/lua/pl/text.lua +++ b/lua/pl/text.lua @@ -52,14 +52,40 @@ end --- dedent a multiline string by removing any initial indent. -- useful when working with [[..]] strings. +-- Empty lines are ignored. -- @tparam string s the (multiline) string -- @return a string with initial indent zero. +-- @usage +-- local s = dedent [[ +-- One +-- +-- Two +-- +-- Three +-- ]] +-- assert(s == [[ +-- One +-- +-- Two +-- +-- Three +-- ]]) function text.dedent (s) assert_arg(1,s,'string') - local sl = split(s,'\n') - local _,i2 = (#sl>0 and sl[1] or ''):find('^%s*') - sl = imap(string.sub,sl,i2+1) - return concat(sl,'\n')..'\n' + local lst = split(s,'\n') + if #lst>0 then + local ind_size = math.huge + for i, line in ipairs(lst) do + local i1, i2 = lst[i]:find('^%s*[^%s]') + if i1 and i2 < ind_size then + ind_size = i2 + end + end + for i, line in ipairs(lst) do + lst[i] = lst[i]:sub(ind_size, -1) + end + end + return concat(lst,'\n')..'\n' end --- format a paragraph into lines so that they fit into a line width. diff --git a/spec/text_spec.lua b/spec/text_spec.lua index d50624f..095afb8 100644 --- a/spec/text_spec.lua +++ b/spec/text_spec.lua @@ -66,6 +66,11 @@ end ]], text.indent("easy\n\nenough!", 2 ,'*')) end) + it("indent() appends a newline if not present", function() + assert.equal(" hello\n world\n", text.indent("hello\nworld", 2)) + assert.equal(" hello\n world\n", text.indent("hello\nworld\n", 2)) + end) + it("dedent() removes prefixed whitespace", function() assert.equal([[ @@ -79,6 +84,27 @@ three ]]) end) + it("dedent() removes prefixed whitespace, retains structure", function() + assert.equal([[ + one + + two + +three +]], text.dedent [[ + one + + two + + three +]]) + end) + + it("dedent() appends a newline if not present", function() + assert.equal("hello\nworld\n", text.dedent(" hello\n world")) + assert.equal("hello\nworld\n", text.dedent(" hello\n world\n")) + end) + it("fill()/wrap() word-wraps a text", function() assert.equal([[ |