//-- //-- Wikifier //-- function getParser(tiddler,format) { if(tiddler) { if(!format) format = tiddler.fields["wikiformat"]; var i; if(format) { //# format field takes precedence over format tag for(i in config.parsers) { if(format == config.parsers[i].format) return config.parsers[i]; } } else { for(i in config.parsers) { if(tiddler.isTagged(config.parsers[i].formatTag)) return config.parsers[i]; } } } return formatter; } //# Construct a wikifier object //# source - source string that's going to be wikified //# formatter - Formatter() object containing the list of formatters to be used //# highlightRegExp - regular expression of the text string to highlight //# tiddler - reference to the tiddler that's taken to be the container for this wikification function Wikifier(source,formatter,highlightRegExp,tiddler) { this.source = source; this.output = null; this.formatter = formatter; this.nextMatch = 0; this.autoLinkWikiWords = tiddler && tiddler.autoLinkWikiWords() == false ? false : true; this.highlightRegExp = highlightRegExp; this.highlightMatch = null; this.isStatic = false; if(highlightRegExp) { highlightRegExp.lastIndex = 0; this.highlightMatch = highlightRegExp.exec(source); } this.tiddler = tiddler; } Wikifier.prototype.wikifyPlain = function() { var e = createTiddlyElement(document.body,"div"); e.style.display = "none"; this.subWikify(e); var text = jQuery(e).text(); jQuery(e).remove(); return text; }; Wikifier.prototype.subWikify = function(output,terminator) { //# Handle the terminated and unterminated cases separately, this speeds up wikifikation by about 30% try { if(terminator) this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg")); else this.subWikifyUnterm(output); } catch(ex) { showException(ex); } }; Wikifier.prototype.subWikifyUnterm = function(output) { //# subWikify can be indirectly recursive, so we need to save the old output pointer var oldOutput = this.output; this.output = output; //# Get the first match this.formatter.formatterRegExp.lastIndex = this.nextMatch; var formatterMatch = this.formatter.formatterRegExp.exec(this.source); while(formatterMatch) { // Output any text before the match if(formatterMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,formatterMatch.index); // Set the match parameters for the handler this.matchStart = formatterMatch.index; this.matchLength = formatterMatch[0].length; this.matchText = formatterMatch[0]; this.nextMatch = this.formatter.formatterRegExp.lastIndex; //# Figure out which formatter matched and call its handler var t; for(t=1; t this.nextMatch) this.outputText(this.output,this.nextMatch,terminatorMatch.index); //# Set the match parameters this.matchText = terminatorMatch[1]; this.matchLength = terminatorMatch[1].length; this.matchStart = terminatorMatch.index; this.nextMatch = this.matchStart + this.matchLength; //# Restore the output pointer this.output = oldOutput; return; } //# It must be a formatter match; output any text before the match if(formatterMatch.index > this.nextMatch) this.outputText(this.output,this.nextMatch,formatterMatch.index); //# Set the match parameters this.matchStart = formatterMatch.index; this.matchLength = formatterMatch[0].length; this.matchText = formatterMatch[0]; this.nextMatch = this.formatter.formatterRegExp.lastIndex; //# Figure out which formatter matched and call its handler var t; for(t=1; t startPos) && (this.highlightMatch.index < endPos) && (startPos < endPos)) { //# Deal with any plain text before the highlight if(this.highlightMatch.index > startPos) { createTiddlyText(place,this.source.substring(startPos,this.highlightMatch.index)); startPos = this.highlightMatch.index; } //# Deal with the highlight var highlightEnd = Math.min(this.highlightRegExp.lastIndex,endPos); createTiddlyElement(place,"span",null,"highlight",this.source.substring(startPos,highlightEnd)); startPos = highlightEnd; //# Nudge along to the next highlight if we're done with this one if(startPos >= this.highlightRegExp.lastIndex) this.highlightMatch = this.highlightRegExp.exec(this.source); } //# Do the unhighlighted text left over if(startPos < endPos) { createTiddlyText(place,this.source.substring(startPos,endPos)); } }; function wikify(source,output,highlightRegExp,tiddler) { if(source) { var wikifier = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler); var t0 = new Date(); wikifier.subWikify(output); if(tiddler && config.options.chkDisplayInstrumentation) displayMessage("wikify:" +tiddler.title+ " in " + (new Date()-t0) + " ms"); } } function wikifyStatic(source,highlightRegExp,tiddler,format) { var e = createTiddlyElement(document.body,"pre"); e.style.display = "none"; var html = ""; if(source && source != "") { if(!tiddler) tiddler = new Tiddler("temp"); var wikifier = new Wikifier(source,getParser(tiddler,format),highlightRegExp,tiddler); wikifier.isStatic = true; wikifier.subWikify(e); html = e.innerHTML; jQuery(e).remove(); } return html; } //# Wikify a string to plain text //# text - text to wikify //# limit - maximum number of characters to generate //# tiddler - optional reference to the tiddler containing this text function wikifyPlainText(text,limit,tiddler) { if(limit > 0) text = text.substr(0,limit); var wikifier = new Wikifier(text,formatter,null,tiddler); return wikifier.wikifyPlain(); } //# Highlight plain text into an element function highlightify(source,output,highlightRegExp,tiddler) { if(source) { var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler); wikifier.outputText(output,0,source.length); } }