PageSourceSearch

https://scoutstracker.ca/test/lib/creole.js?ver=%25VER%25

js scoutstracker.ca collected 2026-09-25 23:55:09 UTC 15,294 bytes, 408 lines download raw bytes

1/*
2 * JavaScript Creole 1.0 Wiki Markup Parser
3 * $Id$
4 *
5 * Copyright (c) 2009 Ivan Fomichev
6 *
7 * Portions Copyright (c) 2007 Chris Purcell
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28if (!Parse) { var Parse = {}; }
29if (!Parse.Simple) { Parse.Simple = {}; }
30
31Parse.Simple.Base = function(grammar, options) {
32    if (!arguments.length) { return; }
33
34    this.grammar = grammar;
35    this.grammar.root = new this.ruleConstructor(this.grammar.root);
36    this.options = options;
37};
38
39Parse.Simple.Base.prototype = {
40    ruleConstructor: null,
41    grammar: null,
42    options: null,
43
44    parse: function(node, data, options) {
45        if (options) {
46            for (i in this.options) {
47                if (typeof options[i] == 'undefined') { options[i] = this.options[i]; }
48            }
49        }
50        else {
51            options = this.options;
52        }
53        if ( data === undefined )
54            data = "";
55        else
56            data = data.replace(/\r\n?/g, '\n');
57        this.grammar.root.apply(node, data, options);
58        if (options && options.forIE) { node.innerHTML = node.innerHTML.replace(/\r?\n/g, '\r\n'); }
59    }
60};
61
62Parse.Simple.Base.prototype.constructor = Parse.Simple.Base;
63
64Parse.Simple.Base.Rule = function(params) {
65    if (!arguments.length) { return; }
66
67    for (var p in params) { this[p] = params[p]; }
68    if (!this.children) { this.children = []; }
69};
70
71Parse.Simple.Base.prototype.ruleConstructor = Parse.Simple.Base.Rule;
72
73Parse.Simple.Base.Rule.prototype = {
74    regex: null,
75    capture: null,
76    replaceRegex: null,
77    replaceString: null,
78    tag: null,
79    attrs: null,
80    children: null,
81
82    match: function(data, options) {
83        //if ( data.match( this.regex ) ) console.log( "matched " + this.regex + " against '" + data + "'" );
84        return data.match(this.regex);
85    },
86
87    build: function(node, r, options) {
88        var data;
89        if (this.capture !== null) {
90            data = r[this.capture];
91        }
92
93        var target;
94        if (this.tag) {
95            target = document.createElement(this.tag);
96            node.appendChild(target);
97        }
98        else { target = node; }
99
100        if (data) {
101            if (this.replaceRegex) {
102                data = data.replace(this.replaceRegex, this.replaceString);
103            }
104            this.apply(target, data, options);
105        }
106
107        if (this.attrs) {
108            for (var i in this.attrs) {
109                target.setAttribute(i, this.attrs[i]);
110                if (options && options.forIE && i == 'class') { target.className = this.attrs[i]; }
111            }
112        }
113        return this;
114    },
115
116    apply: function(node, data, options) {
117        var tail = '' + data;
118        var matches = [];
119//console.log( "data = '" + tail + "'" );
120
121        if (!this.fallback.apply) {
122            this.fallback = new this.constructor(this.fallback);
123        }
124
125        while (true) {
126            var best = false;
127            var rule  = false;
128            for (var i = 0; i < this.children.length; i++) {
129//console.log( "    " + i + ": " + this.children[i].regex );
130                if (typeof matches[i] == 'undefined') {
131                    if (!this.children[i].match) {
132                        this.children[i] = new this.constructor(this.children[i]);
133                    }
134                    matches[i] = this.children[i].match(tail, options);
135                }
136                if (matches[i] && (!best || best.index > matches[i].index)) {
137                    best = matches[i];
138                    rule = this.children[i];
139                    if (best.index == 0) { break; }
140                }
141            }
142                
143            var pos = best ? best.index : tail.length;
144            if (pos > 0) {
145                this.fallback.apply(node, tail.substring(0, pos), options);
146            }
147            
148            if (!best) { break; }
149
150            if (!rule.build) { rule = new this.constructor(rule); }
151            rule.build(node, best, options);
152
153            var chopped = best.index + best[0].length;
154            tail = tail.substring(chopped);
155            for (var i = 0; i < this.children.length; i++) {
156                if (matches[i]) {
157                    if (matches[i].index >= chopped) {
158                        matches[i].index -= chopped;
159                    }
160                    else {
161                        matches[i] = void 0;
162                    }
163                }
164            }
165        }
166
167        return this;
168    },
169
170    fallback: {
171        apply: function(node, data, options) {
172            if (options && options.forIE) {
173                // workaround for bad IE
174                data = data.replace(/\n/g, ' \r');
175            }
176            node.appendChild(document.createTextNode(data));
177        }
178    }    
179};
180
181Parse.Simple.Base.Rule.prototype.constructor = Parse.Simple.Base.Rule;
182
183Parse.Simple.Creole = function(options) {
184    var rx = {};
185    rx.link = '[^\\]|~\\n]*(?:(?:\\](?!\\])|~.)[^\\]|~\\n]*)*';
186    rx.linkText = '[^\\]~\\n]*(?:(?:\\](?!\\])|~.)[^\\]~\\n]*)*';
187    rx.uriPrefix = '\\b(?:(?:https?|ftp)://|mailto:)';
188    rx.uri = rx.uriPrefix + rx.link;
189    rx.rawUri = rx.uriPrefix + '\\S*[^\\s!"\',.:;?]';
190    rx.interwikiPrefix = '[\\w.]+:';
191    rx.interwikiLink = rx.interwikiPrefix + rx.link;
192    rx.img = '\\{\\{((?!\\{)[^|}
192\\n]*(?:}(?!})[^|}\\n]*)*)' +
193             (options && options.strict ? '' : '(?:') + 
194             '\\|([^}~\\n]*((}(?!})|~.)[^}~\\n]*)*)' +
195             (options && options.strict ? '' : ')?') +
196             '}}';
197
198    var formatLink = function(link, format, label) {
199        if (format instanceof Function) {
200            return format(link,label);
201        }
202
203        format = format instanceof Array ? format : [ format ];
204        if (typeof format[1] == 'undefined') { format[1] = ''; }
205        return format[0] + link + format[1];
206    };
207
208    var g = {
209        hr: { tag: 'hr', regex: /(^|\n)\s*----*\s*(\n|$)/ },
210
211        br: { tag: 'br', regex: /\\\\/ },
212        
213        preBlock: { tag: 'pre', capture: 2,
214            regex: /(^|\n)\{\{\{\n((.*\n)*?)\}\}\}(\n|$)/,
215            replaceRegex: /^ ([ \t]*\}\}\})/gm,
216            replaceString: '$1' },
217        tt: { tag: 'tt',
218            regex: /\{\{\{(.*?\}\}\}+)/, capture: 1,
219            replaceRegex: /\}\}\}$/, replaceString: '' },
220
221        ulist: { tag: 'ul', capture: 0,
222            regex: /(^|\n)([ \t]*\*[^*#].*(\n|$)([ \t]*[^\s*#].*(\n|$))*([ \t]*[*#]{2}.*(\n|$))*)+/ },
223        olist: { tag: 'ol', capture: 0,
224            regex: /(^|\n)([ \t]*#[^*#].*(\n|$)([ \t]*[^\s*#].*(\n|$))*([ \t]*[*#]{2}.*(\n|$))*)+/ },
225        li: { tag: 'li', capture: 0,
226            regex: /[ \t]*([*#]).+(\n[ \t]*[^*#\s].*)*(\n[ \t]*\1[*#].+)*/,
227            replaceRegex: /(^|\n)[ \t]*[*#]/g,
228	    replaceString: '$1' },
229
230        blockquote: { tag: 'blockquote', capture: 2,
231            regex: /(^|\n):([ \t]*\S.*(\n|$))/,
232	    replaceString: '$1' },
233        table: { tag: 'table', capture: 0,
234            regex: /(^|\n)(\|.*?[ \t]*(\n|$))+/ },
235        tr: { tag: 'tr', capture: 2, regex: /(^|\n)(\|.*?)\|?[ \t]*(\n|$)/ },
236        th: { tag: 'th', regex: /\|+=([^|]*)/, capture: 1 },
237        td: { tag: 'td', capture: 1,
238            regex: '\\|+([^|~\\[{]*((~(.|(?=\\n)|$)|' +
239                   '\\[\\[' + rx.link + '(\\|' + rx.linkText + ')?\\]\\]' +
240                   (options && options.strict ? '' : '|' + rx.img) +
241                   '|[\\[{])[^|~]*)*)' },
242
243        singleLine: { regex: /.+/, capture: 0 },
244        paragraph: { tag: 'p', capture: 0,
245            regex: /(^|\n)([ \t]*\S.*(\n|$))+/ },
246        text: { capture: 0, regex: /(^|\n)([ \t]*[^\s].*(\n|$))+/ },
247
248        strong: { tag: 'strong', capture: 1,
249            regex: /\*\*([^*~]*((\*(?!\*)|~(.|(?=\n)|$))[^*~]*)*)(\*\*|\n|$)/ },
250        sup: { tag: 'sup', capture: 1,
251            regex: /\^\^(.+?)(\^\^|\n|$)/ },
252        em: { tag: 'em', capture: 1,
253            regex: '\\/\\/(((?!' + rx.uriPrefix + ')[^\\/~])*' +
254                   '((' + rx.rawUri + '|\\/(?!\\/)|~(.|(?=\\n)|$))' +
255                   '((?!' + rx.uriPrefix + ')[^\\/~])*)*)(\\/\\/|\\n|$)' },
256
257        //highlite: { regex: /##([^#]*)(##|\n|$)/,
258        highlite: { regex: /%%([^%~]*((%(?!%)|~(.|(?=\n)|$))[^%~]*)*)(%%|\n|$)/,
259            build: function(node, r, options) {
260                var span = document.createElement('span');
261                span.className = "search";
262                this.apply(span, r[1], options);
263                node.appendChild(span);
264            } },
265        underline: { regex: /__(.+?)(__|\n|$)/,
266            build: function(node, r, options) {
267                var span = document.createElement('span');
268		span.style["text-decoration"] = "underline";
269                this.apply(span, r[1], options);
270                node.appendChild(span);
271            } },
272
273        img: { regex: rx.img,
274            build: function(node, r, options) {
275                var img = document.createElement('img');
276                img.src = r[1];
277                img.alt = r[2] === undefined
278                    ? (options && options.defaultImageText ? options.defaultImageText : '')
279                    : r[2].replace(/~(.)/g, '$1');
280                node.appendChild(img);
281            } },
282
283        namedUri: { regex: '\\[\\[(' + rx.uri + ')\\|(' + rx.linkText + ')\\]\\]',
284            build: function(node, r, options) {
285                var link = document.createElement('a');
286                link.href = r[1];
287                link.setAttribute( "target", "_blank" );        // DAC
288                if (options && options.isPlainUri) {
289                    link.appendChild(document.createTextNode(r[2]));
290                }
291                else {
292                    this.apply(link, r[2], options);
293                }
294                node.appendChild(link);
295            } },
296
297        namedLink: { regex: '\\[\\[(' + rx.link + ')\\|(' + rx.linkText + ')\\]\\]',
298            build: function(node, r, options) {
299                var link = document.createElement('a');
300                link.setAttribute( "target", "_blank" );        // DAC
301                
302                link.href = options && options.linkFormat
303                    ? formatLink(r[1].replace(/~(.)/g, '$1'), options.linkFormat)
304                    : r[1].replace(/~(.)/g, '$1');
305                this.apply(link, r[2], options);
306                
307                node.appendChild(link);
308            } },
309
310        unnamedUri: { regex: '\\[\\[(' + rx.uri + ')\\]\\]',
311            build: 'dummy' },
312        unnamedLink: { regex: '\\[\\[(' + rx.link + ')\\]\\]',
313            build: 'dummy' },
314        unnamedInterwikiLink: { regex: '\\[\\[(' + rx.interwikiLink + ')\\]\\]',
315            build: 'dummy' },
316
317        rawUri: { regex: '(' + rx.rawUri + ')',
318            build: 'dummy' },
319
320        escapedSequence: { regex: '~(' + rx.rawUri + '|.)', capture: 1,
321            tag: 'span', attrs: { 'class': 'escaped' } },
322        escapedSymbol: { regex: /~(.)/, capture: 1,
323            tag: 'span', attrs: { 'class': 'escaped' } }
324    };
325    g.unnamedUri.build = g.rawUri.build = function(node, r, options) {
326        if (!options) { options = {}; }
327        options.isPlainUri = true;
328        g.namedUri.build.call(this, node, Array(r[0], r[1], r[1]), options);
329    };
330    g.unnamedLink.build = function(node, r, options) {
331        g.namedLink.build.call(this, node, Array(r[0], r[1], r[1]), options);
332    };
333    g.namedInterwikiLink = { regex: '\\[\\[(' + rx.interwikiLink + ')\\|(' + rx.linkText + ')\\]\\]',
334        build: function(node, r, options) {
335                var link = document.createElement('a');
336                
337                var m, f;
338                if (options && options.interwiki) {
339                m = r[1].match(/(.*?):(.*)/);
340                f = options.interwiki[m[1]];
341            }
342            
343            if (typeof f == 'undefined') {
344                if (!g.namedLink.apply) {
345                    g.namedLink = new this.constructor(g.namedLink);
346                }
347                return g.namedLink.build.call(g.namedLink, node, r, options);
348            }
349            else if ( f instanceof Function )
350	    {
351		var html = formatLink(m[2].replace(/~(.)/g, '$1'), f, r[2] );
352		var link =  document.createElement("span");
353		link.innerHTML = html;
354	    }
355	    else
356	    {
357		link.href = formatLink(m[2].replace(/~(.)/g, '$1'), f);
358		this.apply(link, r[2], options);
359	    }
360            
361            node.appendChild(link);
362        }
363    };
364    g.unnamedInterwikiLink.build = function(node, r, options) {
365        g.namedInterwikiLink.build.call(this, node, Array(r[0], r[1], r[1]), options);
366    };
367    g.namedUri.children = g.unnamedUri.children = g.rawUri.children =
368            g.namedLink.children = g.unnamedLink.children =
369            g.namedInterwikiLink.children = g.unnamedInterwikiLink.children =
370        [ g.escapedSymbol, g.highlite, g.underline, g.img ];
371
372    for (var i = 1; i <= 6; i++) {
373        g['h' + i] = { tag: 'h' + i, capture: 2,
374            regex: '(^|\\n)[ \\t]*={' + i + '}[ \\t]' +
375                   '([^~]*?(~(.|(?=\\n)|$))*)[ \\t]*=*\\s*(\\n|$)'
376        };
377    }
378
379    g.ulist.children = g.olist.children = [ g.li ];
380    g.li.children = [ g.ulist, g.olist ];
381    g.li.fallback = g.text;
382
383    g.table.children = [ g.tr ];
384    g.tr.children = [ g.th, g.td ];
385    g.td.children = [ g.singleLine ];
386    g.th.children = [ g.singleLine ];
387
388    g.h1.children = g.h2.children = g.h3.children =
389            g.h4.children = g.h5.children = g.h6.children =
390            g.singleLine.children = g.paragraph.children =
391            g.text.children = g.highlite.children = g.strong.children = g.sup.children = g.underline.children = g.em.children =
392        [ g.escapedSequence, g.highlite, g.strong, g.sup, g.underline, g.em, g.br, g.rawUri,
393            g.namedUri, g.namedInterwikiLink, g.namedLink,
394            g.unnamedUri, g.unnamedInterwikiLink, g.unnamedLink,
395            g.tt, g.img ];
396
397    g.root = {
398        children: [ g.h1, g.h2, g.h3, g.h4, g.h5, g.h6,
399            g.hr, g.ulist, g.olist, g.preBlock, g.table, g.blockquote ],
400        fallback: { children: [ g.paragraph ] }
401    };
402
403    Parse.Simple.Base.call(this, g, options);
404};
405
406Parse.Simple.Creole.prototype = new Parse.Simple.Base();
407
408Parse.Simple.Creole.prototype.constructor = Parse.Simple.Creole;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.