##// END OF EJS Templates
exposed pygments styles as ipythonqt options
MinRK -
Show More
@@ -0,0 +1,102 b''
1 """ Style utilities, templates, and defaults for syntax highlighting widgets.
2 """
3 #-----------------------------------------------------------------------------
4 # Imports
5 #-----------------------------------------------------------------------------
6
7 from colorsys import rgb_to_hls
8 from pygments.styles import get_style_by_name
9 from pygments.token import Token
10
11 #-----------------------------------------------------------------------------
12 # Constants
13 #-----------------------------------------------------------------------------
14
15 # The default light style sheet: black text on a white background.
16 default_light_style_template = '''
17 QPlainTextEdit, QTextEdit { background-color: %(bgcolor)s;
18 color: %(fgcolor)s ;
19 selection-background-color: %(select)s}
20 .error { color: red; }
21 .in-prompt { color: navy; }
22 .in-prompt-number { font-weight: bold; }
23 .out-prompt { color: darkred; }
24 .out-prompt-number { font-weight: bold; }
25 '''
26 default_light_style_sheet = default_light_style_template%dict(
27 bgcolor='white', fgcolor='black', select="#ccc")
28 default_light_syntax_style = 'default'
29
30 # The default dark style sheet: white text on a black background.
31 default_dark_style_template = '''
32 QPlainTextEdit, QTextEdit { background-color: %(bgcolor)s;
33 color: %(fgcolor)s ;
34 selection-background-color: %(select)s}
35 QFrame { border: 1px solid grey; }
36 .error { color: red; }
37 .in-prompt { color: lime; }
38 .in-prompt-number { color: lime; font-weight: bold; }
39 .out-prompt { color: red; }
40 .out-prompt-number { color: red; font-weight: bold; }
41 '''
42 default_dark_style_sheet = default_dark_style_template%dict(
43 bgcolor='black', fgcolor='white', select="#555")
44 default_dark_syntax_style = 'monokai'
45
46 def hex_to_rgb(color):
47 """Convert a hex color to rgb integer tuple."""
48 if color.startswith('#'):
49 color = color[1:]
50 if len(color) == 3:
51 color = ''.join([c*2 for c in color])
52 if len(color) != 6:
53 return False
54 try:
55 r = int(color[:2],16)
56 g = int(color[:2],16)
57 b = int(color[:2],16)
58 except ValueError:
59 return False
60 else:
61 return r,g,b
62
63 def dark_color(color):
64 """Check whether a color is 'dark'.
65
66 Currently, this is simply whether the luminance is <50%"""
67 rgb = hex_to_rgb(color)
68 if rgb:
69 return rgb_to_hls(*rgb)[1] < 128
70 else: # default to False
71 return False
72
73 def dark_style(stylename):
74 """Guess whether the background of the style with name 'stylename'
75 counts as 'dark'."""
76 return dark_color(get_style_by_name(stylename).background_color)
77
78 def get_colors(stylename):
79 """Construct the keys to be used building the base stylesheet."""
80 style = get_style_by_name(stylename)
81 fgcolor = style.style_for_token(Token.Text)['color'] or ''
82 if len(fgcolor) in (3,6):
83 # could be 'abcdef' or 'ace' hex, which needs '#' prefix
84 try:
85 int(fgcolor, 16)
86 except TypeError:
87 pass
88 else:
89 fgcolor = "#"+fgcolor
90
91 return dict(
92 bgcolor = style.background_color,
93 select = style.highlight_color,
94 fgcolor = fgcolor
95 )
96
97 def sheet_from_template(name, lightbg=True):
98 """Use one of the base templates, and set bg/fg/select colors."""
99 if lightbg:
100 return default_light_style_template%get_colors(name)
101 else:
102 return default_dark_style_template%get_colors(name) No newline at end of file
@@ -25,33 +25,13 b' from IPython.core.inputsplitter import IPythonInputSplitter, \\'
25 from IPython.core.usage import default_gui_banner
25 from IPython.core.usage import default_gui_banner
26 from IPython.utils.traitlets import Bool, Str
26 from IPython.utils.traitlets import Bool, Str
27 from frontend_widget import FrontendWidget
27 from frontend_widget import FrontendWidget
28 from styles import (default_light_style_sheet, default_dark_style_sheet,
29 default_light_syntax_style, default_dark_syntax_style)
28
30
29 #-----------------------------------------------------------------------------
31 #-----------------------------------------------------------------------------
30 # Constants
32 # Constants
31 #-----------------------------------------------------------------------------
33 #-----------------------------------------------------------------------------
32
34
33 # The default light style sheet: black text on a white background.
34 default_light_style_sheet = '''
35 .error { color: red; }
36 .in-prompt { color: navy; }
37 .in-prompt-number { font-weight: bold; }
38 .out-prompt { color: darkred; }
39 .out-prompt-number { font-weight: bold; }
40 '''
41 default_light_syntax_style = 'default'
42
43 # The default dark style sheet: white text on a black background.
44 default_dark_style_sheet = '''
45 QPlainTextEdit, QTextEdit { background-color: black; color: white }
46 QFrame { border: 1px solid grey; }
47 .error { color: red; }
48 .in-prompt { color: lime; }
49 .in-prompt-number { color: lime; font-weight: bold; }
50 .out-prompt { color: red; }
51 .out-prompt-number { color: red; font-weight: bold; }
52 '''
53 default_dark_syntax_style = 'monokai'
54
55 # Default strings to build and display input and output prompts (and separators
35 # Default strings to build and display input and output prompts (and separators
56 # in between)
36 # in between)
57 default_in_prompt = 'In [<span class="in-prompt-number">%i</span>]: '
37 default_in_prompt = 'In [<span class="in-prompt-number">%i</span>]: '
@@ -7,12 +7,13 b''
7
7
8 # Systemm library imports
8 # Systemm library imports
9 from PyQt4 import QtGui
9 from PyQt4 import QtGui
10
10 from pygments.styles import get_all_styles
11 # Local imports
11 # Local imports
12 from IPython.external.argparse import ArgumentParser
12 from IPython.external.argparse import ArgumentParser
13 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
13 from IPython.frontend.qt.console.frontend_widget import FrontendWidget
14 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
14 from IPython.frontend.qt.console.ipython_widget import IPythonWidget
15 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
15 from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
16 from IPython.frontend.qt.console import styles
16 from IPython.frontend.qt.kernelmanager import QtKernelManager
17 from IPython.frontend.qt.kernelmanager import QtKernelManager
17
18
18 #-----------------------------------------------------------------------------
19 #-----------------------------------------------------------------------------
@@ -129,7 +130,7 b' def main():'
129 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
130 kgroup.add_argument('--rep', type=int, metavar='PORT', default=0,
130 help='set the REP channel port [default random]')
131 help='set the REP channel port [default random]')
131 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
132 kgroup.add_argument('--hb', type=int, metavar='PORT', default=0,
132 help='set the heartbeat port [default: random]')
133 help='set the heartbeat port [default random]')
133
134
134 egroup = kgroup.add_mutually_exclusive_group()
135 egroup = kgroup.add_mutually_exclusive_group()
135 egroup.add_argument('--pure', action='store_true', help = \
136 egroup.add_argument('--pure', action='store_true', help = \
@@ -148,6 +149,14 b' def main():'
148 help='enable rich text support')
149 help='enable rich text support')
149 wgroup.add_argument('--gui-completion', action='store_true',
150 wgroup.add_argument('--gui-completion', action='store_true',
150 help='use a GUI widget for tab completion')
151 help='use a GUI widget for tab completion')
152 wgroup.add_argument('--style', type=str,
153 help='specify a pygments style by name. \
154 Valid are: %s'%(list(get_all_styles())))
155 wgroup.add_argument('--stylesheet', type=str,
156 help="path to a custom CSS stylesheet.")
157 wgroup.add_argument('--dark', action='store_true',
158 help="use the dark style template instead of lightbg.\
159 If --style is not specified, the default dark style is used.")
151
160
152 args = parser.parse_args()
161 args = parser.parse_args()
153
162
@@ -186,6 +195,33 b' def main():'
186 widget.gui_completion = args.gui_completion
195 widget.gui_completion = args.gui_completion
187 widget.kernel_manager = kernel_manager
196 widget.kernel_manager = kernel_manager
188
197
198 # configure the style:
199 if not args.pure: # only IPythonWidget supports styles
200 if args.style:
201 # guess whether it's a dark style:
202 dark = args.dark or styles.dark_style(args.style)
203 widget.syntax_style = args.style
204 widget.style_sheet = styles.sheet_from_template(args.style, not dark)
205 widget._syntax_style_changed()
206 widget._style_sheet_changed()
207 elif args.dark:
208 # use default dark style
209 widget.set_default_style(lightbg=False)
210 else:
211 # this is redundant for now, but allows the widget's
212 # defaults to change
213 widget.set_default_style(lightbg=True)
214
215 if args.stylesheet:
216 # we got an expicit stylesheet
217 if os.path.isfile(args.stylesheet):
218 with open(args.stylesheet) as f:
219 sheet = f.read()
220 widget.style_sheet = sheet
221 widget._style_sheet_changed()
222 else:
223 raise IOError("Stylesheet %r not found."%args.stylesheet)
224
189 # Create the main window.
225 # Create the main window.
190 window = MainWindow(app, widget, args.existing, may_close=local_kernel)
226 window = MainWindow(app, widget, args.existing, may_close=local_kernel)
191 window.setWindowTitle('Python' if args.pure else 'IPython')
227 window.setWindowTitle('Python' if args.pure else 'IPython')
General Comments 0
You need to be logged in to leave comments. Login now