alula-plugins 0.4.24 → 0.4.25

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. data/README.md +29 -0
  2. data/lib/alula/plugins/fresco.rb +1 -0
  3. data/lib/alula/plugins/version.rb +1 -1
  4. data/plugins/disqus/assets/javascripts/disqus.js +0 -0
  5. data/plugins/disqus/assets/stylesheets/disqus.css +0 -0
  6. data/plugins/emphasis/assets/javascripts/emphasis.js +529 -0
  7. data/plugins/emphasis/assets/stylesheets/emphasis.css +0 -0
  8. data/plugins/fancybox/assets/images/blank.gif +0 -0
  9. data/plugins/fancybox/assets/images/fancybox_loading.gif +0 -0
  10. data/plugins/fancybox/assets/images/fancybox_sprite.png +0 -0
  11. data/plugins/fancybox/assets/images/zoom_icon.png +0 -0
  12. data/plugins/fancybox/assets/javascripts/fancybox.js.coffee +15 -0
  13. data/plugins/fancybox/assets/javascripts/jquery.fancybox.js +1414 -0
  14. data/plugins/fancybox/assets/stylesheets/fancybox.css.erb +248 -0
  15. data/plugins/fresco/assets/images/skins/IE6/sprite.png +0 -0
  16. data/plugins/fresco/assets/images/skins/blank.gif +0 -0
  17. data/plugins/fresco/assets/images/skins/fresco/sprite.png +0 -0
  18. data/plugins/fresco/assets/images/skins/fresco/sprite@x2.png +0 -0
  19. data/plugins/fresco/assets/images/skins/loading-medium.gif +0 -0
  20. data/plugins/fresco/assets/images/skins/loading-small.gif +0 -0
  21. data/plugins/fresco/assets/images/skins/loading.gif +0 -0
  22. data/plugins/fresco/assets/javascripts/fresco.js +86 -0
  23. data/plugins/fresco/assets/stylesheets/fresco.css.erb +993 -0
  24. data/plugins/sublimevideo/assets/images/zoom_icon.png +0 -0
  25. data/plugins/sublimevideo/assets/javascripts/sublimevideo.js.coffee +0 -0
  26. data/plugins/sublimevideo/assets/stylesheets/sublimevideo.css.erb +28 -0
  27. metadata +28 -5
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Alula::Plugins
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'alula-plugins'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install alula-plugins
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -62,6 +62,7 @@ module Alula
62
62
  tag += " data-hires=\"#{hires}\"" if context.site.config.attachments.image.hires and hires
63
63
  tag += " data-fresco-group=\"#{context.item.id}\""
64
64
  tag += " data-fresco-group-options=\"ui: 'inside', thumbnails:#{@@options['thumbnails'] ? "true" : "false"}\""
65
+ tag += " data-fresco-caption=\"#{@options['title']}\"" if @options["title"]
65
66
  tag += " title=\"#{@options["title"]}\"" if @options["title"]
66
67
  tag += " style=\"width: #{tn_info.width}px; height: #{tn_info.height}px;\""
67
68
  tag += ">"
@@ -3,7 +3,7 @@ module Alula
3
3
  module VERSION
4
4
  MAJOR = 0
5
5
  MINOR = 4
6
- PATCH = 24
6
+ PATCH = 25
7
7
  PRE = nil
8
8
 
