Fix unclosed header in changelog
[blerg.git] / www / jssrc / blerg / Util.js
1 blerg = window.blerg || {};
2
3 blerg.Util = {};
4
5 // Dirty, terrible shim for rewritten links below
6 blerg.Util.qlink = function(ev) {
7     try {
8         location.href = ev.target.href;
9     } catch(e) { }
10     enyo.$.blerg.bubble('onNavigate');
11     return false;
12 }
13
14 blerg.Util.formatLinkHooks = [
15     BlergMedia
16 ];
17
18 blerg.Util.formatMarkdownLinks = function(l) {
19         m = l.match(/(\s[()\[\]{}]?|^)\[([^\]]+)\]\((https?:\/\/[a-zA-Z0-9.-]*[a-zA-Z0-9](\/[^)"]*?)?|mailto:[^)"]*?)(\s([^)]*))?\)/);
20         if (!m)
21             return l;
22         var whitespace = m[1];
23         var data = {
24             label: m[2],
25             url: m[3],
26             extra: m[5]
27         };
28
29         for (var i = 0; i < blerg.Util.formatLinkHooks.length; i++) {
30             var newdata = blerg.Util.formatLinkHooks[i].process(data);
31             if (newdata)
32                 data = newdata;
33             else
34                 console.warn("Format Link Hook " + i + " returned null");
35         }
36         var s = whitespace + '<a href="' + data.url + '">' + data.label + '</a>' +
37             (data.widget ? ' ' + data.widget : '');
38         return l.slice(0, m.index) + s + blerg.Util.formatMarkdownLinks(l.slice(m.index + m[0].length));
39 }
40
41 blerg.Util.blergFormat = function(text) {
42     var lines = text.split(/\r?\n/);
43     if (lines[lines.length - 1] == '')
44         lines.pop();
45
46     var out = ['<p>'];
47     var endpush = null;
48     var listMode = false;
49     lines.forEach(function(l) {
50         if (l == '') {
51             if (out[out.length - 1] == '<br>') {
52                 out[out.length - 1] = '<p>';
53             }
54             if (out[out.length - 1] == '</li>') {
55                 out.push('</ul>');
56                 out.push('<p>');
57                 listMode = false;
58             }
59             return;
60         }
61
62         // Put quoted material into a special paragraph
63         if (l[0] == '>') {
64             var pi = out.lastIndexOf('<p>');
65             if (pi != -1) {
66                 out[pi] = '<p class="quote">';
67                 l = l.replace(/^>\s*/, '');
68             }
69         }
70
71         // Sanitize HTML input
72         l = l.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
73
74         // Turn HTTP URLs into links
75         l = l.replace(/(\s[()\[\]{}]?|^)(https?:\/\/[a-zA-Z0-9.-]*[a-zA-Z0-9](\/([^\s"]*[^.!,;?()\s])?)?)/g, '$1<a href="$2">$2</a>');
76
77         // Turn markdown links into links
78         l = blerg.Util.formatMarkdownLinks(l);
79
80         // Turn *foo* into italics and **foo** into bold
81         l = l.replace(/([^\w\\]|^)\*\*(\w[^*]*)\*\*(\W|$)/g, '$1<b>$2</b>$3');
82         l = l.replace(/([^\w\\]|^)\*(\w[^*]*)\*(\W|$)/g, '$1<i>$2</i>$3');
83
84         // Turn refs and tags into links
85         l = l.replace(/(\s|^)#([A-Za-z0-9_-]+)/g, '$1<a href="#/tag/$2" class="ref" onclick="return blerg.Util.qlink(event)">#$2</a>');
86         l = l.replace(/(\s|^)@([A-Za-z0-9_-]+)(\/\d+)?/g, '$1<a href="#$2$3" class="ref" onclick="return blerg.Util.qlink(event)">@$2</a>');
87
88         // Create lists when lines begin with *
89         if (l[0] == '*') {
90             if (!listMode) {
91                 var pi = out.lastIndexOf('<p>');
92                 out[pi] = '<ul>';
93                 listMode = true;
94             }
95             l = l.replace(/^\*\s*/, '');
96             out.push('<li>');
97             endpush = '</li>';
98         }
99
100         // Create headers when lines begin with = or #
101         if (l[0] == '=' || l[0] == '#') {
102             var m = l.match(/^([=#]+)/);
103             var depth = m[1].length;
104             if (depth <= 5) {
105                 l = l.replace(/^[=#]+\s*/, '').replace(/\s*[=#]+$/, '');
106                 out.push('<h' + depth + '>');
107                 endpush = '</h' + depth + '>';
108             }
109         }
110
111         // Remove backslashes from escaped metachars
112         l = l.replace(/\\([*\[\]@#])/g, '$1');
113
114         out.push(l);
115         if (endpush) {
116             out.push(endpush);
117             endpush = null;
118         } else {
119             out.push('<br>');
120         }
121     });
122     while (out[out.length - 1] == '<br>' || out[out.length - 1] == '<p>')
123         out.pop();
124     if (listMode)
125         out.push('</ul>');
126
127     return out.join('');
128 }