Completed
Branch master (4a6da2)
by Christophe
28s
created

add_definition()   A

Complexity

Conditions 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
c 1
b 0
f 0
dl 0
loc 13
rs 9.4285
1
#!/usr/bin/env python
2
3
"""
4
Pandoc filter for changing color in LaTeX
5
"""
6
7
from panflute import run_filter, debug, Span, Div, RawInline, RawBlock, MetaInlines
8
9
def x11colors():
10
    # See https://www.w3.org/TR/css-color-3/#svg-color
11
    return {
12
        'aliceblue': 'F0F8FF',
13
        'antiquewhite': 'FAEBD7',
14
        'aqua': '00FFFF',
15
        'aquamarine': '7FFFD4',
16
        'azure': 'F0FFFF',
17
        'beige': 'F5F5DC',
18
        'bisque': 'FFE4C4',
19
        'black': '000000',
20
        'blanchedalmond': 'FFEBCD',
21
        'blue': '0000FF',
22
        'blueviolet': '8A2BE2',
23
        'brown': 'A52A2A',
24
        'burlywood': 'DEB887',
25
        'cadetblue': '5F9EA0',
26
        'chartreuse': '7FFF00',
27
        'chocolate': 'D2691E',
28
        'coral': 'FF7F50',
29
        'cornflowerblue': '6495ED',
30
        'cornsilk': 'FFF8DC',
31
        'crimson': 'DC143C',
32
        'cyan': '00FFFF',
33
        'darkblue': '00008B',
34
        'darkcyan': '008B8B',
35
        'darkgoldenrod': 'B8860B',
36
        'darkgray': 'A9A9A9',
37
        'darkgreen': '006400',
38
        'darkgrey': 'A9A9A9',
39
        'darkkhaki': 'BDB76B',
40
        'darkmagenta': '8B008B',
41
        'darkolivegreen': '556B2F',
42
        'darkorange': 'FF8C00',
43
        'darkorchid': '9932CC',
44
        'darkred': '8B0000',
45
        'darksalmon': 'E9967A',
46
        'darkseagreen': '8FBC8F',
47
        'darkslateblue': '483D8B',
48
        'darkslategray': '2F4F4F',
49
        'darkslategrey': '2F4F4F',
50
        'darkturquoise': '00CED1',
51
        'darkviolet': '9400D3',
52
        'deeppink': 'FF1493',
53
        'deepskyblue': '00BFFF',
54
        'dimgray': '696969',
55
        'dimgrey': '696969',
56
        'dodgerblue': '1E90FF',
57
        'firebrick': 'B22222',
58
        'floralwhite': 'FFFAF0',
59
        'forestgreen': '228B22',
60
        'fuchsia': 'FF00FF',
61
        'gainsboro': 'DCDCDC',
62
        'ghostwhite': 'F8F8FF',
63
        'gold': 'FFD700',
64
        'goldenrod': 'DAA520',
65
        'gray': '808080',
66
        'green': '008000',
67
        'greenyellow': 'ADFF2F',
68
        'grey': '808080',
69
        'honeydew': 'F0FFF0',
70
        'hotpink': 'FF69B4',
71
        'indianred': 'CD5C5C',
72
        'indigo': '4B0082',
73
        'ivory': 'FFFFF0',
74
        'khaki': 'F0E68C',
75
        'lavender': 'E6E6FA',
76
        'lavenderblush': 'FFF0F5',
77
        'lawngreen': '7CFC00',
78
        'lemonchiffon': 'FFFACD',
79
        'lightblue': 'ADD8E6',
80
        'lightcoral': 'F08080',
81
        'lightcyan': 'E0FFFF',
82
        'lightgoldenrodyellow': 'FAFAD2',
83
        'lightgray': 'D3D3D3',
84
        'lightgreen': '90EE90',
85
        'lightgrey': 'D3D3D3',
86
        'lightpink': 'FFB6C1',
87
        'lightsalmon': 'FFA07A',
88
        'lightseagreen': '20B2AA',
89
        'lightskyblue': '87CEFA',
90
        'lightslategray': '778899',
91
        'lightslategrey': '778899',
92
        'lightsteelblue': 'B0C4DE',
93
        'lightyellow': 'FFFFE0',
94
        'lime': '00FF00',
95
        'limegreen': '32CD32',
96
        'linen': 'FAF0E6',
97
        'magenta': 'FF00FF',
98
        'maroon': '800000',
99
        'mediumaquamarine': '66CDAA',
100
        'mediumblue': '0000CD',
101
        'mediumorchid': 'BA55D3',
102
        'mediumpurple': '9370DB',
103
        'mediumseagreen': '3CB371',
104
        'mediumslateblue': '7B68EE',
105
        'mediumspringgreen': '00FA9A',
106
        'mediumturquoise': '48D1CC',
107
        'mediumvioletred': 'C71585',
108
        'midnightblue': '191970',
109
        'mintcream': 'F5FFFA',
110
        'mistyrose': 'FFE4E1',
111
        'moccasin': 'FFE4B5',
112
        'navajowhite': 'FFDEAD',
113
        'navy': '000080',
114
        'oldlace': 'FDF5E6',
115
        'olive': '808000',
116
        'olivedrab': '6B8E23',
117
        'orange': 'FFA500',
118
        'orangered': 'FF4500',
119
        'orchid': 'DA70D6',
120
        'palegoldenrod': 'EEE8AA',
121
        'palegreen': '98FB98',
122
        'paleturquoise': 'AFEEEE',
123
        'palevioletred': 'DB7093',
124
        'papayawhip': 'FFEFD5',
125
        'peachpuff': 'FFDAB9',
126
        'peru': 'CD853F',
127
        'pink': 'FFC0CB',
128
        'plum': 'DDA0DD',
129
        'powderblue': 'B0E0E6',
130
        'purple': '800080',
131
        'red': 'FF0000',
132
        'rosybrown': 'BC8F8F',
133
        'royalblue': '4169E1',
134
        'saddlebrown': '8B4513',
135
        'salmon': 'FA8072',
136
        'sandybrown': 'F4A460',
137
        'seagreen': '2E8B57',
138
        'seashell': 'FFF5EE',
139
        'sienna': 'A0522D',
140
        'silver': 'C0C0C0',
141
        'skyblue': '87CEEB',
142
        'slateblue': '6A5ACD',
143
        'slategray': '708090',
144
        'slategrey': '708090',
145
        'snow': 'FFFAFA',
146
        'springgreen': '00FF7F',
147
        'steelblue': '4682B4',
148
        'tan': 'D2B48C',
149
        'teal': '008080',
150
        'thistle': 'D8BFD8',
151
        'tomato': 'FF6347',
152
        'turquoise': '40E0D0',
153
        'violet': 'EE82EE',
154
        'wheat': 'F5DEB3',
155
        'white': 'FFFFFF',
156
        'whitesmoke': 'F5F5F5',
157
        'yellow': 'FFFF00',
158
        'yellowgreen': '9ACD32'
159
    }
