[RFC] ColorD

Jens Mueller jens.k.mueller at gmx.de
Tue Oct 23 13:42:12 PDT 2012


Jens Mueller wrote:
> 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.

Just read the other post. This has the same problem.

Jens


More information about the Digitalmars-d mailing list