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

# User Rev Content
1 slacapra 1.1 #!/usr/bin/env python
2    
3 slacapra 1.2 import sys, re
4 slacapra 1.1
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