How about colors and terminal graphics in std.format?

James Miller james at aatch.net
Mon Mar 12 19:37:03 PDT 2012


On 13 March 2012 15:20, Chad J <chadjoan at __spam.is.bad__gmail.com> wrote:
> On 03/12/2012 11:02 AM, H. S. Teoh wrote:
>>
>> On Mon, Mar 12, 2012 at 10:51:08AM +0100, Jacob Carlborg wrote:
>>>
>>> On 2012-03-12 03:16, Chad J wrote:
>>>>
>>>> I remember doing colored terminal output in Python. It was pretty
>>>> nifty, and allows for some slick CLI design. I think D can do better
>>>> by putting it in the standard library.
>>>>
>>>> I was thinking something along the lines of this:
>>>> http://www.chadjoan.com/d/dmd.2.058/html/d/phobos/std_format.html
>>>>
>>>> I figure it would probably be easy to get some of the basics down.
>>>> More advanced stuff would probably involve messing with terminfo or
>>>> <term.h>.  Windows' (terribly bad) command prompt can have some of
>>>> these capabilities implemented too, but in a roundabout way because
>>>> Windows defines API functions that need to be called to affect
>>>> terminal graphics and coloring. I figure that would require the help
>>>> of the I/O routines if I were to work on that.
>>>>
>>>> If there's interest, I might take a stab at it.
>>>>
>>>> So, would this sort of thing make it in?
>>>
>>>
>>> I think it would nice to have, but not in std.format. std.terminal or
>>> similar would be better.
>>
>> [...]
>>
>>
>> +1.
>>
>> It's better not to pollute std.format with stuff that, strictly
>> speaking, isn't related to formatting per se, but is tied to a
>> particular output medium.  This is proven by the fact that the
>> translation of color escapes only makes sense w.r.t. a particular
>> terminal, so you'll get garbage if you call std.format on the string,
>> save it to file, say, then load it later and output it to a possibly
>> different terminal type.
>>
>> So what you *really* want is to translate these escape sequences *at
>> output time*, not at string formatting time. If we do it that way, we
>> can have the nicer behaviour that these escapes will work on any
>> terminal and can be freely moved around from terminal to terminal,
>> because they are only interpreted at the instant when they are actually
>> being output to that terminal.
>>
>>
>> T
>>
>
>
> I never felt it would go into std.terminal because I have a fairly narrow
> purpose in mind.  If I wanted to do anything a bit fancier, I would be all
> about making std.terminal.  But currently I feel that this would be
> orthogonal to such a module.  This is very lightweight on the learning side,
> while std.terminal would include code to handle multiple terminals and
> interactivity: it would be much heavier and a bigger mental investment from
> the user.
>
>
> Anyhow, here are my objectives:
>
> What I really want is to have an /easy/ way to do color formatting.  I want
> to be able to write this:
>
> writefln("%Cred(Red text:%) Normal text.");
>
> The syntax should be similar to format strings so that memorization is
> easier due to the extra association, and also so that we don't escapify yet
> another special character: '%' and '\' are already required to be written as
> '%%' and '\\' in various contexts and it would be annoying to have yet
> another one.
>
> I suppose that could be handled output side, but I don't know how I'd avoid
> stuff like this:
>
> writefln("%%Cred(Red text:%%) %d%%%% complete.",percentComplete);
>
> It also made a lot of sense to me that I would find documentation on
> coloring in the place I'd find documentation on formatting.  Maybe this
> isn't what others feel.  Nonetheless, I'm inclined to start from intuition
> and refine if there are objections.
>
> There are probably going to be multiple ways to push things to the terminal
> (maybe in multiple source files too: stdio vs stream?) and it should be
> possible to colorize all of them in a uniform manner. Documentation should
> be easy to find; discovery should be intuitive.
>
>
> If someone has a good vision that accomplishes these things, then please do
> share.

I think the problem with putting it into formatting is that it is
inherently not output. IOW formatting should go anywhere, but colored
output is terminal-only.

Also, there are differences between terminals and all sorts of crap
that just make this harder to do "simply". However, there's no reason
why there cant be an easy way to colorize output in std.terminal (or
whatever), that are basically just modified writef(ln) calls
(colorWritef?) that only output to stdout (and maybe stderr). I think
this would be a good way around it, because then everything that is
terminal-specific is kept in one place, and you don't get mistakes
like outputting color to a file because you did the wrong sequence, or
forgot to check that stdout is a terminal and all that.

--
James Miller


More information about the Digitalmars-d mailing list