annotate orpg/external/terminalwriter.py @ 20:39ebe168ceb3 ornery-orc

Traipse 'OpenRPG' {090827-02} 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: Update Manager is now in version 0.8. While not every button works, users can now browse the different revisions and their different changesets. The code has been refined some with feature from Core added to it. A Crash report is now created if the users software crashes. Update Manager has been moved to the Traipse Suite menu item, and a Debug Console as been added as well. Please Check the Controls Panel to see the other files changed.
author sirebral
date Thu, 27 Aug 2009 01:11:22 -0500
parents 97265586402b
children
rev   line source
18
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
1 """
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
2
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
3 Helper functions for writing to terminals and files.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
4
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
5 """
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
6
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
7
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
8 import sys, os
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
9 from orpg.external.std import std
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
10
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
11 def _getdimensions():
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
12 import termios,fcntl,struct
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
13 call = fcntl.ioctl(0,termios.TIOCGWINSZ,"\000"*8)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
14 height,width = struct.unpack( "hhhh", call ) [:2]
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
15 return height, width
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
16
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
17 if sys.platform == 'win32':
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
18 # ctypes access to the Windows console
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
19
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
20 STD_OUTPUT_HANDLE = -11
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
21 STD_ERROR_HANDLE = -12
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
22 FOREGROUND_BLUE = 0x0001 # text color contains blue.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
23 FOREGROUND_GREEN = 0x0002 # text color contains green.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
24 FOREGROUND_RED = 0x0004 # text color contains red.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
25 FOREGROUND_WHITE = 0x0007
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
26 FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
27 BACKGROUND_BLUE = 0x0010 # background color contains blue.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
28 BACKGROUND_GREEN = 0x0020 # background color contains green.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
29 BACKGROUND_RED = 0x0040 # background color contains red.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
30 BACKGROUND_WHITE = 0x0070
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
31 BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
32
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
33 def GetStdHandle(kind):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
34 import ctypes
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
35 return ctypes.windll.kernel32.GetStdHandle(kind)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
36
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
37 def SetConsoleTextAttribute(handle, attr):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
38 import ctypes
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
39 ctypes.windll.kernel32.SetConsoleTextAttribute(
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
40 handle, attr)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
41
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
42 def _getdimensions():
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
43 import ctypes
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
44 from ctypes import wintypes
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
45
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
46 SHORT = ctypes.c_short
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
47 class COORD(ctypes.Structure):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
48 _fields_ = [('X', SHORT),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
49 ('Y', SHORT)]
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
50 class SMALL_RECT(ctypes.Structure):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
51 _fields_ = [('Left', SHORT),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
52 ('Top', SHORT),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
53 ('Right', SHORT),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
54 ('Bottom', SHORT)]
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
55 class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
56 _fields_ = [('dwSize', COORD),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
57 ('dwCursorPosition', COORD),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
58 ('wAttributes', wintypes.WORD),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
59 ('srWindow', SMALL_RECT),
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
60 ('dwMaximumWindowSize', COORD)]
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
61 STD_OUTPUT_HANDLE = -11
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
62 handle = GetStdHandle(STD_OUTPUT_HANDLE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
63 info = CONSOLE_SCREEN_BUFFER_INFO()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
64 ctypes.windll.kernel32.GetConsoleScreenBufferInfo(
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
65 handle, ctypes.byref(info))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
66 # Substract one from the width, otherwise the cursor wraps
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
67 # and the ending \n causes an empty line to display.
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
68 return info.dwSize.Y, info.dwSize.X - 1
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
69
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
70 def get_terminal_width():
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
71 try:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
72 height, width = _getdimensions()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
73 except (SystemExit, KeyboardInterrupt), e:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
74 raise
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
75 except:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
76 # FALLBACK
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
77 width = int(os.environ.get('COLUMNS', 80))-1
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
78 # XXX the windows getdimensions may be bogus, let's sanify a bit
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
79 width = max(width, 40) # we alaways need 40 chars
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
80 return width
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
81
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
82 terminal_width = get_terminal_width()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
83
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
84 # XXX unify with _escaped func below
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
85 def ansi_print(text, esc, file=None, newline=True, flush=False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
86 if file is None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
87 file = sys.stderr
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
88 text = text.rstrip()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
89 if esc and not isinstance(esc, tuple):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
90 esc = (esc,)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
91 if esc and sys.platform != "win32" and file.isatty():
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
92 text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
93 text +
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
94 '\x1b[0m') # ANSI color code "reset"
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
95 if newline:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
96 text += '\n'
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
97
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
98 if esc and sys.platform == "win32" and file.isatty():
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
99 if 1 in esc:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
100 bold = True
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
101 esc = tuple([x for x in esc if x != 1])
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
102 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
103 bold = False
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
104 esctable = {() : FOREGROUND_WHITE, # normal
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
105 (31,): FOREGROUND_RED, # red
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
106 (32,): FOREGROUND_GREEN, # green
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
107 (33,): FOREGROUND_GREEN|FOREGROUND_RED, # yellow
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
108 (34,): FOREGROUND_BLUE, # blue
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
109 (35,): FOREGROUND_BLUE|FOREGROUND_RED, # purple
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
110 (36,): FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
111 (37,): FOREGROUND_WHITE, # white
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
112 (39,): FOREGROUND_WHITE, # reset
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
113 }
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
114 attr = esctable.get(esc, FOREGROUND_WHITE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
115 if bold:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
116 attr |= FOREGROUND_INTENSITY
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
117 STD_OUTPUT_HANDLE = -11
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
118 STD_ERROR_HANDLE = -12
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
119 if file is sys.stderr:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
120 handle = GetStdHandle(STD_ERROR_HANDLE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
121 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
122 handle = GetStdHandle(STD_OUTPUT_HANDLE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
123 SetConsoleTextAttribute(handle, attr)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
124 file.write(text)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
125 SetConsoleTextAttribute(handle, FOREGROUND_WHITE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
126 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
127 file.write(text)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
128
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
129 if flush:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
130 file.flush()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
131
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
132 def should_do_markup(file):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
133 return hasattr(file, 'isatty') and file.isatty() \
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
134 and os.environ.get('TERM') != 'dumb'
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
135
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
136 class TerminalWriter(object):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
137 _esctable = dict(black=30, red=31, green=32, yellow=33,
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
138 blue=34, purple=35, cyan=36, white=37,
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
139 Black=40, Red=41, Green=42, Yellow=43,
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
140 Blue=44, Purple=45, Cyan=46, White=47,
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
141 bold=1, light=2, blink=5, invert=7)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
142
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
143 def __init__(self, file=None, stringio=False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
144 if file is None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
145 if stringio:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
146 self.stringio = file = std.cStringIO.StringIO()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
147 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
148 file = std.sys.stdout
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
149 elif callable(file):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
150 file = WriteFile(file)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
151 self._file = file
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
152 self.fullwidth = get_terminal_width()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
153 self.hasmarkup = should_do_markup(file)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
154
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
155 def _escaped(self, text, esc):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
156 if esc and self.hasmarkup:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
157 text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
158 text +'\x1b[0m')
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
159 return text
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
160
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
161 def markup(self, text, **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
162 esc = []
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
163 for name in kw:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
164 if name not in self._esctable:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
165 raise ValueError("unknown markup: %r" %(name,))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
166 if kw[name]:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
167 esc.append(self._esctable[name])
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
168 return self._escaped(text, tuple(esc))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
169
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
170 def sep(self, sepchar, title=None, fullwidth=None, **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
171 if fullwidth is None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
172 fullwidth = self.fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
173 # the goal is to have the line be as long as possible
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
174 # under the condition that len(line) <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
175 if title is not None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
176 # we want 2 + 2*len(fill) + len(title) <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
177 # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
178 # 2*len(sepchar)*N <= fullwidth - len(title) - 2
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
179 # N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
180 N = (fullwidth - len(title) - 2) // (2*len(sepchar))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
181 fill = sepchar * N
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
182 line = "%s %s %s" % (fill, title, fill)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
183 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
184 # we want len(sepchar)*N <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
185 # i.e. N <= fullwidth // len(sepchar)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
186 line = sepchar * (fullwidth // len(sepchar))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
187 # in some situations there is room for an extra sepchar at the right,
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
188 # in particular if we consider that with a sepchar like "_ " the
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
189 # trailing space is not important at the end of the line
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
190 if len(line) + len(sepchar.rstrip()) <= fullwidth:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
191 line += sepchar.rstrip()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
192
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
193 self.line(line, **kw)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
194
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
195 def write(self, s, **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
196 if s:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
197 s = str(s)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
198 if self.hasmarkup and kw:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
199 s = self.markup(s, **kw)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
200 self._file.write(s)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
201 self._file.flush()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
202
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
203 def line(self, s='', **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
204 self.write(s, **kw)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
205 self.write('\n')
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
206
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
207 class Win32ConsoleWriter(object):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
208
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
209 def __init__(self, file=None, stringio=False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
210 if file is None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
211 if stringio:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
212 self.stringio = file = std.cStringIO.StringIO()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
213 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
214 file = std.sys.stdout
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
215 elif callable(file):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
216 file = WriteFile(file)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
217 self._file = file
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
218 self.fullwidth = get_terminal_width()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
219 self.hasmarkup = should_do_markup(file)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
220
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
221 def sep(self, sepchar, title=None, fullwidth=None, **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
222 if fullwidth is None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
223 fullwidth = self.fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
224 # the goal is to have the line be as long as possible
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
225 # under the condition that len(line) <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
226 if title is not None:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
227 # we want 2 + 2*len(fill) + len(title) <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
228 # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
229 # 2*len(sepchar)*N <= fullwidth - len(title) - 2
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
230 # N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
231 N = (fullwidth - len(title) - 2) // (2*len(sepchar))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
232 fill = sepchar * N
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
233 line = "%s %s %s" % (fill, title, fill)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
234 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
235 # we want len(sepchar)*N <= fullwidth
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
236 # i.e. N <= fullwidth // len(sepchar)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
237 line = sepchar * (fullwidth // len(sepchar))
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
238 # in some situations there is room for an extra sepchar at the right,
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
239 # in particular if we consider that with a sepchar like "_ " the
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
240 # trailing space is not important at the end of the line
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
241 if len(line) + len(sepchar.rstrip()) <= fullwidth:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
242 line += sepchar.rstrip()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
243
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
244 self.line(line, **kw)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
245
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
246 def write(self, s, **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
247 if s:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
248 s = str(s)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
249 if self.hasmarkup:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
250 handle = GetStdHandle(STD_OUTPUT_HANDLE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
251
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
252 if self.hasmarkup and kw:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
253 attr = 0
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
254 if kw.pop('bold', False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
255 attr |= FOREGROUND_INTENSITY
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
256
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
257 if kw.pop('red', False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
258 attr |= FOREGROUND_RED
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
259 elif kw.pop('blue', False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
260 attr |= FOREGROUND_BLUE
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
261 elif kw.pop('green', False):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
262 attr |= FOREGROUND_GREEN
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
263 else:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
264 attr |= FOREGROUND_WHITE
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
265
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
266 SetConsoleTextAttribute(handle, attr)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
267 self._file.write(s)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
268 self._file.flush()
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
269 if self.hasmarkup:
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
270 SetConsoleTextAttribute(handle, FOREGROUND_WHITE)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
271
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
272 def line(self, s='', **kw):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
273 self.write(s + '\n', **kw)
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
274
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
275 if sys.platform == 'win32':
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
276 TerminalWriter = Win32ConsoleWriter
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
277
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
278 class WriteFile(object):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
279 def __init__(self, writemethod):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
280 self.write = writemethod
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
281 def flush(self):
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
282 return
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
283
97265586402b Traipse 'OpenRPG' {090827-00}
sirebral
parents:
diff changeset
284