annotate orpg/external/terminalwriter.py @ 167:5c9a118476b2 alpha

Traipse Alpha 'OpenRPG' {091210-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Keeping up with Beta) New Features: Added Bookmarks Added 'boot' command to remote admin Added confirmation window for sent nodes Minor changes to allow for portability to an OpenSUSE linux OS Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG Zoom Mouse plugin added Images added to Plugin UI Switching to Element Tree Map efficiency, from FlexiRPG Added Status Bar to Update Manager New TrueDebug Class in orpg_log (See documentation for usage) Portable Mercurial Tip of the Day added, from Core and community New Reference Syntax added for custom PC sheets New Child Reference for gametree New Parent Reference for gametree New Gametree Recursion method, mapping, context sensitivity, and effeciency.. New Features node with bonus nodes and Node Referencing help added Dieroller structure from Core Added 7th Sea die roller method; ie [7k3] = [7d10.takeHighest(3).open(10)] New 'Mythos' System die roller added Added new vs. die roller method for WoD; ie [3v3] = [3d10.vs(3)]. Includes support for Mythos roller Fixes: Fix to Text based Server Fix to Remote Admin Commands Fix to Pretty Print, from Core Fix to Splitter Nodes not being created Fix to massive amounts of images loading, from Core Fix to Map from gametree not showing to all clients Fix to gametree about menus Fix to Password Manager check on startup Fix to PC Sheets from tool nodes. They now use the tabber_panel Fixed Whiteboard ID to prevent random line or text deleting. Modified ID's to prevent non updated clients from ruining the fix. default_manifest.xml renamed to default_upmana.xml Fix to Update Manager; cleaner clode for saved repositories Fixes made to Settings Panel and no reactive settings when Ok is pressed Fixes to Alternity roller's attack roll. Uses a simple Tuple instead of a Splice
author sirebral
date Thu, 10 Dec 2009 10:53:33 -0600
parents c54768cffbd4
children
rev   line source
66
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
1 """
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
2
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
3 Helper functions for writing to terminals and files.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
4
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
5 """
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
6
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
7
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
8 import sys, os
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
9 from orpg.external.std import std
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
10
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
11 def _getdimensions():
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
12 import termios,fcntl,struct
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
13 call = fcntl.ioctl(0,termios.TIOCGWINSZ,"\000"*8)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
14 height,width = struct.unpack( "hhhh", call ) [:2]
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
15 return height, width
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
16
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
17 if sys.platform == 'win32':
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
18 # ctypes access to the Windows console
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
19
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
20 STD_OUTPUT_HANDLE = -11
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
21 STD_ERROR_HANDLE = -12
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
22 FOREGROUND_BLUE = 0x0001 # text color contains blue.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
23 FOREGROUND_GREEN = 0x0002 # text color contains green.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
24 FOREGROUND_RED = 0x0004 # text color contains red.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
25 FOREGROUND_WHITE = 0x0007
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
26 FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
27 BACKGROUND_BLUE = 0x0010 # background color contains blue.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
28 BACKGROUND_GREEN = 0x0020 # background color contains green.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
29 BACKGROUND_RED = 0x0040 # background color contains red.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
30 BACKGROUND_WHITE = 0x0070
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
31 BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
32
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
33 def GetStdHandle(kind):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
34 import ctypes
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
35 return ctypes.windll.kernel32.GetStdHandle(kind)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
36
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
37 def SetConsoleTextAttribute(handle, attr):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
38 import ctypes
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
39 ctypes.windll.kernel32.SetConsoleTextAttribute(
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
40 handle, attr)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
41
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
42 def _getdimensions():
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
43 import ctypes
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
44 from ctypes import wintypes
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
45
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
46 SHORT = ctypes.c_short
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
47 class COORD(ctypes.Structure):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
48 _fields_ = [('X', SHORT),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
49 ('Y', SHORT)]
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
50 class SMALL_RECT(ctypes.Structure):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
51 _fields_ = [('Left', SHORT),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
52 ('Top', SHORT),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
53 ('Right', SHORT),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
54 ('Bottom', SHORT)]
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
55 class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
56 _fields_ = [('dwSize', COORD),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
57 ('dwCursorPosition', COORD),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
58 ('wAttributes', wintypes.WORD),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
59 ('srWindow', SMALL_RECT),
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
60 ('dwMaximumWindowSize', COORD)]
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
61 STD_OUTPUT_HANDLE = -11
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
62 handle = GetStdHandle(STD_OUTPUT_HANDLE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
63 info = CONSOLE_SCREEN_BUFFER_INFO()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
64 ctypes.windll.kernel32.GetConsoleScreenBufferInfo(
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
65 handle, ctypes.byref(info))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
66 # Substract one from the width, otherwise the cursor wraps
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
67 # and the ending \n causes an empty line to display.
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
68 return info.dwSize.Y, info.dwSize.X - 1
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
69
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
70 def get_terminal_width():
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
71 try:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
72 height, width = _getdimensions()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
73 except (SystemExit, KeyboardInterrupt), e:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
74 raise
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
75 except:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
76 # FALLBACK
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
77 width = int(os.environ.get('COLUMNS', 80))-1
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
78 # XXX the windows getdimensions may be bogus, let's sanify a bit
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
79 width = max(width, 40) # we alaways need 40 chars
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
80 return width
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
81
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
82 terminal_width = get_terminal_width()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
83
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
84 # XXX unify with _escaped func below
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
85 def ansi_print(text, esc, file=None, newline=True, flush=False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
86 if file is None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
87 file = sys.stderr
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
88 text = text.rstrip()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
89 if esc and not isinstance(esc, tuple):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
90 esc = (esc,)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
91 if esc and sys.platform != "win32" and file.isatty():
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
92 text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
93 text +
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
94 '\x1b[0m') # ANSI color code "reset"
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
95 if newline:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
96 text += '\n'
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
97
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
98 if esc and sys.platform == "win32" and file.isatty():
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
99 if 1 in esc:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
100 bold = True
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
101 esc = tuple([x for x in esc if x != 1])
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
102 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
103 bold = False
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
104 esctable = {() : FOREGROUND_WHITE, # normal
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
105 (31,): FOREGROUND_RED, # red
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
106 (32,): FOREGROUND_GREEN, # green
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
107 (33,): FOREGROUND_GREEN|FOREGROUND_RED, # yellow
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
108 (34,): FOREGROUND_BLUE, # blue
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
109 (35,): FOREGROUND_BLUE|FOREGROUND_RED, # purple
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
110 (36,): FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
111 (37,): FOREGROUND_WHITE, # white
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
112 (39,): FOREGROUND_WHITE, # reset
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
113 }
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
114 attr = esctable.get(esc, FOREGROUND_WHITE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
115 if bold:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
116 attr |= FOREGROUND_INTENSITY
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
117 STD_OUTPUT_HANDLE = -11
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
118 STD_ERROR_HANDLE = -12
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
119 if file is sys.stderr:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
120 handle = GetStdHandle(STD_ERROR_HANDLE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
121 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
122 handle = GetStdHandle(STD_OUTPUT_HANDLE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
123 SetConsoleTextAttribute(handle, attr)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
124 file.write(text)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
125 SetConsoleTextAttribute(handle, FOREGROUND_WHITE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
126 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
127 file.write(text)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
128
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
129 if flush:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
130 file.flush()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
131
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
132 def should_do_markup(file):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
133 return hasattr(file, 'isatty') and file.isatty() \
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
134 and os.environ.get('TERM') != 'dumb'
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
135
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
136 class TerminalWriter(object):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
137 _esctable = dict(black=30, red=31, green=32, yellow=33,
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
138 blue=34, purple=35, cyan=36, white=37,
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
139 Black=40, Red=41, Green=42, Yellow=43,
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
140 Blue=44, Purple=45, Cyan=46, White=47,
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
141 bold=1, light=2, blink=5, invert=7)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
142
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
143 def __init__(self, file=None, stringio=False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
144 if file is None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
145 if stringio:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
146 self.stringio = file = std.cStringIO.StringIO()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
147 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
148 file = std.sys.stdout
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
149 elif callable(file):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
150 file = WriteFile(file)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
151 self._file = file
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
152 self.fullwidth = get_terminal_width()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
153 self.hasmarkup = should_do_markup(file)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
154
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
155 def _escaped(self, text, esc):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
156 if esc and self.hasmarkup:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
157 text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
158 text +'\x1b[0m')
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
159 return text
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
160
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
161 def markup(self, text, **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
162 esc = []
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
163 for name in kw:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
164 if name not in self._esctable:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
165 raise ValueError("unknown markup: %r" %(name,))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
166 if kw[name]:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
167 esc.append(self._esctable[name])
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
168 return self._escaped(text, tuple(esc))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
169
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
170 def sep(self, sepchar, title=None, fullwidth=None, **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
171 if fullwidth is None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
172 fullwidth = self.fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
173 # the goal is to have the line be as long as possible
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
174 # under the condition that len(line) <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
175 if title is not None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
176 # we want 2 + 2*len(fill) + len(title) <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
177 # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
178 # 2*len(sepchar)*N <= fullwidth - len(title) - 2
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
179 # N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
180 N = (fullwidth - len(title) - 2) // (2*len(sepchar))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
181 fill = sepchar * N
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
182 line = "%s %s %s" % (fill, title, fill)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
183 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
184 # we want len(sepchar)*N <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
185 # i.e. N <= fullwidth // len(sepchar)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
186 line = sepchar * (fullwidth // len(sepchar))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
187 # in some situations there is room for an extra sepchar at the right,
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
188 # in particular if we consider that with a sepchar like "_ " the
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
189 # trailing space is not important at the end of the line
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
190 if len(line) + len(sepchar.rstrip()) <= fullwidth:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
191 line += sepchar.rstrip()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
192
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
193 self.line(line, **kw)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
194
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
195 def write(self, s, **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
196 if s:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
197 s = str(s)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
198 if self.hasmarkup and kw:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
199 s = self.markup(s, **kw)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
200 self._file.write(s)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
201 self._file.flush()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
202
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
203 def line(self, s='', **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
204 self.write(s, **kw)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
205 self.write('\n')
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
206
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
207 class Win32ConsoleWriter(object):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
208
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
209 def __init__(self, file=None, stringio=False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
210 if file is None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
211 if stringio:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
212 self.stringio = file = std.cStringIO.StringIO()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
213 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
214 file = std.sys.stdout
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
215 elif callable(file):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
216 file = WriteFile(file)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
217 self._file = file
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
218 self.fullwidth = get_terminal_width()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
219 self.hasmarkup = should_do_markup(file)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
220
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
221 def sep(self, sepchar, title=None, fullwidth=None, **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
222 if fullwidth is None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
223 fullwidth = self.fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
224 # the goal is to have the line be as long as possible
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
225 # under the condition that len(line) <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
226 if title is not None:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
227 # we want 2 + 2*len(fill) + len(title) <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
228 # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
229 # 2*len(sepchar)*N <= fullwidth - len(title) - 2
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
230 # N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
231 N = (fullwidth - len(title) - 2) // (2*len(sepchar))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
232 fill = sepchar * N
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
233 line = "%s %s %s" % (fill, title, fill)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
234 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
235 # we want len(sepchar)*N <= fullwidth
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
236 # i.e. N <= fullwidth // len(sepchar)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
237 line = sepchar * (fullwidth // len(sepchar))
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
238 # in some situations there is room for an extra sepchar at the right,
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
239 # in particular if we consider that with a sepchar like "_ " the
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
240 # trailing space is not important at the end of the line
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
241 if len(line) + len(sepchar.rstrip()) <= fullwidth:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
242 line += sepchar.rstrip()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
243
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
244 self.line(line, **kw)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
245
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
246 def write(self, s, **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
247 if s:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
248 s = str(s)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
249 if self.hasmarkup:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
250 handle = GetStdHandle(STD_OUTPUT_HANDLE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
251
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
252 if self.hasmarkup and kw:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
253 attr = 0
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
254 if kw.pop('bold', False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
255 attr |= FOREGROUND_INTENSITY
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
256
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
257 if kw.pop('red', False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
258 attr |= FOREGROUND_RED
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
259 elif kw.pop('blue', False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
260 attr |= FOREGROUND_BLUE
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
261 elif kw.pop('green', False):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
262 attr |= FOREGROUND_GREEN
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
263 else:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
264 attr |= FOREGROUND_WHITE
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
265
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
266 SetConsoleTextAttribute(handle, attr)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
267 self._file.write(s)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
268 self._file.flush()
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
269 if self.hasmarkup:
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
270 SetConsoleTextAttribute(handle, FOREGROUND_WHITE)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
271
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
272 def line(self, s='', **kw):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
273 self.write(s + '\n', **kw)
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
274
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
275 if sys.platform == 'win32':
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
276 TerminalWriter = Win32ConsoleWriter
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
277
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
278 class WriteFile(object):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
279 def __init__(self, writemethod):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
280 self.write = writemethod
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
281 def flush(self):
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
282 return
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
283
c54768cffbd4 Traipse Dev 'OpenRPG' {090818-00}
sirebral
parents:
diff changeset
284