Добавлена функция std::stripMargin

This commit is contained in:
Victor 2019-04-12 23:09:34 +03:00
parent ed164085c6
commit c6a2f71457
4 changed files with 113 additions and 0 deletions

View File

@ -133,4 +133,11 @@ sonarqube {
property "sonar.projectKey", "aNNiMON_Own-Programming-Language-Tutorial"
property "sonar.host.url", "https://sonarcloud.io"
}
}
test {
testLogging {
events "passed", "skipped", "failed"
exceptionFormat "full"
}
}

View File

@ -3,6 +3,7 @@ package com.annimon.ownlang.modules.std;
import com.annimon.ownlang.lib.Arguments;
import com.annimon.ownlang.lib.ArrayValue;
import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.StringValue;
import com.annimon.ownlang.lib.Value;
import java.io.UnsupportedEncodingException;
@ -31,4 +32,54 @@ public final class StringFunctions {
final int radix = (args.length == 2) ? args[1].asInt() : 10;
return NumberValue.of(Long.parseLong(args[0].asString(), radix));
}
static Value stripMargin(Value[] args) {
Arguments.checkOrOr(1, 2, args.length);
final String input = args[0].asString();
final String marginPrefix = (args.length == 2) ? args[1].asString() : "|";
if (!input.contains(marginPrefix)) {
return args[0];
}
final String[] lines = input.split("\\r?\\n");
// First blank line is omitted
final StringBuilder sb = new StringBuilder();
final int firstLineIndex = (isBlank(lines[0])) ? 1 : 0;
final int lastLineIndex = lines.length - 1;
int index = firstLineIndex;
while (true) {
sb.append(strip(lines[index], marginPrefix));
if (++index >= lastLineIndex) break;
sb.append('\n');
}
// Process last line
if (lastLineIndex >= (firstLineIndex + 1) && !isBlank(lines[lastLineIndex])) {
sb.append('\n').append(strip(lines[lastLineIndex], marginPrefix));
}
return new StringValue(sb.toString());
}
private static String strip(String str, String marginPrefix) {
final int nonBlankIndex = firstNonBlankIndex(str);
if (str.startsWith(marginPrefix, nonBlankIndex)) {
return str.substring(nonBlankIndex + marginPrefix.length());
} else {
return str;
}
}
private static boolean isBlank(String str) {
return firstNonBlankIndex(str) == str.length();
}
private static int firstNonBlankIndex(String str) {
final int length = str.length();
for (int index = 0; index < length; index++) {
final char ch = str.charAt(index);
if (ch != ' ' && ch != '\t' && !Character.isWhitespace(ch)) {
return index;
}
}
return length;
}
}

View File

@ -55,6 +55,7 @@ public final class std implements Module {
Functions.set("replaceFirst", new std_replacefirst());
Functions.set("parseInt", StringFunctions::parseInt);
Functions.set("parseLong", StringFunctions::parseLong);
Functions.set("stripMargin", StringFunctions::stripMargin);
// Arrays and maps
Functions.set("newarray", new std_newarray());

View File

@ -0,0 +1,54 @@
use "std"
def testStripMargin() {
testCases = [
"|abc".stripMargin(),
" |abc".stripMargin(),
"
|abc".stripMargin(),
"|abc
".stripMargin(),
"
|abc
".stripMargin(),
"abc".stripMargin(""),
"abc".stripMargin(),
"#abc".stripMargin("#"),
"| abc".stripMargin("| "),
"
| abc
".stripMargin("| "),
"xxxabc".stripMargin("xxx"),
"
xxxabc".stripMargin("xxx"),
"
xxxabc
".stripMargin("xxx")
]
for actual : testCases {
assertEquals("abc", actual)
}
}
def testStripMargin2() {
assertEquals("123\n456\n789", "123
|456
|789".stripMargin())
assertEquals("123\n456\n789", "|123
|456
|789".stripMargin())
assertEquals("123\n456\n789", "
|123
|456
|789".stripMargin())
assertEquals("123\n456\n789", "
|123
|456
|789
".stripMargin())
assertEquals("123\n456\n789", "
//123
//456
//789
".stripMargin("//"))
}