2chを参考にしながら作ってみたが、バイナリ表示に一苦労。
コマンド プロンプトはエスケープシーケンスをサポートしてなかったという罠。ビープ音は出るのに…。
utf-16のBOMを区切りとして使って無理やり実装。
Python良く知らんのや面倒という理由でコードは汚い。
コード整理して更新。
if sys.platform == 'win32': from ctypes import windll, Structure, c_short, c_ushort, byref import codecs class COORD(Structure): _fields_ = [ ("X", c_short), ("Y", c_short) ] class SMALL_RECT(Structure): _fields_ = [ ("Left", c_short), ("Top", c_short), ("Right", c_short), ("Bottom", c_short) ] class CONSOLE_SCREEN_BUFFER_INFO(Structure): _fields_ = [ ("dwSize", COORD), ("dwCursorPosition", COORD), ("wAttributes", c_ushort), ("srWindow", SMALL_RECT), ("dwMaximumWindowSize", COORD) ] STD_OUTPUT_HANDLE = -11 STD_ERROR_HANDLE = -12 def consolereplace_errors(exception): if not isinstance(exception, UnicodeDecodeError): raise TypeError("consolereplace() cannot handle %r" % exception) l = [u"\\%x" % ord(exception.object[pos]) for pos in xrange(exception.start, exception.end)] return (u"\ufffe%s\ufeff" % u"".join(l), exception.end) codecs.register_error("consolereplace", consolereplace_errors) FOREGROUND_RED = 4 class WindowsConsoleWriter: def __init__(self, stdhandle, errors='strict'): self.errors = errors self.encoding = 'utf_16' self.handle = windll.kernel32.GetStdHandle(stdhandle) csbi = CONSOLE_SCREEN_BUFFER_INFO() windll.kernel32.GetConsoleScreenBufferInfo(self.handle, byref(csbi)) self.defattr = csbi.wAttributes def writelines(self, text): self.write(text + "\n") def _write(self, text): windll.kernel32.WriteConsoleW(self.handle, text, len(text), 0, 0) def _color(self, color): windll.kernel32.SetConsoleTextAttribute(self.handle, color) def write(self, text): text = unicode(text, 'utf_8', errors='consolereplace') i = 0 j = 0 for c in text: if c == u'\ufffe': self._write(text[i:j]) i = j+1 self._color(FOREGROUND_RED) elif c == u'\ufeff': self._write(text[i:j]) i = j+1 self._color(self.defattr) j+=1 self._write(text[i:j]) def isatty(self): return True def flush(self): pass if sys.stdout.isatty(): sys.stdout = WindowsConsoleWriter(STD_OUTPUT_HANDLE) if sys.stderr.isatty(): sys.stderr = WindowsConsoleWriter(STD_ERROR_HANDLE)
64bitが駄目かも。
あとライセンスは自由に再ライセンスができるWTFPL-2で。