1# -*- coding: utf-8 -*-
2#
3# Copyright © Spyder Project Contributors
4# Licensed under the terms of the MIT License
5# (see spyder/__init__.py for details)
6
7"""
8Style for IPython Console
9"""
10
11# Local imports
12from spyder.config.gui import get_color_scheme
13
14# Third party imports
15from pygments.style import Style
16from pygments.token import (Name, Keyword, Comment, String, Number,
17                            Punctuation, Operator)
18
19from qtconsole.styles import dark_color
20
21
22def create_qss_style(color_scheme):
23    """Returns a QSS stylesheet with Spyder color scheme settings.
24
25    The stylesheet can contain classes for:
26        Qt: QPlainTextEdit, QFrame, QWidget, etc
27       Pygments: .c, .k, .o, etc. (see PygmentsHighlighter)
28        IPython: .error, .in-prompt, .out-prompt, etc
29    """
30
31    def give_font_weight(is_bold):
32        if is_bold:
33            return 'bold'
34        else:
35            return 'normal'
36
37    def give_font_style(is_italic):
38        if is_italic:
39            return 'italic'
40        else:
41            return 'normal'
42
43    color_scheme = get_color_scheme(color_scheme)
44    fon_c, fon_fw, fon_fs = color_scheme['normal']
45    font_color =  fon_c
46    if dark_color(font_color):
47        in_prompt_color = 'navy'
48        out_prompt_color = 'darkred'
49    else:
50        in_prompt_color = 'lime'
51        out_prompt_color = 'red'
52    background_color = color_scheme['background']
53    error_color = 'red'
54    in_prompt_number_font_weight = 'bold'
55    out_prompt_number_font_weight = 'bold'
56    inverted_background_color = font_color
57    inverted_font_color = background_color
58
59    sheet = """QPlainTextEdit, QTextEdit, ControlWidget {{
60                                          color: {} ;
61                                          background-color: {};
62                                         }}
63              .error {{ color: {}; }}
64              .in-prompt {{ color: {}; }}
65              .in-prompt-number {{ color: {}; font-weight: {}; }}
66              .out-prompt {{ color: {}; }}
67              .out-prompt-number {{ color: {}; font-weight: {}; }}
68              .inverted {{ color: {}; background-color: {}; }}
69              """
70
71    sheet_formatted = sheet.format(font_color, background_color,
72                                   error_color,
73                                   in_prompt_color, in_prompt_color,
74                                   in_prompt_number_font_weight,
75                                   out_prompt_color, out_prompt_color,
76                                   out_prompt_number_font_weight,
77                                   inverted_background_color,
78                                   inverted_font_color)
79
80    return (sheet_formatted, dark_color(font_color))
81
82
83def create_pygments_dict(color_scheme_name):
84    """
85    Create a dictionary that saves the given color scheme as a
86    Pygments style.
87    """
88
89    def give_font_weight(is_bold):
90        if is_bold:
91            return 'bold'
92        else:
93            return ''
94
95    def give_font_style(is_italic):
96        if is_italic:
97            return 'italic'
98        else:
99            return ''
100
101    color_scheme = get_color_scheme(color_scheme_name)
102
103    fon_c, fon_fw, fon_fs = color_scheme['normal']
104    font_color =  fon_c
105    font_font_weight = give_font_weight(fon_fw)
106    font_font_style = give_font_style(fon_fs)
107    key_c, key_fw, key_fs = color_scheme['keyword']
108    keyword_color =  key_c
109    keyword_font_weight = give_font_weight(key_fw)
110    keyword_font_style = give_font_style(key_fs)
111    bui_c, bui_fw, bui_fs = color_scheme['builtin']
112    builtin_color =  bui_c
113    builtin_font_weight = give_font_weight(bui_fw)
114    builtin_font_style = give_font_style(bui_fs)
115    str_c, str_fw, str_fs = color_scheme['string']
116    string_color =  str_c
117    string_font_weight = give_font_weight(str_fw)
118    string_font_style = give_font_style(str_fs)
119    num_c, num_fw, num_fs = color_scheme['number']
120    number_color =  num_c
121    number_font_weight = give_font_weight(num_fw)
122    number_font_style = give_font_style(num_fs)
123    com_c, com_fw, com_fs = color_scheme['comment']
124    comment_color =  com_c
125    comment_font_weight = give_font_weight(com_fw)
126    comment_font_style = give_font_style(com_fs)
127    def_c, def_fw, def_fs = color_scheme['definition']
128    definition_color =  def_c
129    definition_font_weight = give_font_weight(def_fw)
130    definition_font_style = give_font_style(def_fs)
131    ins_c, ins_fw, ins_fs = color_scheme['instance']
132    instance_color =  ins_c
133    instance_font_weight = give_font_weight(ins_fw)
134    instance_font_style = give_font_style(ins_fs)
135
136    font_token = font_font_style + ' ' + font_font_weight + ' ' + font_color
137    definition_token = (definition_font_style + ' ' + definition_font_weight +
138                        ' ' + definition_color)
139    builtin_token = (builtin_font_style + ' ' + builtin_font_weight + ' ' +
140                     builtin_color)
141    instance_token = (instance_font_style + ' ' + instance_font_weight + ' ' +
142                      instance_color)
143    keyword_token = (keyword_font_style + ' ' + keyword_font_weight + ' ' +
144                     keyword_color)
145    comment_token = (comment_font_style + ' ' + comment_font_weight + ' ' +
146                     comment_color)
147    string_token = (string_font_style + ' ' + string_font_weight + ' ' +
148                    string_color)
149    number_token = (number_font_style + ' ' + number_font_weight + ' ' +
150                    number_color)
151
152    syntax_style_dic = {Name: font_token.strip(),
153                        Name.Class: definition_token.strip(),
154                        Name.Function: definition_token.strip(),
155                        Name.Builtin: builtin_token.strip(),
156                        Name.Builtin.Pseudo: instance_token.strip(),
157                        Keyword: keyword_token.strip(),
158                        Keyword.Type: builtin_token.strip(),
159                        Comment: comment_token.strip(),
160                        String: string_token.strip(),
161                        Number: number_token.strip(),
162                        Punctuation: font_token.strip(),
163                        Operator.Word: keyword_token.strip()}
164
165    return syntax_style_dic
166
167
168def create_style_class(color_scheme_name):
169    """Create a Pygments Style class with the given color scheme."""
170
171    class StyleClass(Style):
172        default_style = ""
173        styles = create_pygments_dict(color_scheme_name)
174
175    return StyleClass
176