9
9
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
File without changes
File without changes
@@ -0,0 +1,529 @@
1
+ //=require jquery
2
+ /* --------------------------------------------------
3
+
4
+ Emphasis
5
+ by Michael Donohoe (@donohoe)
6
+ https://github.com/NYTimes/Emphasis
7
+ http://open.blogs.nytimes.com/2011/01/10/emphasis-update-and-source/
8
+
9
+ - - - - - - - - - -
10
+
11
+ jQueryized by Rob Flaherty (@ravelrumba)
12
+ https://github.com/robflaherty/Emphasis
13
+
14
+ - - - - - - - - - -
15
+
16
+ Copyright (C) 2011 The New York Times (http://www.nytimes.com)
17
+
18
+ Permission is hereby granted, free of charge, to any person obtaining a copy
19
+ of this software and associated documentation files (the "Software"), to deal
20
+ in the Software without restriction, including without limitation the rights
21
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
22
+ copies of the Software, and to permit persons to whom the Software is
23
+ furnished to do so, subject to the following conditions:
24
+
25
+ The above copyright notice and this permission notice shall be included in
26
+ all copies or substantial portions of the Software.
27
+
28
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
31
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
32
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34
+ SOFTWARE.
35
+
36
+ -------------------------------------------------- */
37
+
38
+ jQuery(function($) {
39
+ var Emphasis = {
40
+ init: function() {
41
+ this.config();
42
+ this.pl = false; // Paragraph List
43
+ this.p = false; // Paragraph Anchor
44
+ this.h = false; // Highlighted paragraphs
45
+ this.s = false; // Highlighted sentences
46
+ this.vu = false; // Are paragraph links visible or not
47
+ this.kh = "|";
48
+
49
+ this.addCSS();
50
+ this.readHash();
51
+
52
+ $(document).bind('keydown', this.keydown);
53
+ },
54
+
55
+ config: function() {
56
+ /*
57
+ Eligible Paragraphs
58
+ This uses some common markup for plain and simple paragraphs - those that are not empty, no classes.
59
+ We use PrototypeJS for its css selector awesomeness, but your needs might be simpler (getElementsByTagName('p') etc.)
60
+ */
61
+ // this.paraSelctors = $('#article-content p');
62
+ this.paraSelctors = $('.articleBody p');
63
+
64
+ // Class names
65
+ this.classReady = "emReady";
66
+ this.classActive = "emActive";
67
+ this.classHighlight = "emHighlight";
68
+ this.classInfo = "emInfo";
69
+ this.classAnchor = "emAnchor";
70
+ this.classActiveAnchor = "emActiveAnchor";
71
+ },
72
+
73
+ addCSS: function() {
74
+ /* Inject the minimum styles rules required */
75
+ var st = document.createElement('style');
76
+ st.setAttribute('type', 'text/css');
77
+ /* for validation goodness */
78
+ var stStr = 'p.' + this.classActive + ' span { background-color:#f2f4f5; } p span.' + this.classHighlight + ' { background-color:#fff0b3; } span.' + this.classInfo + ' { position:absolute; margin:-1px 0px 0px -8px; padding:0; font-size:10px; background-color: transparent !important} span.' + this.classInfo + ' a { text-decoration: none; } a.' + this.classActiveAnchor + ' { color: #000; font-size: 11px; }';
79
+ try {
80
+ /* try the sensible way */
81
+ st.innerHTML = stStr;
82
+ } catch(e) {
83
+ /* IE's way */
84
+ st.styleSheet.cssText = stStr;
85
+ }
86
+ document.getElementsByTagName("head")[0].appendChild(st);
87
+ },
88
+
89
+ readHash: function() {
90
+ /* Read and interpret the URL hash */
91
+ var lh = decodeURI(location.hash),
92
+ p = false,
93
+ h = [],
94
+ s = {},
95
+ a, re, f, r, i, findp, findh, undef, hi, key, pos, b, j;
96
+
97
+
98
+ if (lh.indexOf('[')<0 && lh.indexOf(']')<0) {
99
+ /* Version 1 Legacy support
100
+ #p20h4s2,6,10,h6s5,1 -> p = 20, h = [ 4, 6 ], s = { "4": [ 2, 6, 10 ] , "6": [ 5, 1 ] }
101
+ */
102
+ re = /[ph][0-9]+|s[0-9,]+|[0-9]/g;
103
+ if (lh) {
104
+ while ((a = re.exec(lh)) !== null) {
105
+ f = a[0].substring(0, 1);
106
+ r = a[0].substring(1);
107
+ if (f === 'p') {
108
+ p = parseInt(r, 10);
109
+ } else if (f === 'h') {
110
+ h.push(parseInt(r, 10));
111
+ } else {
112
+ a = r.split(',');
113
+ for (i = 0; i < a.length; i++) {
114
+ a[i] = parseInt(a[i], 10);
115
+ }
116
+ s[h[h.length - 1]] = a;
117
+ }
118
+ }
119
+ }
120
+ } else {
121
+ /* Version 2
122
+ #h[tbsaoa,Sstaoo,2,4],p[FWaadw] -> p = "FWaadw", h = [ "tbsaoa", "Sstaoo" ], s = { "Sstaoo" : [ 2, 4 ] }
123
+ */
124
+ findp = lh.match(/p\[([^[\]]*)\]/);
125
+ findh = lh.match(/h\[([^[\]]*)\]/);
126
+
127
+ p = (findp && findp.length>0) ? findp[1] : false;
128
+ hi = (findh && findh.length>0) ? findh[1] : false;
129
+
130
+ if (hi) {
131
+ hi = hi.match(/[a-zA-Z]+(,[0-9]+)*/g);
132
+ for (i = 0; i < hi.length; i++) {
133
+ a = hi[i].split(',');
134
+ key = a[0];
135
+ pos = this.findKey(key).index;
136
+
137
+ if (pos !== undef) {
138
+ h.push(parseInt(pos, 10)+1);
139
+ b = a;
140
+ b.shift();
141
+ if (b.length>0) {
142
+ for (j=1; j<b.length; j++) {
143
+ b[j] = parseInt(b[j], 10);
144
+ }
145
+ }
146
+ s[h[h.length - 1]] = b;
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ this.p = p; this.h = h; this.s = s;
153
+
154
+ this.goAnchor(p);
155
+ this.goHighlight(h, s);
156
+ },
157
+
158
+ keydown: function(e){
159
+ /* Look for double-shift keypress */
160
+ var self = Emphasis,
161
+ kc = e.keyCode;
162
+
163
+ self.kh = self.kh + kc + '|';
164
+ if (self.kh.indexOf('|16|16|')>-1) {
165
+ self.vu = (self.vu) ? false : true;
166
+ self.paragraphInfo(self.vu);
167
+ }
168
+ setTimeout(function(){ self.kh = '|'; }, 500);
169
+ },
170
+
171
+ paragraphList: function() {
172
+ /* Build a list of Paragrphs, keys, and add meta-data to each Paragraph in DOM, saves list for later re-use */
173
+ if (this.pl && this.pl.list.length > 0) {
174
+ return this.pl;
175
+ }
176
+ var instance = this,
177
+ list = [],
178
+ keys = [],
179
+ c = 0,
180
+ len = this.paraSelctors.length,
181
+ p, pr, k;
182
+
183
+ for (p=0; p<len; p++) {
184
+ pr = this.paraSelctors[p];
185
+ if ((pr.innerText || pr.textContent || "").length>0) {
186
+ k = instance.createKey(pr);
187
+ list.push(pr);
188
+ keys.push(k);
189
+ pr.setAttribute("data-key", k); // Unique Key
190
+ pr.setAttribute("data-num", c); // Order
191
+
192
+ $(pr).bind('click', function(e) {
193
+ instance.paragraphClick(e);
194
+ });
195
+ c++;
196
+ }
197
+ }
198
+
199
+ this.pl = { list: list, keys: keys };
200
+ return this.pl;
201
+ },
202
+
203
+ paragraphClick: function(e) {
204
+ /* Clicking a Paragrsph has consequences for Highlighting, selecting and changing active Anchor */
205
+ if (!this.vu) { return; }
206
+
207
+ var hasChanged = false,
208
+ pr = (e.currentTarget.nodeName === "P") ? e.currentTarget : false, // Paragraph
209
+ $pr = $(pr),
210
+ sp = (e.target.nodeName === "SPAN") ? e.target : false, // Span
211
+ an = (e.target.nodeName === "A") ? e.target : false, // Anchor
212
+ lines, jLen, j, txt, chr;
213
+
214
+ if (an) {
215
+ /* Click an Anchor link */
216
+ if (!$(an).hasClass(this.classActiveAnchor)) {
217
+ this.updateAnchor(an);
218
+ hasChanged = true;
219
+ e.preventDefault();
220
+ }
221
+ }
222
+
223
+ if (!pr && !sp) {
224
+ this.removeClass(this.classActive);
225
+ return;
226
+ }
227
+
228
+ if ($pr.hasClass(this.classReady)) {
229
+ if (!$pr.hasClass(this.classActive) && (sp && !$(sp).hasClass(this.classHighlight))) {
230
+ // If not current Active p tag, clear any others out there and make this the Active p tag
231
+ $(this).removeClass(this.classActive);
232
+ $pr.addClass(this.classActive); // Mark as Active
233
+ } else {
234
+ if (!$pr.hasClass(this.classActive)) {
235
+ $(this).removeClass(this.classActive);
236
+ $pr.addClass(this.classActive); // Mark as Active
237
+ }
238
+
239
+ if (sp) {
240
+ $(sp).toggleClass(this.classHighlight);
241
+ hasChanged = true;
242
+ }
243
+ }
244
+ } else {
245
+ // Add span tags to all Sentences within Paragraph and mark Paragraph as Ready
246
+ lines = this.getSentences(pr);
247
+ jLen = lines.length;
248
+
249
+ for (j=0; j<jLen; j++) {
250
+ lines[j] = "<span data-num='" + (j+1) + "'>" + this.rtrim(lines[j]) + "</span>";
251
+ }
252
+
253
+ txt = lines.join('. ').replace(/__DOT__/g, ".").replace(/<\/span>\./g, ".<\/span>");
254
+ chr = txt.substring(txt.length-8).charCodeAt(0);
255
+ if ("|8221|63|46|41|39|37|34|33|".indexOf(chr) === -1) { txt += "."; }
256
+
257
+ pr.innerHTML = txt;
258
+ pr.setAttribute('data-sentences', jLen);
259
+
260
+ $(this).removeClass(this.classActive);
261
+ $pr.addClass(this.classActive); // Mark as Active
262
+ $pr.addClass(this.classReady); // Mark as Ready
263
+ hasChanged = true;
264
+ }
265
+
266
+ if (hasChanged) {
267
+ this.updateURLHash();
268
+ }
269
+ },
270
+
271
+ paragraphInfo: function(mode) {
272
+ /* Toggle anchor links next to Paragraphs */
273
+ var hasSpan, pl, len, i, para, key, isActive, spans;
274
+
275
+ if (mode) {
276
+ hasSpan = $('span.' + this.classInfo);
277
+ if (hasSpan.length === 0) {
278
+ pl = this.paragraphList();
279
+ len = pl.list.length;
280
+ for (i=0; i<len; i++) {
281
+ para = pl.list[i] || false;
282
+ if (para) {
283
+ key = pl.keys[i];
284
+ isActive = (key===this.p) ? (" " + this.classActiveAnchor) : "";
285
+ para.innerHTML = "<span class='" + this.classInfo + "'><a class='"+ this.classAnchor + isActive + "' href='#p[" + key + "]' data-key='" + key + "' title='Link to " + this.ordinal(i+1) + " paragraph'>&para;</a></span>" + para.innerHTML;
286
+ }
287
+ }
288
+ }
289
+ } else {
290
+ spans = $('span.' + this.classInfo);
291
+
292
+ len = spans.length;
293
+ for (i=0; i<len; i++) {
294
+ $(spans[i]).remove();
295
+ }
296
+ $(this).removeClass(this.classActive);
297
+ }
298
+ },
299
+
300
+ updateAnchor: function(an) {
301
+ /* Make this A tag the one and only Anchor */
302
+ this.p = an.getAttribute("data-key");
303
+ $(this).removeClass(this.classActiveAnchor);
304
+ $(an).addClass(this.classActiveAnchor);
305
+ },
306
+
307
+ updateURLHash: function() {
308
+ /* Scan the Paragraphs, note selections, highlights and update the URL with the new Hash */
309
+ var h = "h[",
310
+ paras = $('p.emReady'),
311
+ pLen = paras.length,
312
+ p, key, spans, sLen, nSent, anchor, hash,s;
313
+
314
+ for (p=0; p < pLen; p++) {
315
+ key = paras[p].getAttribute("data-key");
316
+ if ($(paras[p]).hasClass(this.classHighlight)) {
317
+ h += "," + key; // Highlight full paragraph
318
+ } else {
319
+ spans = $('span.' + this.classHighlight, paras[p]);
320
+ sLen = spans.length;
321
+ nSent = paras[p].getAttribute("data-sentences");
322
+
323
+ if (sLen>0) { h += "," + key; }
324
+
325
+ if (nSent!==sLen) {
326
+ for (s=0; s<sLen; s++) {
327
+ h += "," + spans[s].getAttribute("data-num");
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ anchor = ((this.p) ? "p[" + this.p + "]," : "");
334
+ hash = (anchor + (h.replace("h[,", "h[") + "]")).replace(",h[]", "");
335
+ location.hash = hash;
336
+ },
337
+
338
+ createKey: function(p) {
339
+ /* From a Paragraph, generate a Key */
340
+ var key = "",
341
+ len = 6,
342
+ txt = (p.innerText || p.textContent || '').replace(/[^a-z\. ]+/gi, ''),
343
+ lines, first, last, k, max, i;
344
+
345
+ if (txt && txt.length>1) {
346
+
347
+ lines = this.getSentences(txt);
348
+ if (lines.length>0) {
349
+ first = this.cleanArray(lines[0].replace(/[\s\s]+/gi, ' ').split(' ')).slice(0, (len/2));
350
+ last = this.cleanArray(lines[lines.length-1].replace(/[\s\s]+/gi, ' ').split(' ')).slice(0, (len/2));
351
+ k = first.concat(last);
352
+
353
+ max = (k.length>len) ? len : k.length;
354
+ for (i=0; i<max; i++) {
355
+ key += k[i].substring(0, 1);
356
+ }
357
+ }
358
+ }
359
+ return key;
360
+ },
361
+
362
+ findKey: function(key) {
363
+ /* From a list of Keys, locate the Key and corresponding Paragraph */
364
+ var pl = this.paragraphList(),
365
+ ln = pl.keys.length,
366
+ ix = false,
367
+ el = false,
368
+ i, ls, le;
369
+
370
+ for (i=0;i<ln;i++) {
371
+ if (key===pl.keys[i]) { // Direct Match
372
+ return { index: i, elm: pl.list[i] };
373
+ } else { // Look for 1st closest Match
374
+ if (!ix) {
375
+ ls = this.lev(key.slice(0, 3), pl.keys[i].slice(0, 3));
376
+ le = this.lev(key.slice(-3) , pl.keys[i].slice(-3));
377
+ if ((ls+le)<3) {
378
+ ix = i;
379
+ el = pl.list[i];
380
+ }
381
+ }
382
+ }
383
+ }
384
+ return { index: ix, elm: el };
385
+ },
386
+
387
+ goAnchor: function(p) {
388
+ /* Move view to top of a given Paragraph */
389
+ if (!p) {
390
+ return;
391
+ }
392
+ var pg = (isNaN(p)) ? this.findKey(p)['elm'] : (this.paragraphList().list[p-1] || false);
393
+
394
+ if (pg) {
395
+ setTimeout(function(){
396
+ $(window).scrollTop($(pg).offset().top);
397
+ }, 500);
398
+ }
399
+ },
400
+
401
+ goHighlight: function(h, s) {
402
+ /* Highlight a Paragraph, or specific Sentences within it */
403
+ if (!h) {
404
+ return;
405
+ }
406
+ var hLen = h.length,
407
+ i, para, sntns, multi, lines, jLen, j, k, line;
408
+
409
+ for (i=0; i<hLen; i++) {
410
+ para = this.paragraphList().list[h[i]-1] || false;
411
+ if (para) {
412
+ sntns = s[h[i].toString()] || false;
413
+ multi = !sntns || sntns.length===0; // Individual sentences, or whole paragraphy?
414
+ lines = this.getSentences(para);
415
+ jLen = lines.length;
416
+
417
+ /* First pass. Add SPAN tags to all lines. */
418
+ for (j=0; j<jLen; j++) {
419
+ k = (multi) ? j : sntns[j]-1;
420
+ lines[j] = "<span data-num='" + (j+1) + "'>" + lines[j] + "</span>";
421
+ }
422
+
423
+ /* Second pass, update span to Highlight selected lines */
424
+ for (j=0; j<jLen; j++) {
425
+ k = (multi) ? j : sntns[j]-1;
426
+ line = lines[k] || false;
427
+ if (line) {
428
+ lines[k] = lines[k].replace("<span", "<span class='" + this.classHighlight + "'");
429
+ }
430
+ }
431
+
432
+ para.setAttribute("data-sentences", jLen);
433
+ para.innerHTML = lines.join('. ').replace(/__DOT__/g, ".").replace(/<\/span>\./g, ".<\/span>");
434
+ $(para).addClass('emReady'); /* Mark the paragraph as having SPANs */
435
+ }
436
+ }
437
+ },
438
+
439
+ getSentences: function(el) {
440
+ /* Break a Paragraph into Sentences, bearing in mind that the "." is not the definitive way to do so */
441
+ var html = (typeof el==="string") ? el : el.innerHTML,
442
+ mrsList = "Mr,Ms,Mrs,Miss,Msr,Dr,Gov,Pres,Sen,Prof,Gen,Rep,St,Messrs,Col,Sr,Jf,Ph,Sgt,Mgr,Fr,Rev,No,Jr,Snr",
443
+ topList = "A,B,C,D,E,F,G,H,I,J,K,L,M,m,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,etc,oz,cf,viz,sc,ca,Ave,St",
444
+ geoList = "Calif,Mass,Penn,AK,AL,AR,AS,AZ,CA,CO,CT,DC,DE,FL,FM,GA,GU,HI,IA,ID,IL,IN,KS,KY,LA,MA,MD,ME,MH,MI,MN,MO,MP,MS,MT,NC,ND,NE,NH,NJ,NM,NV,NY,OH,OK,OR,PA,PR,PW,RI,SC,SD,TN,TX,UT,VA,VI,VT,WA,WI,WV,WY,AE,AA,AP,NYC,GB,IRL,IE,UK,GB,FR",
445
+ numList = "0,1,2,3,4,5,6,7,8,9",
446
+ webList = "aero,asia,biz,cat,com,coop,edu,gov,info,int,jobs,mil,mobi,museum,name,net,org,pro,tel,travel,xxx",
447
+ extList = "www",
448
+ d = "__DOT__",
449
+
450
+ list = (topList+","+geoList+","+numList+","+extList).split(","),
451
+ len = list.length,
452
+ i, lines;
453
+
454
+ for (i=0;i<len;i++) {
455
+ html = html.replace(new RegExp((" "+list[i]+"\\."), "g"), (" "+list[i]+d));
456
+ }
457
+
458
+ list = (mrsList+","+numList).split(",");
459
+ len = list.length;
460
+ for (i=0;i<len;i++) {
461
+ html = html.replace(new RegExp((list[i]+"\\."), "g"), (list[i]+d));
462
+ }
463
+
464
+ list = (webList).split(",");
465
+ len = list.length;
466
+ for (i=0;i<len;i++) {
467
+ html = html.replace(new RegExp(("\\."+list[i]), "g"), (d+list[i]));
468
+ }
469
+
470
+ lines = this.cleanArray(html.split('. '));
471
+ return lines;
472
+ },
473
+
474
+ ordinal: function(n) {
475
+ var sfx = ["th","st","nd","rd"],
476
+ val = n%100;
477
+ return n + (sfx[(val-20)%10] || sfx[val] || sfx[0]);
478
+ },
479
+
480
+ lev: function(a, b) {
481
+ /* Get the Levenshtein distance - a measure of difference between two sequences */
482
+ var m = a.length,
483
+ n = b.length,
484
+ r = [],
485
+ c, o, i, j;
486
+
487
+ r[0] = [];
488
+
489
+ if (m < n) { c = a; a = b; b = c; o = m; m = n; n = o; }
490
+ for (c = 0; c < n+1; c++) { r[0][c] = c; }
491
+ for (i = 1; i < m+1; i++) {
492
+ r[i] = [];
493
+ r[i][0] = i;
494
+ for (j=1; j<n+1; j++) {
495
+ r[i][j] = this.smallest(r[i-1][j]+1, r[i][j-1]+1, r[i-1][j-1]+((a.charAt(i-1)===b.charAt(j-1))? 0 : 1));
496
+ }
497
+ }
498
+ return r[m][n];
499
+ },
500
+
501
+ smallest: function(x,y,z) {
502
+ /* Return smallest of two values */
503
+ if (x < y && x < z) { return x; }
504
+ if (y < x && y < z) { return y; }
505
+ return z;
506
+ },
507
+
508
+ rtrim: function(txt) {
509
+ /* Trim whitespace from right of string */
510
+ return txt.replace(/\s+$/, "");
511
+ },
512
+
513
+ cleanArray: function(a){
514
+ /* Remove empty items from an array */
515
+ var n = [],
516
+ i;
517
+ for (i = 0; i<a.length; i++){
518
+ if (a[i] && a[i].replace(/ /g,'').length>0){ n.push(a[i]); }
519
+ }
520
+ return n;
521
+ }
522
+
523
+ };
524
+
525
+ $(window).bind('load', function() {
526
+ Emphasis.init();
527
+ });
528
+
529
+ });