ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/CRAB/python/TerminalController.py
Revision: 1.2
Committed: Wed Jan 17 18:17:59 2007 UTC (18 years, 3 months ago) by slacapra
Content type: text/x-python
Branch: MAIN
CVS Tags: CRAB_2_9_1, CRAB_2_9_1_pre2, CRAB_2_9_1_pre1, CRAB_2_9_0, CRAB_2_9_0_pre2, CRAB_2_9_0_pre1, CRAB_2_8_8, CRAB_2_8_8_pre1, CRAB_2_8_7_patch3, CRAB_2_8_7_patch2, CRAB_2_8_7_patch1, CRAB_2_8_7, CRAB_2_8_7_pre2, CRAB_2_8_7_pre1, CRAB_2_8_6, CRAB_2_8_6_pre1, CRAB_2_8_5_patch3, CRAB_2_8_5_patch2, CRAB_2_8_5_patch1, CRAB_2_8_5, CRAB_2_8_5_pre5, CRAB_2_8_5_pre4, CRAB_2_8_5_pre3, CRAB_2_8_4_patch3, CRAB_2_8_5_pre2, CRAB_2_8_4_patch2, CRAB_2_8_5_pre1, CRAB_2_8_4_patch1, CRAB_2_8_4, CRAB_2_8_4_pre5, CRAB_2_8_4_pre4, CRAB_2_8_4_pre3, CRAB_2_8_4_pre2, CRAB_2_8_4_pre1, CRAB_2_8_3, CRAB_2_8_3_pre4, CRAB_2_8_3_pre3, CRAB_2_8_3_pre2, CRAB_2_8_3_pre1, CRAB_2_8_2_patch1, CRAB_2_8_2, CRAB_2_8_2_pre5, CRAB_2_8_2_pre4, CRAB_2_8_2_pre3, CRAB_2_8_2_pre2, CRAB_2_8_2_pre1, CRAB_2_8_1, CRAB_2_8_0, CRAB_2_8_0_pre1, CRAB_2_7_10_pre3, CRAB_2_7_9_patch2_pre1, CRAB_2_7_10_pre2, CRAB_2_7_10_pre1, CRAB_2_7_9_patch1, CRAB_2_7_9, CRAB_2_7_9_pre5, CRAB_2_7_9_pre4, CRAB_2_7_9_pre3, CRAB_2_7_9_pre2, CRAB_2_7_8_patch2, CRAB_2_7_9_pre1, CRAB_2_7_8_patch2_pre1, CRAB_2_7_8_patch1, CRAB_2_7_8_patch1_pre1, CRAB_2_7_8, CRAB_2_7_8_pre3, CRAB_2_7_8_pre2, CRAB_2_7_8_dash3, CRAB_2_7_8_dash2, CRAB_2_7_8_dash, CRAB_2_7_7_patch1, CRAB_2_7_7_patch1_pre1, CRAB_2_7_8_pre1, CRAB_2_7_7, CRAB_2_7_7_pre2, CRAB_2_7_7_pre1, CRAB_2_7_6_patch1, CRAB_2_7_6, CRAB_2_7_6_pre1, CRAB_2_7_5_patch1, CRAB_2_7_5, CRAB_2_7_5_pre3, CRAB_2_7_5_pre2, CRAB_2_7_5_pre1, CRAB_2_7_4_patch1, CRAB_2_7_4, CRAB_2_7_4_pre6, CRAB_2_7_4_pre5, CRAB_2_7_4_pre4, CRAB_2_7_4_pre3, CRAB_2_7_4_pre2, CRAB_2_7_4_pre1, CRAB_2_7_3, CRAB_2_7_3_pre3, CRAB_2_7_3_pre3_beta, CRAB_2_7_3_pre2, CRAB_2_7_3_pre2_beta, CRAB_2_7_3_pre1, CRAB_2_7_3_beta3, CRAB_2_7_3_beta2, CRAB_2_7_3_beta1, CRAB_2_7_3_beta, CRAB_2_7_2_p1, CRAB_2_7_1_branch_firstMERGE, CRAB_2_7_2, CRAB_2_7_2_pre4, CRAB_2_7_2_pre3, CRAB_2_7_2_pre2, CRAB_2_7_2_pre1, CRAB_2_7_1, fede_170310, CRAB_2_7_1_pre12, CRAB_2_7_1_pre11, CRAB_2_7_1_pre10, CRAB_2_7_1_pre9, CRAB_LumiMask, CRAB_2_7_lumi, from_LimiMask, CRAB_2_7_1_pre8, CRAB_2_7_1_pre6, CRAB_2_7_1_pre5, CRAB_2_7_1_wmbs_pre4, CRAB_2_7_1_pre4, CRAB_2_7_1_pre3, CRAB_2_6_6_pre6, CRAB_2_7_1_pre2, CRAB_2_6_6_pre5, CRAB_2_7_1_pre1, CRAB_2_6_6_pre4, CRAB_2_6_6_pre3, CRAB_2_6_6_pre2, CRAB_2_6_6_check, CRAB_2_6_6, CRAB_2_6_6_pre1, CRAB_2_7_0, CRAB_2_6_5, CRAB_2_7_0_pre8, CRAB_2_6_5_pre1, CRAB_2_7_0_pre7, CRAB_2_6_4, CRAB_2_7_0_pre6, CRAB_2_6_4_pre1, CRAB_2_7_0_pre5, CRAB_2_6_3_patch_2, CRAB_2_6_3_patch_2_pre2, CRAB_2_6_3_patch_2_pre1, CRAB_2_6_3_patch_1, CRAB_2_7_0_pre4, CRAB_2_7_0_pre3, CRAB_2_6_3, CRAB_2_6_3_pre5, CRAB_2_6_3_pre4, CRAB_2_6_3_pre3, CRAB_2_6_3_pre2, CRAB_2_7_0_pre2, CRAB_2_6_3_pre1, test_1, CRAB_2_7_0_pre1, CRAB_2_6_2, CRAB_2_6_2_pre2, CRAB_2_6_2_pre1, CRAB_2_6_1_pre4, CRAB_2_6_1_pre3, CRAB_2_6_1_pre2, CRAB_2_6_1_pre1, CRAB_2_6_1, CRAB_2_6_0, CRAB_2_6_0_pre14, CRAB_2_6_0_pre13, CRAB_2_6_0_pre12, CRAB_2_6_0_pre11, CRAB_2_6_0_pre10, CRAB_2_6_0_pre9, CRAB_2_6_0_pre8, CRAB_2_6_0_pre7, CRAB_2_6_0_pre6, CRAB_2_6_0_pre5, CRAB_2_6_0_pre4, CRAB_2_6_0_pre3, CRAB_2_6_0_pre2, CRAB_2_6_0_pre1, CRAB_2_5_1, CRAB_2_5_1_pre4, CRAB_2_5_1_pre3, CRAB_2_5_1_pre2, CRAB_2_5_1_pre1, CRAB_2_5_0, CRAB_2_5_0_pre7, CRAB_2_5_0_pre6, CRAB_2_5_0_pre5, CRAB_2_5_0_pre4, CRAB_2_5_0_pre3, CRAB_2_5_0_pre2, CRAB_2_5_0_pre1, CRAB_2_4_4, CRAB_2_4_4_pre6, CRAB_2_4_4_pre5, CRAB_2_4_4_pre4, CRAB_2_4_4_pre3, CRAB_2_4_4_pre2, CRAB_2_4_4_pre1, CRAB_2_4_3, CRAB_2_4_3_pre8, CRAB_2_4_3_pre7, CRAB_2_4_3_pre6, CRAB_2_4_3_pre5, CRAB_2_4_3_pre3, CRAB_2_4_3_pre2, CRAB_2_4_3_pre1, CRAB_2_4_2, CRAB_2_4_2_pre3, CRAB_2_4_2_pre2, CRAB_2_4_2_pre1, CRAB_2_4_1, CRAB_2_4_1_pre4, CRAB_2_4_1_pre3, CRAB_2_4_1_pre2, CRAB_2_4_1_pre1, CRAB_2_4_0_Tutorial, CRAB_2_4_0_Tutorial_pre1, CRAB_2_4_0, CRAB_2_4_0_pre9, CRAB_2_4_0_pre8, CRAB_2_4_0_pre7, CRAB_2_4_0_pre6, CRAB_2_4_0_pre5, CRAB_2_4_0_pre4, CRAB_2_4_0_pre3, CRAB_2_4_0_pre2, CRAB_2_4_0_pre1, CRAB_DLS_PHED1, CRAB_DLS_PHED, CRAB_2_3_2_Fnal, CRAB_2_3_2, CRAB_2_3_2_pre7, CRAB_2_3_2_pre5, CRAB_2_3_2_pre4, CRAB_2_3_2_pre3, CRAB_2_3_2_pre2, CRAB_2_3_2_pre1, CRAB_2_4_0_test, CRAB_2_3_1, CRAB_2_3_1_pre6, CRAB_2_3_1_pre5, CRAB_2_3_1_pre4, CRAB_2_3_1_pre3, CRAB_2_3_1_pre2, CRAB_2_3_1_pre1, CRAB_2_3_0, CRAB_2_3_0_pre6, CRAB_2_3_0_pre1, CRAB_2_2_2_pre5, CRAB_2_2_2_pre4, CRAB_2_2_2_pre3, CRAB_2_2_2_pre2, CRAB_2_2_2_pre1, CRAB_2_2_1, CRAB_2_2_1_pre6, CRAB_2_2_1_pre5, CRAB_2_2_1_pre4, PRODCOMMON_0_10_7_testCS2, CRAB_2_2_1_pre3, CRAB_2_2_1_pre2, CRAB_2_2_1_pre1, CRAB_2_2_0, CRAB_2_2_0_pre21, CRAB_2_2_0_pre19, CRAB_2_2_0_pre18, CRAB_2_2_0_pre17, CRAB_2_2_0_pre16, CRAB_2_2_0_pre15, CRAB_2_2_0_pre13, CRAB_2_2_0_pre12, CRAB_2_2_0_pre11, CRAB_2_2_0_pre10, bp_osg_bdii, CRAB_2_2_0_pre9, CRAB_2_2_0_pre8, CRAB_2_2_0_pre7, CRAB_2_1_2, CRAB_2_2_0_pre5, CRAB_2_1_2_pre2, CRAB_2_1_2_pre1, CRAB_2_2_0_pre4, CRAB_2_2_0_pre2, CRAB_2_1_1, CRAB_2_1_1_pre3, CRAB_2_2_0_pre1, CRAB_2_1_1_pre1, CRAB_2_1_0, CRAB_2_1_0_pre6, CRAB_2_1_0_pre5, CRAB_2_1_0_pre4, CRAB_2_1_0_pre3, CRAB_2_1_0_pre2, CRAB_2_1_0_pre1, CRAB_2_0_4, CRAB_2_0_4_pre2, CRAB_2_0_4_pre1, CRAB_2_0_3, CRAB_2_0_3_pre1, CRAB_2_0_2, CRAB_2_0_2_pre6, CRAB_2_0_2_pre5, CRAB_2_0_2_pre4, CRAB_2_0_2_pre3, CRAB_1_5_4_SLC3, CRAB_1_5_4_SLC3_pre4, CRAB_2_0_2_pre2, CRAB_2_0_2_pre1, CRAB_1_5_4_SLC3_pre3, CRAB_2_0_1, CRAB_1_5_4_SLC3_pre2, CRAB_2_0_1_pre1, CRAB_1_5_4_SLC3_pre1, CRAB_2_0_0, CRAB_2_0_0_pre10, CRAB_2_0_0_pre9, CRAB_1_5_4, CRAB_1_5_4_pre2, CRAB_1_5_4_pre1, CRAB_2_0_0_pre7, CRAB_2_0_0_pre6, CRAB_1_5_3, CRAB_1_5_3_pre5, CRAB_1_5_3_pre4, CRAB_2_0_0_pre5, CRAB_1_5_3_pre3, configure, CRAB_2_0_0_pre4, CRAB_1_5_3_pre2, CRAB_1_5_3_pre1, CRAB_2_0_0_pre3, CRAB_1_5_2, CRAB_2_0_0_pre2, CRAB_2_0_0_pre1, CRAB_1_5_1, CRAB_1_5_1_pre4, CRAB_1_5_1_pre3, CRAB_1_5_1_pre2, CRAB_1_5_1_pre1, CRAB_1_5_0, CRAB_1_5_0_pre9, CRAB_1_5_0_pre8, CRAB_1_5_0_pre7, CRAB_1_5_0_pre6, CRAB_1_5_0_pre5, CRAB_1_5_0_pre4, HEAD
Branch point for: CRAB_multiout, CRAB_2_7_1_branch, Lumi2_8, CRAB_2_6_X_br, AnaDataSet, CRAB_2_3_0_br, osg_bdii, CRAB_2_1_2_br, CRAB_2_1_1_pre2, CRAB_1_5_4_SLC3_pre4_br, CRAB_1_5_4_SLC3_start
Changes since 1.1: +1 -1 lines
Log Message:
many minor fixes reported by pychecker, mostly unsude import and unused variables

