forked from SublimeText-Markdown/MarkdownEditing
-
Notifications
You must be signed in to change notification settings - Fork 1
/
insert_references.py
156 lines (118 loc) · 5.14 KB
/
insert_references.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
# -*- coding: UTF-8 -*-
import sublime
import sublime_plugin
import re
def get_clipboard_if_url():
# If the clipboard contains an URL, return it
# Otherwise, return an empty string
re_match_urls = re.compile(r"""((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|(([^\s()<>]+|(([^\s()<>]+)))*))+(?:(([^\s()<>]+|(([^\s()<>]+)))*)|[^\s`!()[]{};:'".,<>?«»“”‘’]))""", re.DOTALL)
m = re_match_urls.search(sublime.get_clipboard())
return m.group() if m else ''
def mangle_url(url):
url = url.strip()
if re.match(r'^([a-z0-9-]+\.)+\w{2,4}', url, re.IGNORECASE):
url = 'http://' + url
return url
def check_for_link(view, url):
titles = []
# Check if URL is already present as reference link
view.find_all(r'^\s{0,3}\[([^^\]]+)\]:[ \t]+' + re.escape(url) + '$', 0, '$1', titles)
return titles[0] if titles else None
def append_reference_link(edit, view, title, url):
# Detect if file ends with \n
if view.substr(view.size() - 1) == '\n':
nl = ''
else:
nl = '\n'
# Append the new reference link to the end of the file
view.insert(edit, view.size(), '{0}[{1}]: {2}\n'.format(nl, title, url))
def insert_references(edit, view, title):
# Add a reference with given title at the current cursor or around the current selection(s)
sels = view.sel()
caret = []
for sel in sels:
text = view.substr(sel)
# If something is selected...
if len(text) > 0:
# ... turn the selected text into the link text
view.replace(edit, sel, "[{0}][{1}]".format(text, title))
else:
# Add the link, with empty link text, and the caret positioned
# ready to type the link text
view.replace(edit, sel, "[][{0}]".format(title))
caret += [sublime.Region(sel.begin() + 1, sel.begin() + 1)]
if len(caret) > 0:
sels.clear()
for c in caret:
sels.add(c)
# Inspired by http://www.leancrew.com/all-this/2012/08/markdown-reference-links-in-bbedit/
# Appends a new reference link to end of document, using a user-input name and URL.
# Then inserts a reference to the link at the current selection(s).
class InsertNamedReferenceCommand(sublime_plugin.TextCommand):
def description(self):
return 'Insert Numbered Reference Link'
def run(self, edit):
self.view.window().show_input_panel(
'URL to link to:',
get_clipboard_if_url(),
self.receive_link,
None, None)
def receive_link(self, linkurl):
linkurl = mangle_url(linkurl)
newref = check_for_link(self.view, linkurl)
if newref:
# Link already exists, reuse existing reference
self.insert_link(linkurl, newref, False)
else:
self.view.window().show_input_panel(
'Name for reference:', '',
lambda newref: self.insert_link(linkurl, newref),
None, None)
def insert_link(self, linkurl, newref, actually_insert=True):
# Check if title is already present as reference
if actually_insert and self.view.find(r'^\s{0,3}\[' + re.escape(newref) + '\]:[ \t]+', 0):
sublime.error_message('A reference named "' + newref + '" already exists.')
self.view.window().show_input_panel(
'Name for reference:', '',
lambda newref: self.insert_link(linkurl, newref),
None, None)
return
edit = self.view.begin_edit()
try:
if actually_insert:
append_reference_link(edit, self.view, newref, linkurl)
insert_references(edit, self.view, newref)
finally:
self.view.end_edit(edit)
def is_enabled(self):
return self.view.sel()
# Inspired by http://www.leancrew.com/all-this/2012/08/markdown-reference-links-in-bbedit/
# Appends a new reference link to end of document, using an autoincrementing number as the reference title.
# Then inserts a reference to the link at the current selection(s).
class InsertNumberedReferenceCommand(sublime_plugin.TextCommand):
def description(self):
return 'Insert Numbered Reference Link'
def run(self, edit):
self.view.window().show_input_panel(
'URL to link to:',
get_clipboard_if_url(),
self.insert_link,
None, None)
def insert_link(self, linkurl):
edit = self.view.begin_edit()
try:
linkurl = mangle_url(linkurl)
newref = check_for_link(self.view, linkurl)
if not newref:
# Find the next reference number
reflinks = self.view.find_all(r'(?<=^\[)(\d+)(?=\]: )')
if len(reflinks) == 0:
newref = 1
else:
newref = max(int(self.view.substr(reg)) for reg in reflinks) + 1
append_reference_link(edit, self.view, newref, linkurl)
insert_references(edit, self.view, newref)
finally:
self.view.end_edit(edit)
def is_enabled(self):
return self.view.sel()