Multiline string literal improvements
Biotronic
simen.kjaras at gmail.com
Fri Oct 13 07:59:36 UTC 2017
On Tuesday, 10 October 2017 at 22:16:00 UTC, sarn wrote:
> On Tuesday, 10 October 2017 at 21:38:41 UTC, captaindet wrote:
>>> string a = |q{
>>> firstLine();
>>> if (cond) {
>>> secondLine()
>>> }
>>> };
>>
>> you could write your own string processing function according
>> to your needs
>
> FWIW, that's the solution in Python:
> https://docs.python.org/release/3.6.3/library/textwrap.html#textwrap.dedent
>
> Works even better in D because it can run at compile time.
D version that works in CTFE:
import std.ascii : newline;
string dedent(string s, string newline = newline) {
import std.string : strip, splitLines, front, join;
import std.uni : isWhite;
import std.array : array;
import std.algorithm : until, startsWith;
auto lines = s.strip().splitLines();
if (lines.length == 0) return "";
if (lines.length == 1) return lines[0];
auto whitespace = lines[1].until!(a => !a.isWhite).array;
foreach (ref line; lines) {
if (line.startsWith(whitespace)) {
line = line[whitespace.length..$];
}
// Throw if line doesn't start with correct amount of
whitespace?
}
return lines.join(newline);
} unittest {
assert(dedent("a") == "a");
assert(dedent("a\n a") == "a"~newline~"a");
string a = q{
firstLine();
if (cond) {
secondLine();
}
};
string b = "firstLine();"~newline~"if (cond) {"~newline~"
secondLine();"~newline~"}";
assert(a.dedent == b);
}
template dedent(string s, string newline = newline) {
enum dedent = .dedent(s, newline);
} unittest {
assert(dedent!("a\n a", "\n") == "a\na");
}
Treats all whitespace the same ('\t' == ' ' == MONGOLIAN VOWEL
SEPARATOR), which might not be optimal, but I'm not gonna touch
that can of worms.
--
Biotronic
More information about the Digitalmars-d
mailing list