On Thursday, 31 March 2016 at 03:15:49 UTC, cy wrote:
This might be a dumb question. How do I format a string so that all the newlines print as \n and all the tabs as \t and such?

The easiest is this:

```d
import std.conv;
string str = `Hello "World"
line 2`;
writeln([str].text[2..$-2]); // Hello \"World\"\nline 2
```

I know this is an old post, but I felt this trick needed to be shared.

This takes advantage of the fact that `std.format` escapes the characters in an array of strings. So we create an array where `str` is the only element, and convert that to text. Without the `[2..$-2]` slicing the output would be `["Hello \"World\"\nline 2"]`.

A slightly more efficient implementation is
```d
string escape(string s)
{
    import std.array : appender;
    import std.format : FormatSpec, formatValue;

    FormatSpec!char f;
    auto w = appender!string;
    w.reserve(s.length);
    formatValue(w, [s], f);
    return w[][2 .. $ - 2];
}
```

And the inverse:
```d
string unescape(string s)
{
    import std.format : FormatSpec, unformatValue;

    FormatSpec!char f;
    string str = `["` ~ s ~ `"]`;
    return unformatValue!(string[])(str, f)[0];
}
```

Perhaps `escape()` and `unescape()` should be part of `std.format` so that they can be refactored to use `std.format.internal.write.formatElement` directly, eliminating the conversion to array.

-- Bastiaan.

Reply via email to