160
161
def latex_code(color):
162
    return '\\color{' + color + '} '
163
164
def get_correct_color(color):
165
    if color in x11colors():
166
        return color
167
    else:
168
        debug('[WARNING] pandoc-latex-color: ' + color + ' is not a correct X11 color; using black')
169
        return 'black'
170
171
def add_latex(elem, latex):
172
    # Is it a Span?
173
    if isinstance(elem, Span):
174
        elem.content.insert(0, RawInline(latex, 'tex'))
175
176
    # Is it a Div?
177
    elif isinstance(elem, Div):
178
        elem.content.insert(0, RawBlock('{' + latex, 'tex'))
179
        elem.content.append(RawBlock('}', 'tex'))
180
181
def color(elem, doc):
182
    # Is it in the right format and is it a Span, Div, Code or CodeBlock?
183
    if doc.format == 'latex' and elem.tag in ['Span', 'Div']:
184
185
        # Is there a latex-color attribute?
186
        if 'latex-color' in elem.attributes:
187
            return add_latex(elem, latex_code(get_correct_color(elem.attributes['latex-color'])))
188
        else:
189
            # Get the classes
190
            classes = set(elem.classes)
191
192
            # Loop on all color definition
193
            for definition in doc.defined:
194
195
                # Are the classes correct?
196
                if classes >= definition['classes']:
197
                    return add_latex(elem, definition['latex'])
198
199
def prepare(doc):
200
    # Prepare the definitions
201
    doc.defined = []
202
203
    # Get the meta data
204
    meta = doc.get_metadata('pandoc-latex-color')
205
206
    if isinstance(meta, list):
207
208
        # Loop on all definitions
209
        for definition in meta:
210
211
            # Verify the definition
212
            if isinstance(definition, dict) and 'classes' in definition and isinstance(definition['classes'], list):
213
                add_definition(doc.defined, definition)
214
215
def add_definition(defined, definition):
216
    # Get the classes
217
    classes = definition['classes']
218
219
    # Get the color
220
    if 'color' in definition:
221
        color = get_correct_color(definition['color'])
222
    else:
223
        debug('[WARNING] pandoc-latex-color: color is not defined; using black')
224
        color = 'black'
225
226
    # Add a definition
227
    defined.append({'classes' : set(classes), 'latex': latex_code(color)})
228
229
def finalize(doc):
230
    # Add header-includes if necessary
231
    if 'header-includes' not in doc.metadata:
232
        doc.metadata['header-includes'] = []
233
234
    # Add usefull LaTexPackage
235
    doc.metadata['header-includes'].append(MetaInlines(RawInline('\\usepackage{xcolor}', 'tex')))
236
237
def main(doc = None):
238
    return run_filter(color, prepare=prepare, finalize=finalize, doc=doc)
239
240
if __name__ == '__main__':
241
    main()
242
243