// (granted, switching from Array() to Object() alone would have left only __proto__
// to be a problem)
functionSaveHash(){}
SaveHash.prototype={
set:function(key,value){
this["s_"+key]=value;
},
get:function(key){
returnthis["s_"+key];
}
};
Markdown.Converter=function(){
varpluginHooks=this.hooks=newHookCollection();
pluginHooks.addNoop("plainLinkText");// given a URL that was encountered by itself (without markup), should return the link text that's to be given to this link
pluginHooks.addNoop("preConversion");// called with the orignal text as given to makeHtml. The result of this plugin hook is the actual markdown source that will be cooked
pluginHooks.addNoop("postConversion");// called with the final cooked HTML code. The result of this plugin hook is the actual output of makeHtml
//
// Private state of the converter instance:
//
// Global hashes, used by various utility routines
varg_urls;
varg_titles;
varg_html_blocks;
// Used to track when we're inside an ordered or unordered list
// (see _ProcessListItems() for details):
varg_list_level;
this.makeHtml=function(text){
//
// Main function. The order in which other subs are called here is
// essential. Link and image substitutions need to happen before
// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
// and <img> tags get encoded.
//
// This will only happen if makeHtml on the same converter instance is called from a plugin hook.
// Don't do that.
if(g_urls)
thrownewError("Recursive call to converter.makeHtml");
// Create the private state objects.
g_urls=newSaveHash();
g_titles=newSaveHash();
g_html_blocks=[];
g_list_level=0;
text=pluginHooks.preConversion(text);
// attacklab: Replace ~ with ~T
// This lets us use tilde as an escape char to avoid md5 hashes
// The choice of character is arbitray; anything that isn't
// magic in Markdown will work.
text=text.replace(/~/g,"~T");
// attacklab: Replace $ with ~D
// RegExp interprets $ as a special character
// when it's in a replacement string
text=text.replace(/\$/g,"~D");
// Standardize line endings
text=text.replace(/\r\n/g,"\n");// DOS to Unix
text=text.replace(/\r/g,"\n");// Mac to Unix
// Make sure text begins and ends with a couple of newlines:
text="\n\n"+text+"\n\n";
// Convert all tabs to spaces.
text=_Detab(text);
// Strip any lines consisting only of spaces and tabs.
// This makes subsequent regexen easier to write, because we can
// match consecutive blank lines with /\n+/ instead of something
// contorted like /[ \t]*\n+/ .
text=text.replace(/^[\t]+$/mg,"");
// Turn block-level HTML blocks into hash entries
text=_HashHTMLBlocks(text);
// Strip link definitions, store in hashes.
text=_StripLinkDefinitions(text);
text=_RunBlockGamut(text);
text=_UnescapeSpecialChars(text);
// attacklab: Restore dollar signs
text=text.replace(/~D/g,"$$");
// attacklab: Restore tildes
text=text.replace(/~T/g,"~");
text=pluginHooks.postConversion(text);
g_html_blocks=g_titles=g_urls=null;
returntext;
};
function_StripLinkDefinitions(text){
//
// Strips link definitions from text, stores the URLs and titles in
// hash references.
//
// Link defs are in the form: ^[id]: url "optional title"
/*
text = text.replace(/
^[ ]{0,3}\[(.+)\]: // id = $1 attacklab: g_tab_width - 1
[ \t]*
\n? // maybe *one* newline
[ \t]*
<?(\S+?)>? // url = $2
(?=\s|$) // lookahead for whitespace instead of the lookbehind removed below
[ \t]*
\n? // maybe one newline
[ \t]*
( // (potential) title = $3
(\n*) // any lines skipped = $4 attacklab: lookbehind removed
tag=escapeCharacters(tag,wholeMatch.charAt(1)=="!"?"\\`*_/":"\\`*_");// also escape slashes in comments to prevent autolinking there -- http://meta.stackoverflow.com/questions/95987
returntag;
});
returntext;
}
function_DoAnchors(text){
//
// Turn Markdown link shortcuts into XHTML <a> tags.
c=c.replace(/:\/\//g,"~P");// to prevent auto-linking. Not necessary in code *blocks*, but in code spans. Will be converted back after the auto-linker runs.
returnm1+"<code>"+c+"</code>";
}
);
returntext;
}
function_EncodeCode(text){
//
// Encode/escape certain characters inside Markdown code runs.
// The point is that in code, these characters are literals,
// and lose their special Markdown meanings.
//
// Encode all ampersands; HTML entities are not
// entities within a Markdown code span.
text=text.replace(/&/g,"&");
// Do the angle bracket song and dance:
text=text.replace(/</g,"<");
text=text.replace(/>/g,">");
// Now, escape characters that are magic in Markdown:
text=escapeCharacters(text,"\*_{}[]\\", false);
// jj the line above breaks this:
//---
//* Item
// 1. Subitem
// special char: *
//---
return text;
}
function _DoItalicsAndBold(text) {
// <strong> must go first:
text = text.replace(/([\W_]|^)(\*\*|__)(?=\S)([^\r]*?\S[\*_]*)\2([\W_]|$)/g,