import { Dict } from "src/util";
const VERSION = "0.4.0";
export interface BBCodeConfig {
showQuotePrefix?: boolean;
classPrefix?: string;
mentionPrefix?: string;
}
// default options
const defaults: BBCodeConfig = {
showQuotePrefix: true,
classPrefix: "bbcode_",
mentionPrefix: "@"
};
export const version = VERSION;
// copied from here:
// http://blog.mattheworiordan.com/post/13174566389/url-regular-expression-for-links-with-or-without-the had to make an
// update to allow / in the query string, since some sites will have a / there made another update to support colons in
// the query string made another update to disallow an ending dot(.)
const URL_PATTERN = new RegExp("(" // overall match
+ "(" // brackets covering match for protocol (optional) and domain
+ "([A-Za-z]{3,9}:(?:\\/\\/)?)" // allow something@ for email addresses
+ "(?:[\\-;:&=\\+\\$,\\w]+@)?[A-Za-z0-9\\.\\-]+[A-Za-z0-9\\-]"
// anything looking at all like a domain, non-unicode domains
+ "|" // or instead of above
+ "(?:www\\.|[\\-;:&=\\+\\$,\\w]+@)" // starting with something@ or www.
+ "[A-Za-z0-9\\.\\-]+[A-Za-z0-9\\-]" // anything looking at all like a domain
+ ")" // end protocol/domain
+ "(" // brackets covering match for path, query string and anchor
+ "(?:\\/[\\+~%\\/\\.\\w\\-_]*)?" // allow optional /path
+ "\\??(?:[\\-\\+=&;%@\\.\\w_\\/:]*)" // allow optional query string starting with ?
+ "#?(?:[\\.\\!\\/\\\\\\w]*)" // allow optional anchor #anchor
+ ")?" // make URL suffix optional
+ ")");
function doReplace(content: string, matches: Replacement[], options: BBCodeConfig) {
let i, obj, regex, hasMatch, tmp;
// match/replace until we don't change the input anymore
do {
hasMatch = false;
for (i = 0; i < matches.length; ++i) {
obj = matches[i];
regex = new RegExp(obj.e, "gi");
tmp = content.replace(regex, obj.func.bind(undefined, options));
if (tmp !== content) {
content = tmp;
hasMatch = true;
}
}
} while (hasMatch);
return content;
}
function listItemReplace(options: BBCodeConfig, fullMatch: string, tag: string, value: string) {
return "
";
case "url":
return "" + value + "";
case "email":
return "" + value + "";
case "anchor":
return "" + value + "";
case "b":
return "" + value + "";
case "i":
return "" + value + "";
case "u":
return "" + value + "";
case "s":
return "" + value + "";
case "indent":
return "
" + value + "
";
case "list": {
tag = "ul";
let className = options.classPrefix + "list";
if (inlineValue && /[1Aa]/.test(inlineValue)) {
tag = "ol";
if (/1/.test(inlineValue)) {
className += "_numeric";
}
else if (/A/.test(inlineValue)) {
className += "_alpha";
}
else if (/a/.test(inlineValue)) {
className += "_alpha_lower";
}
}
val = "<" + tag + " class=\"" + className + "\">";
// parse the value
val += doReplace(value, [{ e: "\\[([*])\\]([^\r\n]+)", func: listItemReplace }], options);
return val + "" + tag + ">";
}
case "code":
case "php":
case "java":
case "javascript":
case "cpp":
case "ruby":
case "python":
return "
" + value + "
";
case "highlight":
return "" + value + "";
case "html":
return value;
case "mention":
val = "" + (options.mentionPrefix || "") + value + "";
case "span":
case "h1":
case "h2":
case "h3":
case "h4":
case "h5":
case "h6":
return "<" + tag + ">" + value + "" + tag + ">";
case "youtube":
return "";
case "gvideo":
return "