import string; import c.stdio; private { template Pair(T) { struct Pair { T first, second; } } int find(char[] str, char c, int startPos) { while (startPos < str.length) if (str[startPos] == c) return startPos; else startPos++; return -1; } alias instance Pair(int).Pair IntPair; } private class Formatter { private { char[] _formatString; // The string to parse and format. We tweak this as we go. IntPair nextMetaString() { IntPair pair; pair.first = string.find(_formatString, "{%"); pair.second = find(_formatString, '}', pair.first); return pair; } void replace(IntPair pos, char[] value) { _formatString = _formatString[0..pos.first] ~ value ~ _formatString[(pos.second + 1).._formatString.length]; //printf("\t%s\n", &_formatString[0]); } } public { this(char[] s) { _formatString = s; } char[] toString() { return _formatString; } Formatter mod(real r) { IntPair meta = nextMetaString(); if (meta.first == -1 || meta.second == -1) return this; char[64] c; c[] = 0; sprintf(c, "%f", cast(double)r); // TODO: play with the meta to get things like precision replace(meta, c[0..strlen(c)]); return this; } Formatter mod(int i) { IntPair meta = nextMetaString(); if (meta.first == -1 || meta.second == -1) return this; replace(meta, string.toString(i)); return this; } Formatter mod(char[] s) { IntPair meta = nextMetaString(); if (meta.first == -1 || meta.second == -1) return this; // TODO: play with the meta to get things like precision replace(meta, s); return this; } Formatter mod(Object o) { IntPair meta = nextMetaString(); if (meta.first == -1 || meta.second == -1) return this; replace(meta, o.toString()); return this; } } } void main() { Formatter s = new Formatter("blah blah {%} {%} {%} blah {%} blah{%}") % "String!" % 13 % cast(real)3.5 % "!"; char[] c = s.toString(); printf("%s", toStringz(c)); delete s; }