[RFC] ColorD
Jens Mueller
jens.k.mueller at gmx.de
Tue Oct 23 13:39:46 PDT 2012
Chad J wrote:
> 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");
Ideally, we get some users and ask them what they find easy to read. Or
look how other languages solve this.
Because I myself don't color my terminals that much I find it hard to
imagine.
I searched for some ruby libraries. I find ruby syntax often very easy.
We could use UFCS, e.g.
"some string".red
or
"some string".foreground(Color.red)
What do you think?
I find this way easier than format strings.
Jens
More information about the Digitalmars-d
mailing list