[RFC] ColorD
Chad J
chadjoan at __spam.is.bad__gmail.com
Tue Oct 23 05:47:21 PDT 2012
On 10/23/2012 03:51 AM, Jens Mueller wrote:
> Chad J wrote:
>> On 10/22/2012 03:47 AM, Jens Mueller wrote:
>>> Chad J wrote:
>>>> There is no weakness to this. The only shred of a counterargument I
>>>> can think of is that it makes the format strings more difficult to
>>>> learn. Other than that, it is possible to detect the destination of
>>>> the formatter, so color codes will never end up in places where they
>>>> shouldn't. A conservative approach to this should handle most
>>>> desires and never interfere with all the people with no interest in
>>>> color.
>>>>
>>>> On the upshot are the things I've mentioned:
>>>> - A format specifier is potentially more discoverable.
>>>> - A format specifier is more concise. This keeps your lines from
>>>> wrapping. They are probably too long already.
>>>
>>> Do you consider this
>>> writecf(Color.red, "something %s", "here")
>>> concise as well?
>>>
>>
>> The case is too easy. You're formatting an entire line.
>
> Am I? I think it's not a line. But I see your point.
> You mean something like
> writec(Color.red, "red")
> writec(Color.blue, "blue")
> writec(Color.green, "green")
> is too verbose.
> You want something like
> writef("%CFred(red%)%CFblue(blue%)%CFgreeng(reen%)");
> Right?
>
>>>> - To cement the previous point: nesting requires a few extra
>>>> characters with a format specifier, rather than a couple extra
>>>> /lines/ for extra function calls.
>>>
>>> Don't understand this point. Can you give an example?
>>>
>>
>> Option A:
>>
>> auto save = getConsoleState();
>> scope (exit) setConsoleState(save);
>> setConsoleColors(Fg.red, Bg.blue);
>> writeln("Red text on blue background.");
>>
>> Option B:
>>
>> writefln("%CFredBblu(Red text on blue background.%)");
>
> I see. Though I find the last line difficult to decipher (because there
> are no spaces).
>
>>>> - Calls to stateful console functions allow people to write bugs
>>>> like saving console state and then forgetting to restore it (or
>>>> throwing an exception and neglecting to restore from within a scope
>>>> guard). Format specifiers do not have this problem.
>>>
>>> The same holds for
>>> writecf(Color.red, "something %s", "here")
>>>
>>
>> See my above example. In that case the formatter no longer requires
>> even using the scope feature because there are no resources to clean
>> up. The library handles that mess.
>>
>> Also statefulness is a pain to deal with. Stack-like operation with
>> push/pop or bracketing constructs is usually much less troublesome
>> for this sort of thing.
>
> It'll be nice then if you can built something using format specifiers on
> top of a basic library.
>
>>>> - etc (I'm sure I'm forgetting one or two.)
>>>>
>>>> These are the reasons why my ideal language has color formatting
>>>> built into its I/O routines.
>>>
>>> Just wanted to point out that instead of that you can add writec*
>>> functions. I think the only thing is that these are less discoverable
>>> but they also work without formatting, e.g.
>>> writec(Color.red, "my text");
>>>
>>
>> The thing I found very difficult with other color formatting APIs
>> was formatting individual words or characters. Entire lines are
>> easy-peasy stuff in any API. Solving the entire-lines case won't
>> impress me. ;)
>
> I see your point now. But we should keep it simple.
>
>> Here's my more typical use case:
>>
>> writefln("The %CFred(widgetometer%) is a device for measuring");
>> writefln("widget effectiveness. It is possible to ");
>> writefln("reconcile transcendental properties by hitting");
>> writefln("%CFblu(B%) for blue coefficients, %CFgrn(G%) for green");
>> writefln("coefficients, or %CFyel(Y%) for yellow coefficients.");
>> writefln("Here is a correspondence table:");
>> writefln(" %CFnue( %) | %CFblu( B %) %CFgrn( G %) %CFyel( Y %) ");
>> writefln(" %CFnue(-%)-+-%CFnue(---%)-%CFnue(---%)-%CFnue(---%)-");
>> writefln(" %CFblu(B%) | %CFblu(200%) %CFwht(330%) %CFwht(303%) ");
>> writefln(" %CFgrn(G%) | %CFwht(110%) %CFgrn(020%) %CFwht(033%) ");
>> writefln(" %CFyel(Y%) | %CFwht(101%) %CFwht(011%) %CFyel(002%) ");
>>
>> I realized that I wanted a "nue" color that has no effect but allows
>> me to align things effectively ;)
>>
>> Anyhow, please try to write the above example using any other style.
>> Interleaved function calls are particularly "fun"<g>
>
> I'm convinced. But I find that it difficult to read. Though that's a
> problem I usually have with format strings. Can these format strings be
> made easier to read. I mean
>
> writefln("The %CF(red)(widgetometer) is a device for measuring");
> or
> writefln("The %c(red,white)(widgetometer) is a device for measuring"); // for writing red on white
>
> is already easier to my eyes.
> I'd be happy to see it built on top.
>
> Jens
That's a reasonable suggestion. The only thing that can't be solved is
the trailing ) enclosing the text to be formatted. That needs a %
before it to prevent ambiguity with parentheses in the text itself. So
I could make your example:
> writefln("The %c(red,white)(widgetometer%) is a device
formeasuring"); // for writing red on white
I was also considering the possibility of separating layout and style by
allowing some kind of style specification before the printing, with a
limited formatting spec for using the styles:
stdout.addTermTextStyle("id=myStyle, fg=red, bg=white, dark, underline");
writefln("The %c(myStyle)(widgetometer%) is a device for measuring");
More information about the Digitalmars-d
mailing list