mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
add links
This commit is contained in:
parent
5a14ce02db
commit
c48801d8fa
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "showdown",
|
||||
"version": "2.0.0",
|
||||
"version": "3.0.0-alpha",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "showdown",
|
||||
"version": "2.0.0",
|
||||
"version": "3.0.0-alpha",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commander": "^9.0.0",
|
||||
|
|
|
@ -140,9 +140,9 @@ showdown.subParser('makehtml.image', function (text, options, globals) {
|
|||
startEvent = globals.converter.dispatch(startEvent);
|
||||
text = startEvent.output;
|
||||
|
||||
let inlineRegExp = /!\[([^\]]*?)][ \t]*\([ \t]?<?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\5)?[ \t]?\)/g,
|
||||
let inlineRegExp = /!\[([^\]]*?)][ \t]*\([ \t]?<?(\S+?(?:\(\S*?\)\S*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\5)?[ \t]?\)/g,
|
||||
crazyRegExp = /!\[([^\]]*?)][ \t]*\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\5)?[ \t]?\)/g,
|
||||
base64RegExp = /!\[([^\]]*?)][ \t]*\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
|
||||
base64RegExp = /!\[([^\]]*?)][ \t]*\([ \t]?<?(data:.+?\/.+?;base64,[A-Za-z\d+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g,
|
||||
referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]/g,
|
||||
refShortcutRegExp = /!\[([^\[\]]+)]/g;
|
||||
|
||||
|
|
|
@ -25,11 +25,19 @@ showdown.subParser('makehtml.link', function (text, options, globals) {
|
|||
* @param {string|null} [url]
|
||||
* @param {string|null} [title]
|
||||
* @param {boolean} [emptyCase]
|
||||
* @returns {string}
|
||||
*/
|
||||
function writeAnchorTag (subEvtName, pattern, wholeMatch, text, linkId, url, title, emptyCase) {
|
||||
|
||||
let otp = '';
|
||||
let target = null;
|
||||
let matches = {
|
||||
_wholeMatch: wholeMatch,
|
||||
_linkId: linkId,
|
||||
_url: url,
|
||||
_title: title,
|
||||
text: text
|
||||
},
|
||||
otp,
|
||||
attributes = {};
|
||||
|
||||
title = title || null;
|
||||
url = url || null;
|
||||
|
@ -55,35 +63,85 @@ showdown.subParser('makehtml.link', function (text, options, globals) {
|
|||
}
|
||||
}
|
||||
|
||||
url = showdown.helper.applyBaseUrl(options.relativePathBaseUrl, url);
|
||||
url = url.replace(showdown.helper.regexes.asteriskDashTildeAndColon, showdown.helper.escapeCharactersCallback);
|
||||
attributes.href = url;
|
||||
|
||||
if (title && showdown.helper.isString(title)) {
|
||||
title = title
|
||||
.replace(/"/g, '"')
|
||||
.replace(showdown.helper.regexes.asteriskDashTildeAndColon, showdown.helper.escapeCharactersCallback);
|
||||
attributes.title = title;
|
||||
}
|
||||
|
||||
// optionLinksInNewWindow only applies
|
||||
// to external links. Hash links (#) open in same page
|
||||
if (options.openLinksInNewWindow && !/^#/.test(url)) {
|
||||
// escaped _
|
||||
target = ' rel="noopener noreferrer" target="¨E95Eblank"';
|
||||
attributes.rel = 'noopener noreferrer';
|
||||
attributes.target = '¨E95Eblank'; // escaped _
|
||||
|
||||
}
|
||||
|
||||
// Text can be a markdown element, so we run through the appropriate parsers
|
||||
text = showdown.subParser('makehtml.codeSpan')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.emoji')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.underline')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.emphasisAndStrong')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.strikethrough')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.ellipsis')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.hashHTMLSpans')(text, options, globals);
|
||||
let captureStartEvent = new showdown.Event('makehtml.link.' + subEvtName + '.onCapture', wholeMatch);
|
||||
captureStartEvent
|
||||
.setOutput(null)
|
||||
._setGlobals(globals)
|
||||
._setOptions(options)
|
||||
.setRegexp(pattern)
|
||||
.setMatches(matches)
|
||||
.setAttributes(attributes);
|
||||
captureStartEvent = globals.converter.dispatch(captureStartEvent);
|
||||
|
||||
// if something was passed as output, it takes precedence
|
||||
// and will be used as output
|
||||
if (captureStartEvent.output && captureStartEvent.output !== '') {
|
||||
otp = captureStartEvent.output;
|
||||
} else {
|
||||
attributes = captureStartEvent.attributes;
|
||||
text = captureStartEvent.matches.text || '';
|
||||
// Text can be a markdown element, so we run through the appropriate parsers
|
||||
text = showdown.subParser('makehtml.codeSpan')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.emoji')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.underline')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.emphasisAndStrong')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.strikethrough')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.ellipsis')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.hashHTMLSpans')(text, options, globals);
|
||||
otp = '<a' + showdown.helper._populateAttributes(attributes) + '>' + text + '</a>';
|
||||
}
|
||||
|
||||
|
||||
return otp;
|
||||
let beforeHashEvent = new showdown.Event('makehtml.link.' + subEvtName + '.onHash', otp);
|
||||
beforeHashEvent
|
||||
.setOutput(otp)
|
||||
._setGlobals(globals)
|
||||
._setOptions(options);
|
||||
beforeHashEvent = globals.converter.dispatch(beforeHashEvent);
|
||||
otp = beforeHashEvent.output;
|
||||
return showdown.subParser('makehtml.hashHTMLSpans')(otp, options, globals);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} mail
|
||||
* @returns {{mail: string, url: string}}
|
||||
*/
|
||||
function parseMail (mail) {
|
||||
let url = 'mailto:';
|
||||
mail = showdown.subParser('makehtml.unescapeSpecialChars')(mail, options, globals);
|
||||
if (options.encodeEmails) {
|
||||
url = showdown.helper.encodeEmailAddress(url + mail);
|
||||
mail = showdown.helper.encodeEmailAddress(mail);
|
||||
} else {
|
||||
url = url + mail;
|
||||
}
|
||||
return {
|
||||
mail: mail,
|
||||
url: url
|
||||
};
|
||||
}
|
||||
|
||||
//
|
||||
// Parser starts here
|
||||
//
|
||||
let startEvent = new showdown.Event('makehtml.link.onStart', text);
|
||||
startEvent
|
||||
.setOutput(text)
|
||||
|
@ -92,10 +150,172 @@ showdown.subParser('makehtml.link', function (text, options, globals) {
|
|||
startEvent = globals.converter.dispatch(startEvent);
|
||||
text = startEvent.output;
|
||||
|
||||
let referenceRegex = /\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g;
|
||||
|
||||
// 1. Handle reference-style links: [link text] [id]
|
||||
text = text.replace(referenceRegex, function (wholeMatch, altText, linkId) {
|
||||
return writeAnchorTag ('reference', referenceRegex, wholeMatch, altText, linkId, '');
|
||||
let referenceRegex = /\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]/g;
|
||||
text = text.replace(referenceRegex, function (wholeMatch, text, linkId) {
|
||||
// bail if we find 2 newlines somewhere
|
||||
if (/\n\n/.test(wholeMatch)) {
|
||||
return wholeMatch;
|
||||
}
|
||||
return writeAnchorTag ('reference', referenceRegex, wholeMatch, text, linkId);
|
||||
});
|
||||
|
||||
// 2. Handle inline-style links: [link text](url "optional title")
|
||||
// 2.1. Look for empty cases: []() and [empty]() and []("title")
|
||||
let inlineEmptyRegex = /\[(.*?)]\(<? ?>? ?(["'](.*)["'])?\)/g;
|
||||
text = text.replace(inlineEmptyRegex, function (wholeMatch, text, m1, title) {
|
||||
return writeAnchorTag ('inline', inlineEmptyRegex, wholeMatch, text, null, null, title, true);
|
||||
});
|
||||
|
||||
// 2.2. Look for cases with crazy urls like ./image/cat1).png
|
||||
// the url mus be enclosed in <>
|
||||
let inlineCrazyRegex = /\[((?:\[[^\]]*]|[^\[\]])*)]\s?\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\4))?[ \t]?\)/g;
|
||||
text = text.replace(inlineCrazyRegex, function (wholeMatch, text, url, m1, m2, title) {
|
||||
return writeAnchorTag ('inline', inlineCrazyRegex, wholeMatch, text, null, url, title);
|
||||
});
|
||||
|
||||
// 2.3. inline links with no title or titles wrapped in ' or ":
|
||||
// [text](url.com) || [text](<url.com>) || [text](url.com "title") || [text](<url.com> "title")
|
||||
let inlineNormalRegex1 = /\[([\S ]*?)]\s?\( *<?([^\s'"]*?(?:\(\S*?\)\S*?)?)>?\s*(?:(['"])(.*?)\3)? *\)/g;
|
||||
text = text.replace(inlineNormalRegex1, function (wholeMatch, text, url, m1, title) {
|
||||
return writeAnchorTag ('inline', inlineNormalRegex1, wholeMatch, text, null, url, title);
|
||||
});
|
||||
|
||||
// 2.4. inline links with titles wrapped in (): [foo](bar.com (title))
|
||||
let inlineNormalRegex2 = /\[([\S ]*?)]\s?\( *<?([^\s'"]*?(?:\(\S*?\)\S*?)?)>?\s+\((.*?)\) *\)/g;
|
||||
text = text.replace(inlineNormalRegex2, function (wholeMatch, text, url, title) {
|
||||
return writeAnchorTag ('inline', inlineNormalRegex2, wholeMatch, text, null, url, title);
|
||||
});
|
||||
|
||||
|
||||
// 3. Handle reference-style shortcuts: [link text]
|
||||
// These must come last in case there's a [link text][1] or [link text](/foo)
|
||||
let referenceShortcutRegex = /\[([^\[\]]+)]/g;
|
||||
text = text.replace(referenceShortcutRegex, function (wholeMatch, text) {
|
||||
return writeAnchorTag ('reference', referenceShortcutRegex, wholeMatch, text);
|
||||
});
|
||||
|
||||
// 4. Handle angle brackets links -> `<http://example.com/>`
|
||||
// Must come after links, because you can use < and > delimiters in inline links like [this](<url>).
|
||||
|
||||
// 4.1. Handle links first
|
||||
let angleBracketsLinksRegex = /<(((?:https?|ftp):\/\/|www\.)[^'">\s]+)>/gi;
|
||||
text = text.replace(angleBracketsLinksRegex, function (wholeMatch, url, urlStart) {
|
||||
let text = url;
|
||||
url = (urlStart === 'www.') ? 'http://' + url : url;
|
||||
return writeAnchorTag ('angleBrackets', angleBracketsLinksRegex, wholeMatch, text, null, url);
|
||||
});
|
||||
|
||||
// 4.2. Then mail adresses
|
||||
let angleBracketsMailRegex = /<(?:mailto:)?([-.\w]+@[-a-z\d]+(\.[-a-z\d]+)*\.[a-z]+)>/gi;
|
||||
text = text.replace(angleBracketsMailRegex, function (wholeMatch, mail) {
|
||||
const m = parseMail(mail);
|
||||
return writeAnchorTag ('angleBrackets', angleBracketsMailRegex, wholeMatch, m.mail, null, m.url);
|
||||
});
|
||||
|
||||
// 5. Handle GithubMentions (if option is enabled)
|
||||
if (options.ghMentions) {
|
||||
let ghMentionsRegex = /(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d._-]+?[a-z\d]+)*))/gi;
|
||||
text = text.replace(ghMentionsRegex, function (wholeMatch, st, escape, mentions, username) {
|
||||
// bail if the mentions was escaped
|
||||
if (escape === '\\') {
|
||||
return st + mentions;
|
||||
}
|
||||
// check if options.ghMentionsLink is a string
|
||||
// TODO Validation should be done at initialization not at runtime
|
||||
if (!showdown.helper.isString(options.ghMentionsLink)) {
|
||||
throw new Error('ghMentionsLink option must be a string');
|
||||
}
|
||||
let url = options.ghMentionsLink.replace(/\{u}/g, username);
|
||||
return st + writeAnchorTag ('reference', ghMentionsRegex, wholeMatch, mentions, null, url);
|
||||
});
|
||||
}
|
||||
|
||||
// 6 and 7 have to come here to prevent naked links to catch html
|
||||
// 6. Handle <a> tags
|
||||
text = text.replace(/<a\s[^>]*>[\s\S]*<\/a>/g, function (wholeMatch) {
|
||||
return showdown.helper._hashHTMLSpan(wholeMatch, globals);
|
||||
});
|
||||
|
||||
// 7. Handle <img> tags
|
||||
text = text.replace(/<img\s[^>]*\/?>/g, function (wholeMatch) {
|
||||
return showdown.helper._hashHTMLSpan(wholeMatch, globals);
|
||||
});
|
||||
|
||||
// 8. Handle naked links (if option is enabled)
|
||||
if (options.simplifiedAutoLink) {
|
||||
// 8.1. Check for naked URLs
|
||||
// we also include leading markdown magic chars [_*~] for cases like __https://www.google.com/foobar__
|
||||
let nakedUrlRegex = /([_*~]*?)(((?:https?|ftp):\/\/|www\.)[^\s<>"'`´.-][^\s<>"'`´]*?\.[a-z\d.]+[^\s<>"']*)\1/gi;
|
||||
text = text.replace(nakedUrlRegex, function (wholeMatch, leadingMDChars, url, urlPrefix) {
|
||||
// we now will start traversing the url from the front to back, looking for punctuation chars [_*~,;:.!?\)\]]
|
||||
const len = url.length;
|
||||
let suffix = '';
|
||||
|
||||
for (let i = len - 1; i >= 0; --i) {
|
||||
let char = url.charAt(i);
|
||||
if (/[_*~,;:.!?]/.test(char)) {
|
||||
// it's a punctuation char so we remove it from the url
|
||||
url = url.slice(0, -1);
|
||||
// and prepend it to the suffix
|
||||
suffix = char + suffix;
|
||||
} else if (/[)\]]/.test(char)) {
|
||||
// it's a parenthesis so we need to check for "balance" (kinda)
|
||||
let opPar, clPar;
|
||||
if (/\)/.test(char)) {
|
||||
// it's a curved parenthesis
|
||||
opPar = url.match(/\(/g) || [];
|
||||
clPar = url.match(/\)/g);
|
||||
} else {
|
||||
// it's a squared parenthesis
|
||||
opPar = url.match(/\[/g) || [];
|
||||
clPar = url.match(/]/g);
|
||||
}
|
||||
if (opPar.length < clPar.length) {
|
||||
// there are more closing Parenthesis than opening so chop it!!!!!
|
||||
url = url.slice(0, -1);
|
||||
// and prepend it to the suffix
|
||||
suffix = char + suffix;
|
||||
} else {
|
||||
// it's (kinda) balanced so our work is done
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// it's not a punctuation or a parenthesis so our work is done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// we copy the treated url to the text variable
|
||||
let txt = url;
|
||||
// finally, if it's a www shortcut, we prepend http
|
||||
url = (urlPrefix === 'www.') ? 'http://' + url : url;
|
||||
|
||||
// url part is done so let's take care of text now
|
||||
// we need to escape the text (because of links such as www.example.com/foo__bar__baz)
|
||||
txt = txt.replace(showdown.helper.regexes.asteriskDashTildeAndColon, showdown.helper.escapeCharactersCallback);
|
||||
|
||||
// and return the link tag, with the leadingMDChars and suffix. The leadingMDChars are added at the end too because
|
||||
// we consumed those characters in the regexp
|
||||
return leadingMDChars +
|
||||
writeAnchorTag ('autoLink', nakedUrlRegex, wholeMatch, txt, null, url) +
|
||||
suffix +
|
||||
leadingMDChars;
|
||||
});
|
||||
|
||||
// 8.2. Now check for naked mail
|
||||
let nakedMailRegex = /(^|\s)(?:mailto:)?([A-Za-z\d!#$%&'*+-/=?^_`{|}~.]+@[-a-z\d]+(\.[-a-z\d]+)*\.[a-z]+)(?=$|\s)/gmi;
|
||||
text = text.replace(nakedMailRegex, function (wholeMatch, leadingChar, mail) {
|
||||
const m = parseMail(mail);
|
||||
return leadingChar + writeAnchorTag ('autoLink', nakedMailRegex, wholeMatch, m.mail, null, m.url);
|
||||
});
|
||||
}
|
||||
|
||||
let afterEvent = new showdown.Event('makehtml.link.onEnd', text);
|
||||
afterEvent
|
||||
.setOutput(text)
|
||||
._setGlobals(globals)
|
||||
._setOptions(options);
|
||||
afterEvent = globals.converter.dispatch(afterEvent);
|
||||
return afterEvent.output;
|
||||
});
|
||||
|
|
|
@ -1,429 +0,0 @@
|
|||
////
|
||||
// makehtml/links.js
|
||||
// Copyright (c) 2018 ShowdownJS
|
||||
//
|
||||
// Transforms MD links into `<a>` html anchors
|
||||
//
|
||||
// A link contains link text (the visible text), a link destination (the URI that is the link destination), and
|
||||
// optionally a link title. There are two basic kinds of links in Markdown.
|
||||
// In inline links the destination and title are given immediately after the link text.
|
||||
// In reference links the destination and title are defined elsewhere in the document.
|
||||
//
|
||||
// ***Author:***
|
||||
// - Estevão Soares dos Santos (Tivie) <https://github.com/tivie>
|
||||
////
|
||||
|
||||
(function () {
|
||||
/**
|
||||
* Helper function: Wrapper function to pass as second replace parameter
|
||||
*
|
||||
* @param {RegExp} rgx
|
||||
* @param {string} evtRootName
|
||||
* @param {{}} options
|
||||
* @param {{}} globals
|
||||
* @param {boolean} emptyCase
|
||||
* @returns {Function}
|
||||
*/
|
||||
function replaceAnchorTagReference (rgx, evtRootName, options, globals, emptyCase) {
|
||||
emptyCase = !!emptyCase;
|
||||
return function (wholeMatch, text, id, url, m5, m6, title) {
|
||||
// bail we we find 2 newlines somewhere
|
||||
if (/\n\n/.test(wholeMatch)) {
|
||||
return wholeMatch;
|
||||
}
|
||||
|
||||
var evt = createEvent(rgx, evtRootName + '.captureStart', wholeMatch, text, id, url, title, options, globals);
|
||||
return writeAnchorTag(evt, options, globals, emptyCase);
|
||||
};
|
||||
}
|
||||
|
||||
function replaceAnchorTagBaseUrl (rgx, evtRootName, options, globals, emptyCase) {
|
||||
return function (wholeMatch, text, id, url, m5, m6, title) {
|
||||
url = showdown.helper.applyBaseUrl(options.relativePathBaseUrl, url);
|
||||
|
||||
var evt = createEvent(rgx, evtRootName + '.captureStart', wholeMatch, text, id, url, title, options, globals);
|
||||
return writeAnchorTag(evt, options, globals, emptyCase);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO Normalize this
|
||||
* Helper function: Create a capture event
|
||||
* @param {RegExp} rgx
|
||||
* @param {String} evtName Event name
|
||||
* @param {String} wholeMatch
|
||||
* @param {String} text
|
||||
* @param {String} id
|
||||
* @param {String} url
|
||||
* @param {String} title
|
||||
* @param {{}} options
|
||||
* @param {{}} globals
|
||||
* @returns {showdown.Event|*}
|
||||
*/
|
||||
function createEvent (rgx, evtName, wholeMatch, text, id, url, title, options, globals) {
|
||||
return globals.converter._dispatch(evtName, wholeMatch, options, globals, {
|
||||
regexp: rgx,
|
||||
matches: {
|
||||
wholeMatch: wholeMatch,
|
||||
text: text,
|
||||
id: id,
|
||||
url: url,
|
||||
title: title
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper Function: Normalize and write an anchor tag based on passed parameters
|
||||
* @param evt
|
||||
* @param options
|
||||
* @param globals
|
||||
* @param {boolean} emptyCase
|
||||
* @returns {string}
|
||||
*/
|
||||
function writeAnchorTag (evt, options, globals, emptyCase) {
|
||||
|
||||
var wholeMatch = evt.matches.wholeMatch;
|
||||
var text = evt.matches.text;
|
||||
var id = evt.matches.id;
|
||||
var url = evt.matches.url;
|
||||
var title = evt.matches.title;
|
||||
var target = '';
|
||||
|
||||
if (!title) {
|
||||
title = '';
|
||||
}
|
||||
id = (id) ? id.toLowerCase() : '';
|
||||
|
||||
if (emptyCase) {
|
||||
url = '';
|
||||
} else if (!url) {
|
||||
if (!id) {
|
||||
// lower-case and turn embedded newlines into spaces
|
||||
id = text.toLowerCase().replace(/ ?\n/g, ' ');
|
||||
}
|
||||
url = '#' + id;
|
||||
|
||||
if (!showdown.helper.isUndefined(globals.gUrls[id])) {
|
||||
url = globals.gUrls[id];
|
||||
if (!showdown.helper.isUndefined(globals.gTitles[id])) {
|
||||
title = globals.gTitles[id];
|
||||
}
|
||||
} else {
|
||||
return wholeMatch;
|
||||
}
|
||||
}
|
||||
//url = showdown.helper.escapeCharacters(url, '*_:~', false); // replaced line to improve performance
|
||||
url = url.replace(showdown.helper.regexes.asteriskDashTildeAndColon, showdown.helper.escapeCharactersCallback);
|
||||
|
||||
if (title !== '' && title !== null) {
|
||||
title = title.replace(/"/g, '"');
|
||||
//title = showdown.helper.escapeCharacters(title, '*_', false); // replaced line to improve performance
|
||||
title = title.replace(showdown.helper.regexes.asteriskDashTildeAndColon, showdown.helper.escapeCharactersCallback);
|
||||
title = ' title="' + title + '"';
|
||||
}
|
||||
|
||||
// optionLinksInNewWindow only applies
|
||||
// to external links. Hash links (#) open in same page
|
||||
if (options.openLinksInNewWindow && !/^#/.test(url)) {
|
||||
// escaped _
|
||||
target = ' rel="noopener noreferrer" target="¨E95Eblank"';
|
||||
}
|
||||
|
||||
// Text can be a markdown element, so we run through the appropriate parsers
|
||||
text = showdown.subParser('makehtml.codeSpan')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.emoji')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.underline')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.emphasisAndStrong')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.strikethrough')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.ellipsis')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.hashHTMLSpans')(text, options, globals);
|
||||
|
||||
//evt = createEvent(rgx, evtRootName + '.captureEnd', wholeMatch, text, id, url, title, options, globals);
|
||||
|
||||
var result = '<a href="' + url + '"' + title + target + '>' + text + '</a>';
|
||||
|
||||
//evt = createEvent(rgx, evtRootName + '.beforeHash', wholeMatch, text, id, url, title, options, globals);
|
||||
|
||||
result = showdown.subParser('makehtml.hashHTMLSpans')(result, options, globals);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
var evtRootName = 'makehtml.links';
|
||||
|
||||
/**
|
||||
* Turn Markdown link shortcuts into XHTML <a> tags.
|
||||
*/
|
||||
showdown.subParser('makehtml.links', function (text, options, globals) {
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
// 1. Handle reference-style links: [link text] [id]
|
||||
text = showdown.subParser('makehtml.links.reference')(text, options, globals);
|
||||
|
||||
// 2. Handle inline-style links: [link text](url "optional title")
|
||||
text = showdown.subParser('makehtml.links.inline')(text, options, globals);
|
||||
|
||||
// 3. Handle reference-style shortcuts: [link text]
|
||||
// These must come last in case there's a [link text][1] or [link text](/foo)
|
||||
text = showdown.subParser('makehtml.links.referenceShortcut')(text, options, globals);
|
||||
|
||||
// 4. Handle angle brackets links -> `<http://example.com/>`
|
||||
// Must come after links, because you can use < and > delimiters in inline links like [this](<url>).
|
||||
text = showdown.subParser('makehtml.links.angleBrackets')(text, options, globals);
|
||||
|
||||
// 5. Handle GithubMentions (if option is enabled)
|
||||
text = showdown.subParser('makehtml.links.ghMentions')(text, options, globals);
|
||||
|
||||
// 6. Handle <a> tags and img tags
|
||||
text = text.replace(/<a\s[^>]*>[\s\S]*<\/a>/g, function (wholeMatch) {
|
||||
return showdown.helper._hashHTMLSpan(wholeMatch, globals);
|
||||
});
|
||||
|
||||
text = text.replace(/<img\s[^>]*\/?>/g, function (wholeMatch) {
|
||||
return showdown.helper._hashHTMLSpan(wholeMatch, globals);
|
||||
});
|
||||
|
||||
// 7. Handle naked links (if option is enabled)
|
||||
text = showdown.subParser('makehtml.links.naked')(text, options, globals);
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO WRITE THIS DOCUMENTATION
|
||||
*/
|
||||
showdown.subParser('makehtml.links.inline', function (text, options, globals) {
|
||||
var evtRootName = evtRootName + '.inline';
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
// 1. Look for empty cases: []() and [empty]() and []("title")
|
||||
var rgxEmpty = /\[(.*?)]()()()()\(<? ?>? ?(?:["'](.*)["'])?\)/g;
|
||||
text = text.replace(rgxEmpty, replaceAnchorTagBaseUrl(rgxEmpty, evtRootName, options, globals, true));
|
||||
|
||||
// 2. Look for cases with crazy urls like ./image/cat1).png
|
||||
var rgxCrazy = /\[((?:\[[^\]]*]|[^\[\]])*)]()\s?\([ \t]?<([^>]*)>(?:[ \t]*((["'])([^"]*?)\5))?[ \t]?\)/g;
|
||||
text = text.replace(rgxCrazy, replaceAnchorTagBaseUrl(rgxCrazy, evtRootName, options, globals));
|
||||
|
||||
// 3. inline links with no title or titles wrapped in ' or ":
|
||||
// [text](url.com) || [text](<url.com>) || [text](url.com "title") || [text](<url.com> "title")
|
||||
//var rgx2 = /\[[ ]*[\s]?[ ]*([^\n\[\]]*?)[ ]*[\s]?[ ]*] ?()\(<?[ ]*[\s]?[ ]*([^\s'"]*)>?(?:[ ]*[\n]?[ ]*()(['"])(.*?)\5)?[ ]*[\s]?[ ]*\)/; // this regex is too slow!!!
|
||||
var rgx2 = /\[([\S ]*?)]\s?()\( *<?([^\s'"]*?(?:\([\S]*?\)[\S]*?)?)>?\s*(?:()(['"])(.*?)\5)? *\)/g;
|
||||
text = text.replace(rgx2, replaceAnchorTagBaseUrl(rgx2, evtRootName, options, globals));
|
||||
|
||||
// 4. inline links with titles wrapped in (): [foo](bar.com (title))
|
||||
var rgx3 = /\[([\S ]*?)]\s?()\( *<?([^\s'"]*?(?:\([\S]*?\)[\S]*?)?)>?\s+()()\((.*?)\) *\)/g;
|
||||
text = text.replace(rgx3, replaceAnchorTagBaseUrl(rgx3, evtRootName, options, globals));
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO WRITE THIS DOCUMENTATION
|
||||
*/
|
||||
showdown.subParser('makehtml.links.reference', function (text, options, globals) {
|
||||
var evtRootName = evtRootName + '.reference';
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
var rgx = /\[((?:\[[^\]]*]|[^\[\]])*)] ?(?:\n *)?\[(.*?)]()()()()/g;
|
||||
text = text.replace(rgx, replaceAnchorTagReference(rgx, evtRootName, options, globals));
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO WRITE THIS DOCUMENTATION
|
||||
*/
|
||||
showdown.subParser('makehtml.links.referenceShortcut', function (text, options, globals) {
|
||||
var evtRootName = evtRootName + '.referenceShortcut';
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
var rgx = /\[([^\[\]]+)]()()()()()/g;
|
||||
text = text.replace(rgx, replaceAnchorTagReference(rgx, evtRootName, options, globals));
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO WRITE THIS DOCUMENTATION
|
||||
*/
|
||||
showdown.subParser('makehtml.links.ghMentions', function (text, options, globals) {
|
||||
var evtRootName = evtRootName + 'ghMentions';
|
||||
|
||||
if (!options.ghMentions) {
|
||||
return text;
|
||||
}
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
var rgx = /(^|\s)(\\)?(@([a-z\d]+(?:[a-z\d._-]+?[a-z\d]+)*))/gi;
|
||||
|
||||
text = text.replace(rgx, function (wholeMatch, st, escape, mentions, username) {
|
||||
// bail if the mentions was escaped
|
||||
if (escape === '\\') {
|
||||
return st + mentions;
|
||||
}
|
||||
|
||||
// check if options.ghMentionsLink is a string
|
||||
// TODO Validation should be done at initialization not at runtime
|
||||
if (!showdown.helper.isString(options.ghMentionsLink)) {
|
||||
throw new Error('ghMentionsLink option must be a string');
|
||||
}
|
||||
var url = options.ghMentionsLink.replace(/{u}/g, username);
|
||||
var evt = createEvent(rgx, evtRootName + '.captureStart', wholeMatch, mentions, null, url, null, options, globals);
|
||||
// captureEnd Event is triggered inside writeAnchorTag function
|
||||
return st + writeAnchorTag(evt, options, globals);
|
||||
});
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO WRITE THIS DOCUMENTATION
|
||||
*/
|
||||
showdown.subParser('makehtml.links.angleBrackets', function (text, options, globals) {
|
||||
var evtRootName = 'makehtml.links.angleBrackets';
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
// 1. Parse links first
|
||||
var urlRgx = /<(((?:https?|ftp):\/\/|www\.)[^'">\s]+)>/gi;
|
||||
text = text.replace(urlRgx, function (wholeMatch, url, urlStart) {
|
||||
var text = url;
|
||||
url = (urlStart === 'www.') ? 'http://' + url : url;
|
||||
var evt = createEvent(urlRgx, evtRootName + '.captureStart', wholeMatch, text, null, url, null, options, globals);
|
||||
return writeAnchorTag(evt, options, globals);
|
||||
});
|
||||
|
||||
// 2. Then Mail Addresses
|
||||
var mailRgx = /<(?:mailto:)?([-.\w]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi;
|
||||
text = text.replace(mailRgx, function (wholeMatch, mail) {
|
||||
var url = 'mailto:';
|
||||
mail = showdown.subParser('makehtml.unescapeSpecialChars')(mail, options, globals);
|
||||
if (options.encodeEmails) {
|
||||
url = showdown.helper.encodeEmailAddress(url + mail);
|
||||
mail = showdown.helper.encodeEmailAddress(mail);
|
||||
} else {
|
||||
url = url + mail;
|
||||
}
|
||||
var evt = createEvent(mailRgx, evtRootName + '.captureStart', wholeMatch, mail, null, url, null, options, globals);
|
||||
return writeAnchorTag(evt, options, globals);
|
||||
});
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* TODO MAKE THIS WORK (IT'S NOT ACTIVATED)
|
||||
* TODO WRITE THIS DOCUMENTATION
|
||||
*/
|
||||
showdown.subParser('makehtml.links.naked', function (text, options, globals) {
|
||||
if (!options.simplifiedAutoLink) {
|
||||
return text;
|
||||
}
|
||||
|
||||
var evtRootName = 'makehtml.links.naked';
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.start', text, options, globals).getText();
|
||||
|
||||
// 2. Now we check for
|
||||
// we also include leading markdown magic chars [_*~] for cases like __https://www.google.com/foobar__
|
||||
var urlRgx = /([_*~]*?)(((?:https?|ftp):\/\/|www\.)[^\s<>"'`´.-][^\s<>"'`´]*?\.[a-z\d.]+[^\s<>"']*)\1/gi;
|
||||
text = text.replace(urlRgx, function (wholeMatch, leadingMDChars, url, urlPrefix) {
|
||||
|
||||
// we now will start traversing the url from the front to back, looking for punctuation chars [_*~,;:.!?\)\]]
|
||||
var len = url.length;
|
||||
var suffix = '';
|
||||
for (var i = len - 1; i >= 0; --i) {
|
||||
var char = url.charAt(i);
|
||||
|
||||
if (/[_*~,;:.!?]/.test(char)) {
|
||||
// it's a punctuation char
|
||||
// we remove it from the url
|
||||
url = url.slice(0, -1);
|
||||
// and prepend it to the suffix
|
||||
suffix = char + suffix;
|
||||
} else if (/\)/.test(char)) {
|
||||
var opPar = url.match(/\(/g) || [];
|
||||
var clPar = url.match(/\)/g);
|
||||
|
||||
// it's a curved parenthesis so we need to check for "balance" (kinda)
|
||||
if (opPar.length < clPar.length) {
|
||||
// there are more closing Parenthesis than opening so chop it!!!!!
|
||||
url = url.slice(0, -1);
|
||||
// and prepend it to the suffix
|
||||
suffix = char + suffix;
|
||||
} else {
|
||||
// it's (kinda) balanced so our work is done
|
||||
break;
|
||||
}
|
||||
} else if (/]/.test(char)) {
|
||||
var opPar2 = url.match(/\[/g) || [];
|
||||
var clPar2 = url.match(/\]/g);
|
||||
// it's a squared parenthesis so we need to check for "balance" (kinda)
|
||||
if (opPar2.length < clPar2.length) {
|
||||
// there are more closing Parenthesis than opening so chop it!!!!!
|
||||
url = url.slice(0, -1);
|
||||
// and prepend it to the suffix
|
||||
suffix = char + suffix;
|
||||
} else {
|
||||
// it's (kinda) balanced so our work is done
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// it's not a punctuation or a parenthesis so our work is done
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// we copy the treated url to the text variable
|
||||
var text = url;
|
||||
// finally, if it's a www shortcut, we prepend http
|
||||
url = (urlPrefix === 'www.') ? 'http://' + url : url;
|
||||
|
||||
// url part is done so let's take care of text now
|
||||
// we need to escape the text (because of links such as www.example.com/foo__bar__baz)
|
||||
text = text.replace(showdown.helper.regexes.asteriskDashTildeAndColon, showdown.helper.escapeCharactersCallback);
|
||||
|
||||
// finally we dispatch the event
|
||||
var evt = createEvent(urlRgx, evtRootName + '.captureStart', wholeMatch, text, null, url, null, options, globals);
|
||||
|
||||
// and return the link tag, with the leadingMDChars and suffix. The leadingMDChars are added at the end too because
|
||||
// we consumed those characters in the regexp
|
||||
return leadingMDChars + writeAnchorTag(evt, options, globals) + suffix + leadingMDChars;
|
||||
});
|
||||
|
||||
// 2. Then mails
|
||||
var mailRgx = /(^|\s)(?:mailto:)?([A-Za-z0-9!#$%&'*+-/=?^_`{|}~.]+@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)(?=$|\s)/gmi;
|
||||
text = text.replace(mailRgx, function (wholeMatch, leadingChar, mail) {
|
||||
var url = 'mailto:';
|
||||
mail = showdown.subParser('makehtml.unescapeSpecialChars')(mail, options, globals);
|
||||
if (options.encodeEmails) {
|
||||
url = showdown.helper.encodeEmailAddress(url + mail);
|
||||
mail = showdown.helper.encodeEmailAddress(mail);
|
||||
} else {
|
||||
url = url + mail;
|
||||
}
|
||||
var evt = createEvent(mailRgx, evtRootName + '.captureStart', wholeMatch, mail, null, url, null, options, globals);
|
||||
return leadingChar + writeAnchorTag(evt, options, globals);
|
||||
});
|
||||
|
||||
|
||||
text = globals.converter._dispatch(evtRootName + '.end', text, options, globals).getText();
|
||||
return text;
|
||||
});
|
||||
})();
|
|
@ -20,7 +20,7 @@ showdown.subParser('makehtml.spanGamut', function (text, options, globals) {
|
|||
// Process link and image tags. Images must come first,
|
||||
// because ![foo][f] looks like a link.
|
||||
text = showdown.subParser('makehtml.image')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.links')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.link')(text, options, globals);
|
||||
|
||||
text = showdown.subParser('makehtml.emoji')(text, options, globals);
|
||||
text = showdown.subParser('makehtml.underline')(text, options, globals);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* Created by Estevao on 08-06-2015.
|
||||
*/
|
||||
var bootstrap = require('./makehtml.bootstrap.js'),
|
||||
const bootstrap = require('./makehtml.bootstrap.js'),
|
||||
showdown = bootstrap.showdown,
|
||||
assertion = bootstrap.assertion,
|
||||
testsuite = bootstrap.getTestSuite('test/functional/makehtml/cases/features/'),
|
||||
|
@ -29,8 +29,8 @@ describe('makeHtml() features testsuite', function () {
|
|||
'use strict';
|
||||
|
||||
describe('issues', function () {
|
||||
for (var i = 0; i < testsuite.length; ++i) {
|
||||
var converter;
|
||||
for (let i = 0; i < testsuite.length; ++i) {
|
||||
let converter;
|
||||
if (testsuite[i].name === '#143.support-image-dimensions') {
|
||||
converter = new showdown.Converter({parseImgDimensions: true});
|
||||
} else if (testsuite[i].name === '#69.header-level-start') {
|
||||
|
@ -114,9 +114,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test Table Syntax Support **/
|
||||
describe('table support', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = tableSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'basic-with-header-ids') {
|
||||
converter = new showdown.Converter({tables: true, tablesHeaderId: true});
|
||||
} else if (suite[i].name === '#179.parse-md-in-table-ths') {
|
||||
|
@ -130,9 +130,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test simplifiedAutoLink Support **/
|
||||
describe('simplifiedAutoLink support in', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = simplifiedAutoLinkSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'emphasis-and-strikethrough') {
|
||||
converter = new showdown.Converter({simplifiedAutoLink: true, strikethrough: true});
|
||||
} else if (suite[i].name === 'disallow-underscores') {
|
||||
|
@ -148,9 +148,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test openLinksInNewWindow support **/
|
||||
describe('openLinksInNewWindow support in', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = openLinksInNewWindowSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'simplifiedAutoLink') {
|
||||
converter = new showdown.Converter({openLinksInNewWindow: true, simplifiedAutoLink: true});
|
||||
} else {
|
||||
|
@ -162,9 +162,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test disableForced4SpacesIndentedSublists support **/
|
||||
describe('disableForced4SpacesIndentedSublists support in', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = disableForced4SpacesIndentedSublistsSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({disableForced4SpacesIndentedSublists: true});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
@ -172,9 +172,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test rawHeaderId support **/
|
||||
describe('rawHeaderId support', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = rawHeaderIdSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'with-prefixHeaderId') {
|
||||
converter = new showdown.Converter({rawHeaderId: true, prefixHeaderId: '/prefix/'});
|
||||
} else {
|
||||
|
@ -186,9 +186,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test rawPrefixHeaderId support **/
|
||||
describe('rawPrefixHeaderId support', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = rawPrefixHeaderIdSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({rawPrefixHeaderId: true, prefixHeaderId: '/prefix/'});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test emojis support **/
|
||||
describe('emojis support', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = emojisSuite,
|
||||
imgSrcRegexp = /<img[^>]+src=("https?:\/\/[^"]+"|'https?:\/\/[^']+')/g;
|
||||
|
||||
|
@ -222,7 +222,7 @@ describe('makeHtml() features testsuite', function () {
|
|||
};
|
||||
}
|
||||
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'simplifiedautolinks') {
|
||||
converter = new showdown.Converter({emoji: true, simplifiedAutoLink: true});
|
||||
} else {
|
||||
|
@ -231,7 +231,7 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
|
||||
var imgUrl = imgSrcRegexp.exec(suite[i].expected);
|
||||
let imgUrl = imgSrcRegexp.exec(suite[i].expected);
|
||||
if (imgUrl) {
|
||||
it('should use a working emoji URL', testImageUrlExists(imgUrl[1]));
|
||||
}
|
||||
|
@ -240,9 +240,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test underline support **/
|
||||
describe('underline support', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = underlineSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'simplifiedautolinks') {
|
||||
converter = new showdown.Converter({underline: true, simplifiedAutoLink: true});
|
||||
} else {
|
||||
|
@ -254,9 +254,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test ellipsis option **/
|
||||
describe('ellipsis option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = ellipsisSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({ellipsis: false});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
@ -264,9 +264,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test literalMidWordUnderscores option **/
|
||||
describe('literalMidWordUnderscores option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = literalMidWordUnderscoresSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({literalMidWordUnderscores: true});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
@ -275,9 +275,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
/** test literalMidWordAsterisks option **/
|
||||
/*
|
||||
describe('literalMidWordAsterisks option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = literalMidWordAsterisksSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({literalMidWordAsterisks: true});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
@ -286,9 +286,9 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test completeHTMLDocument option **/
|
||||
describe('completeHTMLDocument option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = completeHTMLOutputSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({completeHTMLDocument: true});
|
||||
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
|
@ -297,10 +297,10 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test metadata option **/
|
||||
describe('metadata option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = metadataSuite;
|
||||
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
if (suite[i].name === 'embeded-in-output' ||
|
||||
suite[i].name === 'embeded-two-consecutive-metadata-blocks' ||
|
||||
suite[i].name === 'embeded-two-consecutive-metadata-blocks-different-symbols') {
|
||||
|
@ -316,10 +316,10 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test metadata option **/
|
||||
describe('splitAdjacentBlockquotes option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = splitAdjacentBlockquotesSuite;
|
||||
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({splitAdjacentBlockquotes: true});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
@ -327,10 +327,10 @@ describe('makeHtml() features testsuite', function () {
|
|||
|
||||
/** test moreStyling option **/
|
||||
describe('moreStyling option', function () {
|
||||
var converter,
|
||||
let converter,
|
||||
suite = moreStyling;
|
||||
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
for (let i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({moreStyling: true, tasklists: true});
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
|
||||
describe('showdown.Event', function () {
|
||||
'use strict';
|
||||
let eventList = {
|
||||
|
||||
};
|
||||
//let eventList = {};
|
||||
describe('event listeners', function () {
|
||||
|
||||
it('should listen to triggered event', function () {
|
||||
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user