Files: 83ccc060f8a25977d0a70d8d4a0e8b6c3f721531 / index.js
3442 bytesRaw
1 | var ref = require('ssb-ref') |
2 | var marked = require('ssb-marked') |
3 | function noop(){} |
4 | var onLink = noop |
5 | var extractor = new marked.Renderer() |
6 | var qs = require('querystring') |
7 | |
8 | var keyRegex = /[0-9a-zA-Z\/+]{43}=(?:\.boxs)?/ |
9 | |
10 | function isKey(str) { |
11 | return keyRegex.test(str) |
12 | } |
13 | |
14 | // prevent html from entering into mention labels. |
15 | // code taken from ssb-markdown |
16 | extractor.code = function(code, lang, escaped) { return escaped ? unquote(code) : code } |
17 | extractor.blockquote = function(quote) { return unquote(quote) } |
18 | extractor.html = function(html) { return false } |
19 | extractor.heading = function(text, level, raw) { return unquote(text)+' ' } |
20 | extractor.hr = function() { return ' --- ' } |
21 | extractor.br = function() { return ' ' } |
22 | extractor.list = function(body, ordered) { return unquote(body) } |
23 | extractor.listitem = function(text) { return '- '+unquote(text) } |
24 | extractor.paragraph = function(text) { return unquote(text)+' ' } |
25 | extractor.table = function(header, body) { return unquote(header + ' ' + body) } |
26 | extractor.tablerow = function(content) { return unquote(content) } |
27 | extractor.tablecell = function(content, flags) { return unquote(content) } |
28 | extractor.strong = function(text) { return unquote(text) } |
29 | extractor.em = function(text) { return unquote(text) } |
30 | extractor.codespan = function(text) { return unquote(text) } |
31 | extractor.del = function(text) { return unquote(text) } |
32 | |
33 | function unquote (text) { |
34 | return text.replace(/&/g, '&').replace(/"/g, '"').replace(/'/g, '\'') |
35 | } |
36 | |
37 | extractor.mention = function (_, id) { |
38 | onLink({target: id}) |
39 | } |
40 | |
41 | extractor.emoji = function (name) { |
42 | onLink({label: name, emoji: true}) |
43 | return ':' + name + ':' |
44 | } |
45 | |
46 | extractor.hashtag = function (_, hashtag) { |
47 | onLink({target: hashtag}) |
48 | } |
49 | |
50 | extractor.link = function (href, _, text) { |
51 | onLink({label: text, target: href, embed: false}) |
52 | } |
53 | |
54 | extractor.image = function (href, _, text) { |
55 | onLink({label: text, target: href, embed: true}) |
56 | } |
57 | |
58 | function links (s, _onLink) { |
59 | if('string' !== typeof s) return |
60 | onLink = _onLink |
61 | try { |
62 | marked(s, {renderer: extractor, emoji: extractor.emoji}) |
63 | } catch(err) { |
64 | console.log(JSON.stringify(s)) |
65 | throw err |
66 | } |
67 | onLink = noop |
68 | } |
69 | |
70 | module.exports = function (text, opts) { |
71 | var bareFeedNames = opts && opts.bareFeedNames |
72 | var emoji = opts && opts.emoji |
73 | var a = [] |
74 | links(text, function (link) { |
75 | if(ref.isFeed(link.target)) |
76 | a.push({link: link.target, name: link.label && link.label.replace(/^@/, '')}) |
77 | else if(link.target && link.target[0] === '&') { |
78 | var parts = link.target.split('?') |
79 | var hash = parts[0] |
80 | var key |
81 | if(parts[1]) { |
82 | var q |
83 | try { q = qs.parse(parts[1]) } |
84 | catch(e) { q = {} } |
85 | if(typeof q.unbox === 'string') key = q.unbox.replace(/\s/g, '+') |
86 | } else { |
87 | parts = hash.split('#') |
88 | hash = parts[0] |
89 | key = parts[1] |
90 | } |
91 | if(ref.isBlob(hash)) { |
92 | link = {link: hash, name: link.label} |
93 | if(isKey(key)) link.key = key.replace(/\.boxs$/, '') |
94 | a.push(link) |
95 | } |
96 | } |
97 | else if(ref.isMsg(link.target)) |
98 | a.push({link: link.target, name: link.label}) |
99 | else if(bareFeedNames && link.target && link.target[0] === '@') |
100 | a.push({link: link.target[0], name: link.target.substr(1)}) |
101 | else if(link.target && link.target[0] === '#') |
102 | a.push({link: link.target}) |
103 | else if(emoji && link.emoji) |
104 | a.push({emoji: true, name: link.label}) |
105 | }) |
106 | return a |
107 | } |
108 | |
109 |
Built with git-ssb-web