In std.format, a linefeed after a positional parameter is ignored. A format string ending with a positional parameter throws RangeError. -------------------------------------------------------------- // Demo code string line1 = "line 1"; string line2 = "line 2"; writefln("With %%s parameters... ok"); writefln(" %s\n %s\n %s", line1, line2, line1); writefln("\nWith positional parameters... ignores linefeed"); writefln(" %1$\n %2$\n %1$\n", line1, line2); writefln("\nWithout trailing linefeed... throws RangeError"); writefln(" %1$\n %2$\n %1$", line1, line2); -------------------------------------------------------------- Output: With %s parameters... ok line 1 line 2 line 1 With positional parameters... ignores linefeed line 1 line 2 line 1 Without trailing linefeed... throws RangeError core.exception.RangeError@std.format(1578): Range violation line 1 line 2
This issue still persists in 2.048, although the exception thrown now is FormatError, not RangeError.
You'd think that sometime in the 15-month period since I first reported this "bug" someone would say, "No, you're an idiot. It works just fine when used correctly." Obviously, this is not a bug. My apologies. -------------------------------------------------------------- // Demo code string line1 = "line 1"; string line2 = "line 2"; string line3 = "line 3"; writeln("With explicit parameters... ok"); writefln(" %s\n %s\n %s\n %s\n %s", line1, line2, line3, line2, line1); writeln("(complete)"); writeln("\nWith positional parameters... works fine."); writefln(" %1$s\n %2$s\n %3$s\n %2$s\n %1$s", line1, line2, line3); writeln("(complete)"); -------------------------------------------------------------- Output: With explicit parameters... ok line 1 line 2 line 3 line 2 line 1 (complete) With positional parameters... works fine. line 1 line 2 line 3 line 2 line 1 (complete)