File Contents

# Content
1 #!/usr/bin/env python
2
3 import sys, re
4
5 class TerminalController:
6 """
7 A class that can be used to portably generate formatted output to
8 a terminal.
9
10 `TerminalController` defines a set of instance variables whose
11 values are initialized to the control sequence necessary to
12 perform a given action. These can be simply included in normal
13 output to the terminal:
14
15 >>> term = TerminalController()
16 >>> print 'This is '+term.GREEN+'green'+term.NORMAL
17
18 Alternatively, the `render()` method can used, which replaces
19 '${action}' with the string required to perform 'action':
20
21 >>> term = TerminalController()
22 >>> print term.render('This is ${GREEN}green${NORMAL}')
23
24 If the terminal doesn't support a given action, then the value of
25 the corresponding instance variable will be set to ''. As a
26 result, the above code will still work on terminals that do not
27 support color, except that their output will not be colored.
28 Also, this means that you can test whether the terminal supports a
29 given action by simply testing the truth value of the
30 corresponding instance variable:
31
32 >>> term = TerminalController()
33 >>> if term.CLEAR_SCREEN:
34 ... print 'This terminal supports clearning the screen.'
35
36 Finally, if the width and height of the terminal are known, then
37 they will be stored in the `COLS` and `LINES` attributes.
38 """
39 # Cursor movement:
40 BOL = '' #: Move the cursor to the beginning of the line
41 UP = '' #: Move the cursor up one line
42 DOWN = '' #: Move the cursor down one line
43 LEFT = '' #: Move the cursor left one char
44 RIGHT = '' #: Move the cursor right one char
45
46 # Deletion:
47 CLEAR_SCREEN = '' #: Clear the screen and move to home position
48 CLEAR_EOL = '' #: Clear to the end of the line.
49 CLEAR_BOL = '' #: Clear to the beginning of the line.
50 CLEAR_EOS = '' #: Clear to the end of the screen
51
52 # Output modes:
53 BOLD = '' #: Turn on bold mode
54 BLINK = '' #: Turn on blink mode
55 DIM = '' #: Turn on half-bright mode
56 REVERSE = '' #: Turn on reverse-video mode
57 NORMAL = '' #: Turn off all modes
58
59 # Cursor display:
60 HIDE_CURSOR = '' #: Make the cursor invisible
61 SHOW_CURSOR = '' #: Make the cursor visible
62
63 # Terminal size:
64 COLS = None #: Width of the terminal (None for unknown)
65 LINES = None #: Height of the terminal (None for unknown)
66
67 # Foreground colors:
68 BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
69
70 # Background colors:
71 BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
72 BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
73
74 _STRING_CAPABILITIES = """
75 BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
76 CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
77 BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
78 HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
79 _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
80 _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
81
82 def __init__(self, term_stream=sys.stdout):
83 """
84 Create a `TerminalController` and initialize its attributes
85 with appropriate values for the current terminal.
86 `term_stream` is the stream that will be used for terminal
87 output; if this stream is not a tty, then the terminal is
88 assumed to be a dumb terminal (i.e., have no capabilities).
89 """
90 # Curses isn't available on all platforms
91 try: import curses
92 except: return
93
94 # If the stream isn't a tty, then assume it has no capabilities.
95 if not term_stream.isatty(): return
96
97 # Check the terminal type. If we fail, then assume that the
98 # terminal has no capabilities.
99 try: curses.setupterm()
100 except: return
101
102 # Look up numeric capabilities.
103 self.COLS = curses.tigetnum('cols')
104 self.LINES = curses.tigetnum('lines')
105
106 # Look up string capabilities.
107 for capability in self._STRING_CAPABILITIES:
108 (attrib, cap_name) = capability.split('=')
109 setattr(self, attrib, self._tigetstr(cap_name) or '')
110
111 # Colors
112 set_fg = self._tigetstr('setf')
113 if set_fg:
114 for i,color in zip(range(len(self._COLORS)), self._COLORS):
115 setattr(self, color, curses.tparm(set_fg, i) or '')
116 set_fg_ansi = self._tigetstr('setaf')
117 if set_fg_ansi:
118 for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
119 setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
120 set_bg = self._tigetstr('setb')
121 if set_bg:
122 for i,color in zip(range(len(self._COLORS)), self._COLORS):
123 setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
124 set_bg_ansi = self._tigetstr('setab')
125 if set_bg_ansi:
126 for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
127 setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
128
129 def _tigetstr(self, cap_name):
130 # String capabilities can include "delays" of the form "$<2>".
131 # For any modern terminal, we should be able to just ignore
132 # these, so strip them out.
133 import curses
134 cap = curses.tigetstr(cap_name) or ''
135 return re.sub(r'\$<\d+>[/*]?', '', cap)
136
137 def render(self, template):
138 """
139 Replace each $-substitutions in the given template string with
140 the corresponding terminal control string (if it's defined) or
141 '' (if it's not).
142 """
143 return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
144
145 def _render_sub(self, match):
146 s = match.group()
147 if s == '$$': return s
148 else: return getattr(self, s[2:-1])
149
150
151 if __name__ == '__main__':
152 term = TerminalController()
153 print 'This is '+term.GREEN+term.BG_WHITE+'green'+term.NORMAL