showdown-rails 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +2 -2
- data/lib/showdown/rails/version.rb +1 -1
- data/vendor/assets/javascripts/showdown.js +132 -19
- metadata +13 -27
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2de1e46c86ff19fd34dc916bbfac4c00286fb2f
|
4
|
+
data.tar.gz: 27cad48a4b1cce8947ca5d3b9a74b2725b0b5053
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 60b10f7c0bd690aa5a50e2794bd5eaf2989fe823c40083ed5da6eb338f33dd3897ad7d5f5b5fc0308bdbaf93307a1340f61237424dadee5a6f49ea9a25d6c626
|
7
|
+
data.tar.gz: 1a4826cc693988807fcf65c999635616c9675bc0427f033f0145739a1a18d8bfb9058d73302e0c695a5ddb9f25178b6e6f54d7294ccd8670db3bdbb98582e21e
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@ The script enables features such as:
|
|
13
13
|
|
14
14
|
Add this line to your application's Gemfile:
|
15
15
|
|
16
|
-
gem 'rails
|
16
|
+
gem 'showdown-rails'
|
17
17
|
|
18
18
|
And then execute:
|
19
19
|
|
@@ -21,7 +21,7 @@ And then execute:
|
|
21
21
|
|
22
22
|
Or install it yourself as:
|
23
23
|
|
24
|
-
$ gem install rails
|
24
|
+
$ gem install showdown-rails
|
25
25
|
|
26
26
|
|
27
27
|
## Usage
|
@@ -64,7 +64,28 @@
|
|
64
64
|
//
|
65
65
|
// Showdown namespace
|
66
66
|
//
|
67
|
-
var Showdown = {};
|
67
|
+
var Showdown = { extensions: {} };
|
68
|
+
|
69
|
+
//
|
70
|
+
// forEach
|
71
|
+
//
|
72
|
+
var forEach = Showdown.forEach = function(obj, callback) {
|
73
|
+
if (typeof obj.forEach === 'function') {
|
74
|
+
obj.forEach(callback);
|
75
|
+
} else {
|
76
|
+
var i, len = obj.length;
|
77
|
+
for (i = 0; i < len; i++) {
|
78
|
+
callback(obj[i], i, obj);
|
79
|
+
}
|
80
|
+
}
|
81
|
+
};
|
82
|
+
|
83
|
+
//
|
84
|
+
// Standard extension naming
|
85
|
+
//
|
86
|
+
var stdExtName = function(s) {
|
87
|
+
return s.replace(/[_-]||\s/g, '').toLowerCase();
|
88
|
+
};
|
68
89
|
|
69
90
|
//
|
70
91
|
// converter
|
@@ -72,7 +93,7 @@ var Showdown = {};
|
|
72
93
|
// Wraps all "globals" so that the only thing
|
73
94
|
// exposed is makeHtml().
|
74
95
|
//
|
75
|
-
Showdown.converter = function() {
|
96
|
+
Showdown.converter = function(converter_options) {
|
76
97
|
|
77
98
|
//
|
78
99
|
// Globals:
|
@@ -87,6 +108,32 @@ var g_html_blocks;
|
|
87
108
|
// (see _ProcessListItems() for details):
|
88
109
|
var g_list_level = 0;
|
89
110
|
|
111
|
+
// Global extensions
|
112
|
+
var g_lang_extensions = [];
|
113
|
+
var g_output_modifiers = [];
|
114
|
+
|
115
|
+
|
116
|
+
//
|
117
|
+
// Automatic Extension Loading (node only):
|
118
|
+
//
|
119
|
+
|
120
|
+
if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof require !== 'undefind') {
|
121
|
+
var fs = require('fs');
|
122
|
+
|
123
|
+
if (fs) {
|
124
|
+
// Search extensions folder
|
125
|
+
var extensions = fs.readdirSync((__dirname || '.')+'/extensions').filter(function(file){
|
126
|
+
return ~file.indexOf('.js');
|
127
|
+
}).map(function(file){
|
128
|
+
return file.replace(/\.js$/, '');
|
129
|
+
});
|
130
|
+
// Load extensions into Showdown namespace
|
131
|
+
Showdown.forEach(extensions, function(ext){
|
132
|
+
var name = stdExtName(ext);
|
133
|
+
Showdown.extensions[name] = require('./extensions/' + ext);
|
134
|
+
});
|
135
|
+
}
|
136
|
+
}
|
90
137
|
|
91
138
|
this.makeHtml = function(text) {
|
92
139
|
//
|
@@ -100,14 +147,14 @@ this.makeHtml = function(text) {
|
|
100
147
|
// from other articles when generating a page which contains more than
|
101
148
|
// one article (e.g. an index page that shows the N most recent
|
102
149
|
// articles):
|
103
|
-
g_urls =
|
104
|
-
g_titles =
|
105
|
-
g_html_blocks =
|
150
|
+
g_urls = {};
|
151
|
+
g_titles = {};
|
152
|
+
g_html_blocks = [];
|
106
153
|
|
107
154
|
// attacklab: Replace ~ with ~T
|
108
155
|
// This lets us use tilde as an escape char to avoid md5 hashes
|
109
156
|
// The choice of character is arbitray; anything that isn't
|
110
|
-
|
157
|
+
// magic in Markdown will work.
|
111
158
|
text = text.replace(/~/g,"~T");
|
112
159
|
|
113
160
|
// attacklab: Replace $ with ~D
|
@@ -131,6 +178,11 @@ this.makeHtml = function(text) {
|
|
131
178
|
// contorted like /[ \t]*\n+/ .
|
132
179
|
text = text.replace(/^[ \t]+$/mg,"");
|
133
180
|
|
181
|
+
// Run language extensions
|
182
|
+
Showdown.forEach(g_lang_extensions, function(x){
|
183
|
+
text = _ExecuteExtension(x, text);
|
184
|
+
});
|
185
|
+
|
134
186
|
// Handle github codeblocks prior to running HashHTML so that
|
135
187
|
// HTML contained within the codeblock gets escaped propertly
|
136
188
|
text = _DoGithubCodeBlocks(text);
|
@@ -151,9 +203,60 @@ this.makeHtml = function(text) {
|
|
151
203
|
// attacklab: Restore tildes
|
152
204
|
text = text.replace(/~T/g,"~");
|
153
205
|
|
206
|
+
// Run output modifiers
|
207
|
+
Showdown.forEach(g_output_modifiers, function(x){
|
208
|
+
text = _ExecuteExtension(x, text);
|
209
|
+
});
|
210
|
+
|
154
211
|
return text;
|
155
212
|
};
|
213
|
+
//
|
214
|
+
// Options:
|
215
|
+
//
|
216
|
+
|
217
|
+
// Parse extensions options into separate arrays
|
218
|
+
if (converter_options && converter_options.extensions) {
|
219
|
+
|
220
|
+
var self = this;
|
221
|
+
|
222
|
+
// Iterate over each plugin
|
223
|
+
Showdown.forEach(converter_options.extensions, function(plugin){
|
156
224
|
|
225
|
+
// Assume it's a bundled plugin if a string is given
|
226
|
+
if (typeof plugin === 'string') {
|
227
|
+
plugin = Showdown.extensions[stdExtName(plugin)];
|
228
|
+
}
|
229
|
+
|
230
|
+
if (typeof plugin === 'function') {
|
231
|
+
// Iterate over each extension within that plugin
|
232
|
+
Showdown.forEach(plugin(self), function(ext){
|
233
|
+
// Sort extensions by type
|
234
|
+
if (ext.type) {
|
235
|
+
if (ext.type === 'language' || ext.type === 'lang') {
|
236
|
+
g_lang_extensions.push(ext);
|
237
|
+
} else if (ext.type === 'output' || ext.type === 'html') {
|
238
|
+
g_output_modifiers.push(ext);
|
239
|
+
}
|
240
|
+
} else {
|
241
|
+
// Assume language extension
|
242
|
+
g_output_modifiers.push(ext);
|
243
|
+
}
|
244
|
+
});
|
245
|
+
} else {
|
246
|
+
throw "Extension '" + plugin + "' could not be loaded. It was either not found or is not a valid extension.";
|
247
|
+
}
|
248
|
+
});
|
249
|
+
}
|
250
|
+
|
251
|
+
|
252
|
+
var _ExecuteExtension = function(ext, text) {
|
253
|
+
if (ext.regex) {
|
254
|
+
var re = new RegExp(ext.regex, 'g');
|
255
|
+
return text.replace(re, ext.replace);
|
256
|
+
} else if (ext.filter) {
|
257
|
+
return ext.filter(text);
|
258
|
+
}
|
259
|
+
};
|
157
260
|
|
158
261
|
var _StripLinkDefinitions = function(text) {
|
159
262
|
//
|
@@ -184,7 +287,11 @@ var _StripLinkDefinitions = function(text) {
|
|
184
287
|
/gm,
|
185
288
|
function(){...});
|
186
289
|
*/
|
187
|
-
|
290
|
+
|
291
|
+
// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
|
292
|
+
text += "~0";
|
293
|
+
|
294
|
+
text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|(?=~0))/gm,
|
188
295
|
function (wholeMatch,m1,m2,m3,m4) {
|
189
296
|
m1 = m1.toLowerCase();
|
190
297
|
g_urls[m1] = _EncodeAmpsAndAngles(m2); // Link IDs are case-insensitive
|
@@ -201,6 +308,9 @@ var _StripLinkDefinitions = function(text) {
|
|
201
308
|
}
|
202
309
|
);
|
203
310
|
|
311
|
+
// attacklab: strip sentinel
|
312
|
+
text = text.replace(/~0/,"");
|
313
|
+
|
204
314
|
return text;
|
205
315
|
}
|
206
316
|
|
@@ -259,13 +369,13 @@ var _HashHTMLBlocks = function(text) {
|
|
259
369
|
\b // word break
|
260
370
|
// attacklab: hack around khtml/pcre bug...
|
261
371
|
[^\r]*? // any number of lines, minimally matching
|
262
|
-
|
372
|
+
</\2> // the matching end tag
|
263
373
|
[ \t]* // trailing spaces/tabs
|
264
374
|
(?=\n+) // followed by a newline
|
265
375
|
) // attacklab: there are sentinel newlines at end of document
|
266
376
|
/gm,function(){...}};
|
267
377
|
*/
|
268
|
-
text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]
|
378
|
+
text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
|
269
379
|
|
270
380
|
// Special case just for <hr />. It was easier to make a special case than
|
271
381
|
// to make the other regex more complicated.
|
@@ -483,7 +593,7 @@ var _DoAnchors = function(text) {
|
|
483
593
|
)
|
484
594
|
/g,writeAnchorTag);
|
485
595
|
*/
|
486
|
-
text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
|
596
|
+
text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?(?:\(.*?\).*?)?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
|
487
597
|
|
488
598
|
//
|
489
599
|
// Last, handle reference-style shortcuts: [link text]
|
@@ -1089,7 +1199,7 @@ var _FormParagraphs = function(text) {
|
|
1089
1199
|
text = text.replace(/\n+$/g,"");
|
1090
1200
|
|
1091
1201
|
var grafs = text.split(/\n{2,}/g);
|
1092
|
-
var grafsOut =
|
1202
|
+
var grafsOut = [];
|
1093
1203
|
|
1094
1204
|
//
|
1095
1205
|
// Wrap <p> tags.
|
@@ -1208,16 +1318,9 @@ var _EncodeEmailAddress = function(addr) {
|
|
1208
1318
|
// mailing list: <http://tinyurl.com/yu7ue>
|
1209
1319
|
//
|
1210
1320
|
|
1211
|
-
// attacklab: why can't javascript speak hex?
|
1212
|
-
function char2hex(ch) {
|
1213
|
-
var hexDigits = '0123456789ABCDEF';
|
1214
|
-
var dec = ch.charCodeAt(0);
|
1215
|
-
return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
|
1216
|
-
}
|
1217
|
-
|
1218
1321
|
var encode = [
|
1219
1322
|
function(ch){return "&#"+ch.charCodeAt(0)+";";},
|
1220
|
-
function(ch){return "&#x"+
|
1323
|
+
function(ch){return "&#x"+ch.charCodeAt(0).toString(16)+";";},
|
1221
1324
|
function(ch){return ch;}
|
1222
1325
|
];
|
1223
1326
|
|
@@ -1337,5 +1440,15 @@ var escapeCharacters_callback = function(wholeMatch,m1) {
|
|
1337
1440
|
|
1338
1441
|
} // end of Showdown.converter
|
1339
1442
|
|
1443
|
+
|
1340
1444
|
// export
|
1341
1445
|
if (typeof module !== 'undefined') module.exports = Showdown;
|
1446
|
+
|
1447
|
+
// stolen from AMD branch of underscore
|
1448
|
+
// AMD define happens at the end for compatibility with AMD loaders
|
1449
|
+
// that don't enforce next-turn semantics on modules.
|
1450
|
+
if (typeof define === 'function' && define.amd) {
|
1451
|
+
define('showdown', function() {
|
1452
|
+
return Showdown;
|
1453
|
+
});
|
1454
|
+
}
|
metadata
CHANGED
@@ -1,62 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: showdown-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Josh McArthur
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: railties
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '3.1'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '3.1'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: actionpack
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '3.1'
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '3.1'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rails
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '3.1'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '3.1'
|
62
55
|
description: Showdown.js for Rails 3.1 Asset Pipeline
|
@@ -79,32 +72,25 @@ files:
|
|
79
72
|
- vendor/assets/javascripts/showdown.js
|
80
73
|
homepage: ''
|
81
74
|
licenses: []
|
75
|
+
metadata: {}
|
82
76
|
post_install_message:
|
83
77
|
rdoc_options: []
|
84
78
|
require_paths:
|
85
79
|
- lib
|
86
80
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
81
|
requirements:
|
89
|
-
- -
|
82
|
+
- - '>='
|
90
83
|
- !ruby/object:Gem::Version
|
91
84
|
version: '0'
|
92
|
-
segments:
|
93
|
-
- 0
|
94
|
-
hash: -2517281631621975678
|
95
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
-
none: false
|
97
86
|
requirements:
|
98
|
-
- -
|
87
|
+
- - '>='
|
99
88
|
- !ruby/object:Gem::Version
|
100
89
|
version: '0'
|
101
|
-
segments:
|
102
|
-
- 0
|
103
|
-
hash: -2517281631621975678
|
104
90
|
requirements: []
|
105
91
|
rubyforge_project:
|
106
|
-
rubygems_version:
|
92
|
+
rubygems_version: 2.0.3
|
107
93
|
signing_key:
|
108
|
-
specification_version:
|
94
|
+
specification_version: 4
|
109
95
|
summary: Showdown.js for Rails 3.1 Asset Pipeline
|
110
96
|
test_files: []
|