-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreformatmdrefs.py
134 lines (106 loc) · 3.85 KB
/
reformatmdrefs.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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Convert Markdown text from inline URL link style to
reference style and vice-versa.
http://3e156c33bb09beb35fd0-19fc75fdc34cce7558ab01263b95946a.r86.cf1.rackcdn.com/formd.py
Seth Brown 02-24-12
"""
from __future__ import print_function, unicode_literals
import re
from io import open
from collections import OrderedDict
class ReformatMarkdownRefs(object):
"""Reformat links and references in Markdown text."""
match_links = re.compile(r'(\[[^^]*?\])\s?(\[.*?\]|\(.*?\))',
re.DOTALL | re.MULTILINE)
match_refs = re.compile(r'(?<=\n)\[[^^]*?\]:\s?.*')
def __init__(self, text):
super(ReformatMarkdownRefs, self).__init__()
self.text = text
self.data = []
def _links(self, ):
"""Find Markdown links."""
for link in re.findall(self.match_links, self.text):
# remove newline breaks from urls spanning multi-lines
parsed_link = [s.replace('\n', '') for s in link]
yield parsed_link
def _refs(self):
"""Find Markdown references."""
refs = re.findall(self.match_refs, self.text)
return OrderedDict(i.split(":", 1) for i in sorted(refs))
def _format(self):
"""Process text."""
links = tuple(self._links())
refs = self._refs()
for n, link in enumerate(links):
text, ref = link
ref_num = '[%i]: ' % (n + 1,)
if ref in refs:
url = refs.get(ref).strip()
md_ref = ref_num + url
elif text in refs:
url = refs.get(text).strip()
md_ref = ref_num + url
else:
parse_ref = ref.strip("()")
md_ref = ref_num + parse_ref
md_text = text + ref_num
self.data.append([md_text, md_ref])
def inline_md(self):
"""Generate Markdown with inline URLs."""
self._format()
print(self.data)
text_link = iter([''.join((_[0].split("][", 1)[0],
"](", _[1].split(":", 1)[1].strip(), ")"))
for _ in self.data])
md_text = self.match_links.sub(lambda _: next(text_link), self.text)
return self.match_refs.sub('', md_text).strip()
def ref_md(self):
"""Generate Markdown with referenced URLs."""
self._format()
ref_nums = iter([_[0].rstrip(" :") for _ in self.data])
md_text = self.match_links.sub(lambda _: next(ref_nums), self.text)
md_refs = self.match_refs.sub('', md_text).strip()
references = (i[1] for i in self.data)
return '%s\n\n\n%s' % (md_refs, '\n'.join(references))
def flip(self):
"""Convert markdown to the opposite style of the first text link."""
first_match = re.search(self.match_links, self.text).group(0)
if first_match and '(' in first_match and ')' in first_match:
return self.ref_md()
else:
return self.inline_md()
def pythonista_main():
import clipboard
import console
md = clipboard.get()
if md:
text = ReformatMarkdownRefs(md)
md = text.flip()
clipboard.set(md)
console.clear()
print(md)
def main():
import sys
try:
fp = None
if len(sys.argv) > 1:
fp = open(sys.argv[1], encoding='utf-8')
else:
fp = sys.stdin
text = ReformatMarkdownRefs(fp.read())
except (IOError, OSError) as exc:
sys.exit("Usage: reformatmdrefs.py <markdown file>" + '\n' + str(exc))
else:
print(text.inline_md())
finally:
if fp and fp is not sys.stdin:
fp.close()
if __name__ == '__main__':
try:
pythonista_main()
except ImportError:
try:
main()
except KeyboardInterrupt:
print('')