mirror of
https://github.com/yamadapc/d-colorize
synced 2024-11-14 21:14:00 +01:00
commit
f630d6fdfa
5
dub.json
5
dub.json
|
@ -3,7 +3,10 @@
|
|||
"description": "A port of Ruby's colorize library to D.",
|
||||
"license": "MIT",
|
||||
"copyright": "Copyright © 2014, Pedro Tacla Yamada",
|
||||
"importPaths": ["source"],
|
||||
"sourcePaths": ["source"],
|
||||
"authors": [
|
||||
"Pedro Tacla Yamada"
|
||||
"Pedro Tacla Yamada",
|
||||
"ponce"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* License: Licensed under the MIT license. See LICENSE for more information
|
||||
* Version: 0.1.0
|
||||
*/
|
||||
module colorize.colorize;
|
||||
|
||||
import std.string : format;
|
||||
|
74
source/colorize/cwrite.d
Normal file
74
source/colorize/cwrite.d
Normal file
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* Authors: ponce
|
||||
* Date: July 28, 2014
|
||||
* License: Licensed under the MIT license. See LICENSE for more information
|
||||
* Version: 0.1.0
|
||||
*/
|
||||
module colorize.cwrite;
|
||||
|
||||
import std.stdio : File, stdout;
|
||||
|
||||
import colorize.winterm;
|
||||
|
||||
/// Coloured write.
|
||||
void cwrite(T...)(T args) if (!is(T[0] : File))
|
||||
{
|
||||
stdout.cwrite(args);
|
||||
}
|
||||
|
||||
/// Coloured writef.
|
||||
void cwritef(T...)(T args)
|
||||
{
|
||||
stdout.cwritef(args);
|
||||
}
|
||||
|
||||
/// Coloured writefln.
|
||||
void cwritefln(T...)(T args)
|
||||
{
|
||||
stdout.cwritef(args, "\n");
|
||||
}
|
||||
|
||||
/// Coloured writeln.
|
||||
void cwriteln(T...)(T args)
|
||||
{
|
||||
// Most general instance
|
||||
stdout.cwrite(args, '\n');
|
||||
}
|
||||
|
||||
/// Coloured writef to a File.
|
||||
void cwritef(Char, A...)(File f, in Char[] fmt, A args)
|
||||
{
|
||||
auto s = format(fmt, args);
|
||||
f.cwrite(s);
|
||||
}
|
||||
|
||||
/// Coloured writef to a File.
|
||||
void cwrite(S...)(File f, S args)
|
||||
{
|
||||
import std.conv : to;
|
||||
|
||||
string s = "";
|
||||
foreach(arg; args)
|
||||
s ~= to!string(arg);
|
||||
|
||||
version(Windows)
|
||||
{
|
||||
WinTermEmulation winterm;
|
||||
winterm.initialize();
|
||||
foreach(dchar c ; s)
|
||||
{
|
||||
auto charAction = winterm.feed(c);
|
||||
final switch(charAction) with (WinTermEmulation.CharAction)
|
||||
{
|
||||
case drop: break;
|
||||
case write: f.write(c); break;
|
||||
case flush: f.flush(); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
f.write(s);
|
||||
}
|
||||
}
|
||||
|
10
source/colorize/package.d
Normal file
10
source/colorize/package.d
Normal file
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
* Authors: ponce
|
||||
* Date: July 28, 2014
|
||||
* License: Licensed under the MIT license. See LICENSE for more information
|
||||
* Version: 0.1.0
|
||||
*/
|
||||
module colorize;
|
||||
|
||||
public import colorize.colorize;
|
||||
public import colorize.cwrite;
|
162
source/colorize/winterm.d
Normal file
162
source/colorize/winterm.d
Normal file
|
@ -0,0 +1,162 @@
|
|||
/**
|
||||
* Authors: ponce
|
||||
* Date: July 28, 2014
|
||||
* License: Licensed under the MIT license. See LICENSE for more information
|
||||
* Version: 0.1.0
|
||||
*/
|
||||
module colorize.winterm;
|
||||
|
||||
|
||||
version(Windows)
|
||||
{
|
||||
import core.sys.windows.windows;
|
||||
|
||||
// This is a state machine to enable terminal colors on Windows.
|
||||
// Parses and interpret ANSI/VT100 Terminal Control Escape Sequences.
|
||||
// Only supports colour sequences, will output char incorrectly on invalid input.
|
||||
struct WinTermEmulation
|
||||
{
|
||||
public:
|
||||
@nogc void initialize() nothrow
|
||||
{
|
||||
// saves console attributes
|
||||
_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
_savedInitialColor = (0 != GetConsoleScreenBufferInfo(_console, &consoleInfo));
|
||||
_state = State.initial;
|
||||
}
|
||||
|
||||
@nogc ~this() nothrow
|
||||
{
|
||||
// Restore initial text attributes on release
|
||||
if (_savedInitialColor)
|
||||
{
|
||||
SetConsoleTextAttribute(_console, consoleInfo.wAttributes);
|
||||
_savedInitialColor = false;
|
||||
}
|
||||
}
|
||||
|
||||
enum CharAction
|
||||
{
|
||||
write,
|
||||
drop,
|
||||
flush
|
||||
}
|
||||
|
||||
// Eat one character and update color state accordingly.
|
||||
// Returns what to do with the fed character.
|
||||
@nogc CharAction feed(dchar d) nothrow
|
||||
{
|
||||
final switch(_state) with (State)
|
||||
{
|
||||
case initial:
|
||||
if (d == '\x1B')
|
||||
{
|
||||
_state = escaped;
|
||||
return CharAction.flush;
|
||||
}
|
||||
break;
|
||||
|
||||
case escaped:
|
||||
if (d == '[')
|
||||
{
|
||||
_state = readingAttribute;
|
||||
_parsedAttr = 0;
|
||||
return CharAction.drop;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case readingAttribute:
|
||||
if (d >= '0' && d <= '9')
|
||||
{
|
||||
_parsedAttr = _parsedAttr * 10 + (d - '0');
|
||||
return CharAction.drop;
|
||||
}
|
||||
else if (d == ';')
|
||||
{
|
||||
executeAttribute(_parsedAttr);
|
||||
_parsedAttr = 0;
|
||||
return CharAction.drop;
|
||||
}
|
||||
else if (d == 'm')
|
||||
{
|
||||
executeAttribute(_parsedAttr);
|
||||
_state = State.initial;
|
||||
return CharAction.drop;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CharAction.write;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _console;
|
||||
bool _savedInitialColor;
|
||||
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
||||
State _state;
|
||||
WORD _currentAttr;
|
||||
int _parsedAttr;
|
||||
|
||||
enum State
|
||||
{
|
||||
initial,
|
||||
escaped,
|
||||
readingAttribute
|
||||
}
|
||||
|
||||
@nogc void setForegroundColor(WORD fgFlags) nothrow
|
||||
{
|
||||
_currentAttr = _currentAttr & ~(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
_currentAttr = _currentAttr | fgFlags;
|
||||
SetConsoleTextAttribute(_console, _currentAttr);
|
||||
}
|
||||
|
||||
@nogc void setBackgroundColor(WORD bgFlags) nothrow
|
||||
{
|
||||
_currentAttr = _currentAttr & ~(BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY);
|
||||
_currentAttr = _currentAttr | bgFlags;
|
||||
SetConsoleTextAttribute(_console, _currentAttr);
|
||||
}
|
||||
|
||||
@nogc void executeAttribute(int attr) nothrow
|
||||
{
|
||||
switch (attr)
|
||||
{
|
||||
case 0:
|
||||
// reset all attributes
|
||||
SetConsoleTextAttribute(_console, consoleInfo.wAttributes);
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( (30 <= attr && attr <= 37) || (90 <= attr && attr <= 97) )
|
||||
{
|
||||
WORD color = 0;
|
||||
if (90 <= attr && attr <= 97)
|
||||
{
|
||||
color = FOREGROUND_INTENSITY;
|
||||
attr -= 60;
|
||||
}
|
||||
attr -= 30;
|
||||
color |= (attr & 1 ? FOREGROUND_RED : 0) | (attr & 2 ? FOREGROUND_GREEN : 0) | (attr & 4 ? FOREGROUND_BLUE : 0);
|
||||
setForegroundColor(color);
|
||||
}
|
||||
|
||||
if ( (40 <= attr && attr <= 47) || (100 <= attr && attr <= 107) )
|
||||
{
|
||||
WORD color = 0;
|
||||
if (100 <= attr && attr <= 107)
|
||||
{
|
||||
color = BACKGROUND_INTENSITY;
|
||||
attr -= 60;
|
||||
}
|
||||
attr -= 40;
|
||||
color |= (attr & 1 ? BACKGROUND_RED : 0) | (attr & 2 ? BACKGROUND_GREEN : 0) | (attr & 4 ? BACKGROUND_BLUE : 0);
|
||||
setBackgroundColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue