-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path__init__.py
363 lines (328 loc) · 14.1 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# coding:utf-8
import os
import sys
import re
import sixpad as sp
from sixpad import msg
from sixpad import window as win
from . import goto_regex
from .item import *
from . import tracer
# shortcut programme #
curPage = sp.window.curPage
def get_shortkey(action):
"""get_shortkey(action) -> shorkey, str"""
# shortkeys
shortkey ={
'next_head': ['CTRL+R', None],
'previous_head':['CTRL+SHIFT+R', None],
'next_head1': ['CTRL+&', None],
'previous_head1': ['CTRL+SHIFT+&', None],
'next_head2': ['CTRL+é', None],
'previous_head2': ['CTRL+SHIFT+é', None],
'next_head3': ['CTRL+"', None],
'previous_head3': ['CTRL+SHIFT+"', None],
'next_head4': ["CTRL+'", None],
'previous_head4': ["CTRL+SHIFT+'", None],
'next_head5': ['CTRL+(', None],
'previous_head5': ['CTRL+SHIFT+(', None],
'next_link': ['CTRL+k', None],
'previous_link': ['CTRL+SHIFT+k', None]
} # end shortkey dico
value = shortkey[action]
# test if user set personal key for this action
if value[1]:
# User shortkey found
key = value[1]
else:
# Default shortkey used
key = value[0]
# end if
return key
# end def
def load_markpad(page):
"""Load MarkPad module"""
log.h2('Load Markpad with %s language' % page.mul.name)
# Compile regex
page.mul.compile_regex()
# Create goto functions
page.mul.generate_goto_functions()
# Creating MarkUp menu
log('Create MarkPad menu')
menu_markup = win.menus.add(label = "MarkPad", action = None, index = -2, submenu = True, name = 'markpad', specific = True)
# creat sub menu and global submenus and items
log('creat sub menu and global submenus and items')
submenus, items = creat_submenu(menu_markup, page.mul.goto)
# Accelerator
log('creat accelerators')
accelerator_active = creat_accelerator(page.mul.goto)
return menu_markup, submenus, items
# end def
def creat_submenu(menu_markup, goto):
"""Creat sub menu and item for MarkPad modul
arg : menu_markup, 6pad menu typ
return submenus dico, items dico"""
submenus = {}
items = {}
# Sub Menu
# Goto
submenus['goto'] = menu_markup.add(
label = msg('Goto'), submenu = True, action = None, name = 'goto')
# items in Goto sub menu
# next head
items['next_head'] = submenus['goto'].add(
label = msg('Next head'), action = lambda: goto.next_head(HEAD), accelerator = get_shortkey('next_head'), name = "next_head")
# Previous head
items['previous_head'] = submenus['goto'].add(
label = msg('Previous head'), action = lambda:goto.previous_head(HEAD), accelerator = get_shortkey('previous_head'), name = "previous_head")
# next head 1
items['next_head1'] = submenus['goto'].add(
label = msg('Next level 1 heading'), action = lambda: goto.next_head(HEAD1), accelerator = get_shortkey('next_head1'), name = "next_head1")
# Previous head 1
items['previous_head1'] = submenus['goto'].add(
label = msg('Previous level 1 heading'), action = lambda:goto.previous_head(HEAD1), accelerator = get_shortkey('previous_head1'), name = "previous_head1")
# next link
items['next_link'] = submenus['goto'].add(
label = msg('Next link'), action = lambda: goto.next_link(LINK), accelerator = get_shortkey('next_link'), name = "next_link")
# Previous link
items['previous_link'] = submenus['goto'].add(
label = msg('Previous link'), action = lambda:goto.previous_link(LINK), accelerator = get_shortkey('previous_link'), name = "previous_link")
return submenus, items
# end def
def creat_accelerator(goto):
""" Create accelerators from shorkey dico and return accelerator_active"""
accelerator_active = {}
# Goto
# Next level 2 heading.
accelerator_active['next_head2'] = win.addAccelerator(
get_shortkey('next_head2'), lambda:goto.next_head(HEAD2), True)
# Previous level 2 heading.
accelerator_active['previous_head2'] = win.addAccelerator(
get_shortkey('previous_head2'), lambda:goto.previous_head(HEAD2), True)
# Next level 3 heading.
accelerator_active['next_head3'] = win.addAccelerator(
get_shortkey('next_head3'), lambda:goto.next_head(HEAD3), True)
# Previous level 3 heading.
accelerator_active['previous_head3'] = win.addAccelerator(
get_shortkey('previous_head3'), lambda:goto.previous_head(HEAD3), True)
# Next level 4 heading.
accelerator_active['next_head4'] = win.addAccelerator(
get_shortkey('next_head4'), lambda:goto.next_head(HEAD4), True)
# Previous level 4 heading.
accelerator_active['previous_head4'] = win.addAccelerator(
get_shortkey('previous_head4'), lambda:goto.previous_head(HEAD4), True)
# Next level 5 heading.
accelerator_active['next_head5'] = win.addAccelerator(
get_shortkey('next_head5'), lambda:goto.next_head(HEAD5), True)
# Previous level 5 heading.
accelerator_active['previous_head5'] = win.addAccelerator(
get_shortkey('previous_head5'), lambda:goto.previous_head(HEAD5), True)
return accelerator_active
# end def
def load_translate_file():
"""Load the lang file to translate markpad"""
log.h1('Load translate file')
# Load language
for lang in(sp.locale, 'english'):
lang_file = os.path.join(PLUGIN_PATH, lang + '.lng')
if os.path.isfile(lang_file) :
# Lang file found
log('Lang file found : %s' % lang)
sp.loadTranslation(lang_file)
# end if
# end for
# end def
class MarkupManager():
"""Manage markup language
@ plugin_path : Module path to scan MUL file into markup language directory
* Scan MUL File
* Exctract capabilities into caps dictionary
* Generate MUL instance from extension"""
def __init__(self, plugin_path):
"""Load markdown language definition"""
log.h1('Markup Manager init')
# Load markup language definition from language directory
self.markup_languages = self._fetch_markup_definition(plugin_path)
# Extract extensions capability from each markup language
self.caps = self._extract_capabilitys(self.markup_languages)
# end def
def _fetch_markup_definition(self, plugin_path):
"""Create MUL file dictionary from file present into "markup language" directory"""
log.h2('Scan markup language directory')
# Instanciate mul dictionary
markup_langs = {}
# List mul file
lang_path = os.path.join(plugin_path, 'markup language')
list_file = os.listdir(lang_path)
# Search mul file into language directory
for file_name in list_file:
if '.mul' in file_name[-4:]:
# mul file found.
# fetch language name
mul_name = file_name[:-4]
mul_path = os.path.join(lang_path, file_name)
log.h3('%s.mul' % mul_name)
# Add this markup language into markup definition dictionary
parse_result = self._parse_mul_file(mul_name, mul_path)
# Test parsing result.
if parse_result:
log('"%s" language added in markup manager' % mul_name)
markup_langs[mul_name] = parse_result
# end if # mul file found
# end for # file
log('Scan MUL file completed')
return markup_langs
# end def
def _parse_mul_file(self, mul_name, mul_path):
"""Parse mul file and return MarkupLanguage definition"""
log('Parsing MUL file "%s"' % mul_name)
# Open file.
log('Open file "%s"' % mul_path)
mul_file = open(mul_path, encoding='utf8')
# Instanciate MarkupLanguage class
mul = MarkupManager.MarkupLanguage(mul_name, mul_path)
# Parse file line by line
n_line = 0
for line in mul_file:
n_line +=1
# Test if this line is a comment or empty.
if line[0] in ['#', '\n', '\r']:
# next line
continue
# end if
# remove line ending, dos or unix
line.rstrip('\n\r')
# extract key and value
try :
key, value = line.split('=')
value = eval(value)
# find key type, extension, help or regex
if 'extension' in key:
# Value is a list or one extension compatible
# Convert one extension to a list.
if type(value) == str : value = (value, )
log('Extensions declared : ' + str(value)[1:-1])
mul.extension = value
elif 'help' in key:
# Help page definition
log('Help link : ' + value)
mul.help = value
else:
# Regex definition
log('%s, regex : "%s"' %(key, value))
# Convert item type
try :
key = eval(key)
mul[key] = value
except NameError :
win.warning('Parsing MUL file error.\nFile : "%s"\nRrror at line %d :\n%s\nItem type "%s" does not exist.\nThis item will be ignored.' %(mul_path, n_line, line, key), 'Markpad Error')
log('Warning at line %d : Item type %s does not exist. Item ignored' %( n_line, key))
# end try
# end if
except ValueError and SyntaxError :
win.warning('Parsing MUL file error.\nFile : "%s"\nSyntaxe error at line %d\n%s' %(mul_path, n_line, line), 'Markpad Error')
log('Error at line %d : %s' %( n_line, line))
return None
# end try
# end for
log('Close MUL file')
mul_file.close()
return mul
# end def
def _extract_capabilitys(self, markup_languages):
"""From MarkupManager containing MUL definition, extract markpad capabilities
@ markup_languages, dictionary containing mul dico;
return capability, dictionary. [ext]:"markup language name"
"""
log.h2('Extract Markpad capabilities')
# Instanciate capability dictionary
caps = {}
# Extract extension from each language
for mul in markup_languages.values():
# Verify extension definition.
if not mul.extension:
log('Warning, no "extension" definition found in "%s" markup language' % mul.name)
win.warning('No extension found into "%s" markup language definition. This language will be ignored.' % mul.name, 'Markpad warning')
# next language
continue
# end if
# explore each extension and add it in the capability dictionary with its language
log('"%s" extensions :\n%s' %(mul.name, str(mul.extension)[1:-1]))
for ext in mul.extension:
caps[ext] = mul.name
# end for # , ext
# end for # , mul
return caps
# end def
class MarkupLanguage(dict):
def __init__(self, name, path):
self.name = name
self.path = path
self.help = None
self.extension = None
self._compiled = False
# end def
def compile_regex(self):
if self._compiled:
# Regex already compiled
log('Regex already compiled')
return
# end if
# Compile regex
for item_type, regex_raw in self.items():
log('Compile %s' % item_type)
self[item_type] = re.compile(regex_raw, re.MULTILINE)
# end for
log('Compile completed')
self._compiled = True
# end def
def generate_goto_functions(self):
# Verify is goto function have not already been created
if hasattr(self, "goto"):
log('Gotot functions alredy generated')
else:
log('Creat goto function for this language')
self.goto = goto_regex.Goto(self)
# end def
# end class MarkupLanguage
# end class MarkupManager
def page_opened(page):
"""Start when new page is openned.
find file extension and load markPad if a markup language uses this extension"""
# fetch extension of this new page
log.h1('Page "%s" opened, search kind of this document' % page.name)
ext = os.path.splitext(page.file)[1][1:].lower()
if not ext:
# This page contains a new file or file without extension.
log('Page not saved page or file without extension.')
ext = 'noext'
# end if
log('File extension : %s' % ext)
# Search language for this extension
if ext in markup_manager.caps:
# MUL available for this extension
mul_name = markup_manager.caps[ext]
log('Markup language found : "%s".' %mul_name)
# Add MUL reference in page
page.mul = markup_manager.markup_languages[mul_name]
# Load module markPad
menu_markup, submenus, items = load_markpad(page)
else:
log('No markup language found for this kind of document')
log('Markpad not loaded for "%s".' % page.name)
# end else
# end def
## main ##
# Init log systeme
log_file_path = os.path.join(PLUGIN_PATH, 'log_markpad.md')
log = tracer.Tracer(log_file_path)
log.h1('MarkPad trace')
log.print_time()
# Load lng file to translate markpad
load_translate_file()
# Init Markup Manager.
markup_manager = MarkupManager(PLUGIN_PATH)
# Add event to load module when new page is open
win.addEvent('pageOpened', page_opened)
# Load module for the initial page
page_opened(win.curPage)