This commit is contained in:
Dominik Picheta
2016-04-04 13:39:42 +01:00
parent 436b003173
commit 73e48f9c9c
2 changed files with 66 additions and 27 deletions

View File

@@ -784,8 +784,7 @@ proc indent*(s: string, count: Natural, padding: string = " "): string
{.noSideEffect, rtl, extern: "nsuIndent".} = {.noSideEffect, rtl, extern: "nsuIndent".} =
## Indents each line in ``s`` by ``count`` amount of ``padding``. ## Indents each line in ``s`` by ``count`` amount of ``padding``.
## ##
## **Note:** This currently does not preserve the specific new line characters ## **Note:** This does not preserve the new line characters used in ``s``.
## used.
result = "" result = ""
var i = 0 var i = 0
for line in s.splitLines(): for line in s.splitLines():
@@ -796,32 +795,39 @@ proc indent*(s: string, count: Natural, padding: string = " "): string
result.add(line) result.add(line)
i.inc i.inc
proc unindent*(s: string, eatAllIndent = false): string {. proc unindent*(s: string, count: Natural, padding: string = " "): string
noSideEffect, rtl, extern: "nsuUnindent".} = {.noSideEffect, rtl, extern: "nsuUnindent".} =
## Unindents `s`. ## Unindents each line in ``s`` by ``count`` amount of ``padding``.
result = newStringOfCap(s.len) ##
## **Note:** This does not preserve the new line characters used in ``s``.
result = ""
var i = 0 var i = 0
var pattern = true for line in s.splitLines():
var indent = 0 if i != 0:
while s[i] == ' ': inc i result.add("\n")
var level = if i == 0: -1 else: i var indentCount = 0
while i < s.len: for j in 0..<count.int:
if s[i] == ' ': indentCount.inc
if i > 0 and s[i-1] in {'\l', '\c'}: if line[j .. j + <padding.len] != padding:
pattern = true indentCount = j
indent = 0 break
if pattern: result.add(line[indentCount*padding.len .. ^1])
inc(indent) i.inc
if indent > level and not eatAllIndent:
result.add(s[i]) proc unindent*(s: string): string
if level < 0: level = indent {.noSideEffect, rtl, extern: "nsuUnindentAll".} =
else: ## Removes all indentation composed of whitespace from each line in ``s``.
# a space somewhere: do not delete ##
result.add(s[i]) ## For example:
else: ##
pattern = false ## .. code-block:: nim
result.add(s[i]) ## const x = """
inc i ## Hello
## There
## """.unindent()
##
## doAssert x == "Hello\nThere\n"
unindent(s, 1000) # TODO: Passing a 1000 is a bit hackish.
proc startsWith*(s, prefix: string): bool {.noSideEffect, proc startsWith*(s, prefix: string): bool {.noSideEffect,
rtl, extern: "nsuStartsWith".} = rtl, extern: "nsuStartsWith".} =
@@ -1743,3 +1749,33 @@ when isMainModule:
doAssert join(@["foo", "bar", "baz"], ", ") == "foo, bar, baz" doAssert join(@["foo", "bar", "baz"], ", ") == "foo, bar, baz"
doAssert join([1, 2, 3]) == "123" doAssert join([1, 2, 3]) == "123"
doAssert join(@[1, 2, 3], ", ") == "1, 2, 3" doAssert join(@[1, 2, 3], ", ") == "1, 2, 3"
doAssert """~~!!foo
~~!!bar
~~!!baz""".unindent(2, "~~!!") == "foo\nbar\nbaz"
doAssert """~~!!foo
~~!!bar
~~!!baz""".unindent(2, "~~!!aa") == "~~!!foo\n~~!!bar\n~~!!baz"
doAssert """~~foo
~~ bar
~~ baz""".unindent(4, "~") == "foo\n bar\n baz"
doAssert """foo
bar
baz
""".unindent(4) == "foo\nbar\nbaz\n"
doAssert """foo
bar
baz
""".unindent(2) == "foo\n bar\n baz\n"
doAssert """foo
bar
baz
""".unindent(100) == "foo\nbar\nbaz\n"
doAssert """foo
foo
bar
""".unindent() == "foo\nfoo\nbar\n"
echo("strutils tests passed")

View File

@@ -23,6 +23,9 @@ Changes affecting backwards compatibility
- Procedures in ``mersenne.nim`` (Mersenne Twister implementation) no longer - Procedures in ``mersenne.nim`` (Mersenne Twister implementation) no longer
accept and produce ``int`` values which have platform-dependent size - accept and produce ``int`` values which have platform-dependent size -
they use ``uint32`` instead. they use ``uint32`` instead.
- The ``strutils.unindent`` procedure has been rewritten. Its parameters now
match the parameters of ``strutils.indent``. See issue [#4037](https://github.com/nim-lang/Nim/issues/4037)
for more details.
Library Additions Library Additions