mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
Added new extension registering method
This commit is contained in:
parent
8ee87ead9f
commit
0fd10cb56a
BIN
dist/showdown.js
vendored
BIN
dist/showdown.js
vendored
Binary file not shown.
BIN
dist/showdown.js.map
vendored
BIN
dist/showdown.js.map
vendored
Binary file not shown.
BIN
dist/showdown.min.js
vendored
BIN
dist/showdown.min.js
vendored
Binary file not shown.
BIN
dist/showdown.min.js.map
vendored
BIN
dist/showdown.min.js.map
vendored
Binary file not shown.
|
@ -8,6 +8,7 @@ if (!showdown.hasOwnProperty('helper')) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if var is string
|
* Check if var is string
|
||||||
|
* @static
|
||||||
* @param {string} a
|
* @param {string} a
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +19,7 @@ showdown.helper.isString = function isString(a) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ForEach helper function
|
* ForEach helper function
|
||||||
|
* @static
|
||||||
* @param {*} obj
|
* @param {*} obj
|
||||||
* @param {function} callback
|
* @param {function} callback
|
||||||
*/
|
*/
|
||||||
|
@ -26,8 +28,7 @@ showdown.helper.forEach = function forEach(obj, callback) {
|
||||||
if (typeof obj.forEach === 'function') {
|
if (typeof obj.forEach === 'function') {
|
||||||
obj.forEach(callback);
|
obj.forEach(callback);
|
||||||
} else {
|
} else {
|
||||||
var i, len = obj.length;
|
for (var i = 0; i < obj.length; i++) {
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
callback(obj[i], i, obj);
|
callback(obj[i], i, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +36,7 @@ showdown.helper.forEach = function forEach(obj, callback) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* isArray helper function
|
* isArray helper function
|
||||||
|
* @static
|
||||||
* @param {*} a
|
* @param {*} a
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
|
@ -45,7 +47,6 @@ showdown.helper.isArray = function isArray(a) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if value is undefined
|
* Check if value is undefined
|
||||||
*
|
|
||||||
* @static
|
* @static
|
||||||
* @param {*} value The value to check.
|
* @param {*} value The value to check.
|
||||||
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
|
* @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
|
||||||
|
@ -55,6 +56,17 @@ showdown.helper.isUndefined = function isUndefined(value) {
|
||||||
return typeof value === 'undefined';
|
return typeof value === 'undefined';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Standardidize extension name
|
||||||
|
* @static
|
||||||
|
* @param {string} s extension name
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
showdown.helper.stdExtName = function (s) {
|
||||||
|
'use strict';
|
||||||
|
return s.replace(/[_-]||\s/g, '').toLowerCase();
|
||||||
|
};
|
||||||
|
|
||||||
function escapeCharactersCallback(wholeMatch, m1) {
|
function escapeCharactersCallback(wholeMatch, m1) {
|
||||||
'use strict';
|
'use strict';
|
||||||
var charCodeToEscape = m1.charCodeAt(0);
|
var charCodeToEscape = m1.charCodeAt(0);
|
||||||
|
@ -63,6 +75,7 @@ function escapeCharactersCallback(wholeMatch, m1) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback used to escape characters when passing through String.replace
|
* Callback used to escape characters when passing through String.replace
|
||||||
|
* @static
|
||||||
* @param {string} wholeMatch
|
* @param {string} wholeMatch
|
||||||
* @param {string} m1
|
* @param {string} m1
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
|
@ -71,7 +84,7 @@ showdown.helper.escapeCharactersCallback = escapeCharactersCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape characters in a string
|
* Escape characters in a string
|
||||||
*
|
* @static
|
||||||
* @param {string} text
|
* @param {string} text
|
||||||
* @param {string} charsToEscape
|
* @param {string} charsToEscape
|
||||||
* @param {boolean} afterBackslash
|
* @param {boolean} afterBackslash
|
||||||
|
|
111
src/showdown.js
111
src/showdown.js
|
@ -5,32 +5,24 @@
|
||||||
// Private properties
|
// Private properties
|
||||||
var showdown = {},
|
var showdown = {},
|
||||||
parsers = {},
|
parsers = {},
|
||||||
|
extensions = {},
|
||||||
globalOptions = {
|
globalOptions = {
|
||||||
omitExtraWLInCodeBlocks: false,
|
omitExtraWLInCodeBlocks: false,
|
||||||
prefixHeaderId: false
|
prefixHeaderId: false
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public API
|
|
||||||
//
|
|
||||||
/**
|
/**
|
||||||
* helper namespace
|
* helper namespace
|
||||||
* @type {{}}
|
* @type {{}}
|
||||||
*/
|
*/
|
||||||
showdown.helper = {};
|
showdown.helper = {};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
|
||||||
// API
|
|
||||||
//
|
|
||||||
|
|
||||||
// Public properties
|
// Public properties
|
||||||
showdown.extensions = {};
|
showdown.extensions = {};
|
||||||
|
|
||||||
//Public methods
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a global option
|
* Set a global option
|
||||||
*
|
* @static
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @param {string} value
|
* @param {string} value
|
||||||
* @returns {showdown}
|
* @returns {showdown}
|
||||||
|
@ -43,7 +35,7 @@ showdown.setOption = function (key, value) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a global option
|
* Get a global option
|
||||||
*
|
* @static
|
||||||
* @param {string} key
|
* @param {string} key
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
|
@ -54,6 +46,7 @@ showdown.getOption = function (key) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the global options
|
* Get the global options
|
||||||
|
* @static
|
||||||
* @returns {{omitExtraWLInCodeBlocks: boolean, prefixHeaderId: boolean}}
|
* @returns {{omitExtraWLInCodeBlocks: boolean, prefixHeaderId: boolean}}
|
||||||
*/
|
*/
|
||||||
showdown.getOptions = function () {
|
showdown.getOptions = function () {
|
||||||
|
@ -66,6 +59,7 @@ showdown.getOptions = function () {
|
||||||
*
|
*
|
||||||
* subParser(name) - Get a registered subParser
|
* subParser(name) - Get a registered subParser
|
||||||
* subParser(name, func) - Register a subParser
|
* subParser(name, func) - Register a subParser
|
||||||
|
* @static
|
||||||
* @param {string} name
|
* @param {string} name
|
||||||
* @param {function} [func]
|
* @param {function} [func]
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
|
@ -85,6 +79,47 @@ showdown.subParser = function (name, func) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
showdown.extension = function (name, ext) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (!showdown.helper.isString(name)) {
|
||||||
|
throw Error('Extension \'name\' must be a string');
|
||||||
|
}
|
||||||
|
|
||||||
|
name = showdown.helper.stdExtName(name);
|
||||||
|
|
||||||
|
if (showdown.helper.isUndefined(ext)) {
|
||||||
|
return getExtension();
|
||||||
|
} else {
|
||||||
|
return setExtension();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function getExtension(name) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (!extensions.hasOwnProperty(name)) {
|
||||||
|
throw Error('Extension named ' + name + ' is not registered!');
|
||||||
|
}
|
||||||
|
return extensions[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
function setExtension(name, ext) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (typeof ext !== 'object') {
|
||||||
|
throw Error('A Showdown Extension must be an object, ' + typeof ext + ' given');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!showdown.helper.isString(ext.type)) {
|
||||||
|
throw Error('When registering a showdown extension, "type" must be a string, ' + typeof ext.type + ' given');
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.type = ext.type.toLowerCase();
|
||||||
|
|
||||||
|
extensions[name] = ext;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Showdown Converter class
|
* Showdown Converter class
|
||||||
*
|
*
|
||||||
|
@ -97,10 +132,9 @@ showdown.Converter = function (converterOptions) {
|
||||||
converterOptions = converterOptions || {};
|
converterOptions = converterOptions || {};
|
||||||
|
|
||||||
var options = globalOptions,
|
var options = globalOptions,
|
||||||
|
langExtensions = [],
|
||||||
|
outputModifiers = [],
|
||||||
parserOrder = [
|
parserOrder = [
|
||||||
'detab',
|
|
||||||
'stripBlankLines',
|
|
||||||
//runLanguageExtensions,
|
|
||||||
'githubCodeBlocks',
|
'githubCodeBlocks',
|
||||||
'hashHTMLBlocks',
|
'hashHTMLBlocks',
|
||||||
'stripLinkDefinitions',
|
'stripLinkDefinitions',
|
||||||
|
@ -117,6 +151,38 @@ showdown.Converter = function (converterOptions) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse options
|
||||||
|
if (options.extensions) {
|
||||||
|
|
||||||
|
// Iterate over each plugin
|
||||||
|
showdown.helper.forEach(options.extensions, function (plugin) {
|
||||||
|
|
||||||
|
// Assume it's a bundled plugin if a string is given
|
||||||
|
if (typeof plugin === 'string') {
|
||||||
|
plugin = extensions[showdown.helper.stdExtName(plugin)];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof plugin === 'function') {
|
||||||
|
// Iterate over each extension within that plugin
|
||||||
|
showdown.helper.forEach(plugin(self), function (ext) {
|
||||||
|
// Sort extensions by type
|
||||||
|
if (ext.type) {
|
||||||
|
if (ext.type === 'language' || ext.type === 'lang') {
|
||||||
|
langExtensions.push(ext);
|
||||||
|
} else if (ext.type === 'output' || ext.type === 'html') {
|
||||||
|
outputModifiers.push(ext);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Assume language extension
|
||||||
|
outputModifiers.push(ext);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw 'Extension "' + plugin + '" could not be loaded. It was either not found or is not a valid extension.';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a markdown string into HTML
|
* Converts a markdown string into HTML
|
||||||
* @param {string} text
|
* @param {string} text
|
||||||
|
@ -134,7 +200,9 @@ showdown.Converter = function (converterOptions) {
|
||||||
gUrls: {},
|
gUrls: {},
|
||||||
gTitles: {},
|
gTitles: {},
|
||||||
gListLevel: 0,
|
gListLevel: 0,
|
||||||
hashLinkCounts: {}
|
hashLinkCounts: {},
|
||||||
|
langExtensions: langExtensions,
|
||||||
|
outputModifiers: outputModifiers
|
||||||
};
|
};
|
||||||
|
|
||||||
// attacklab: Replace ~ with ~T
|
// attacklab: Replace ~ with ~T
|
||||||
|
@ -155,6 +223,15 @@ showdown.Converter = function (converterOptions) {
|
||||||
// Make sure text begins and ends with a couple of newlines:
|
// Make sure text begins and ends with a couple of newlines:
|
||||||
text = '\n\n' + text + '\n\n';
|
text = '\n\n' + text + '\n\n';
|
||||||
|
|
||||||
|
// detab
|
||||||
|
text = parsers.detab(text, options, globals);
|
||||||
|
|
||||||
|
// stripBlankLines
|
||||||
|
text = parsers.stripBlankLines(text, options, globals);
|
||||||
|
|
||||||
|
//run languageExtensions
|
||||||
|
text = parsers.languageExtensions(text, options, globals);
|
||||||
|
|
||||||
// Run all registered parsers
|
// Run all registered parsers
|
||||||
for (var i = 0; i < parserOrder.length; ++i) {
|
for (var i = 0; i < parserOrder.length; ++i) {
|
||||||
var name = parserOrder[i];
|
var name = parserOrder[i];
|
||||||
|
@ -168,9 +245,7 @@ showdown.Converter = function (converterOptions) {
|
||||||
text = text.replace(/~T/g, '~');
|
text = text.replace(/~T/g, '~');
|
||||||
|
|
||||||
// Run output modifiers
|
// Run output modifiers
|
||||||
//showdown.forEach(g_output_modifiers, function (x) {
|
text = parsers.outputModifiers(text, options, globals);
|
||||||
// text = _ExecuteExtension(x, text);
|
|
||||||
//});
|
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
11
src/subParsers/languageExtensions.js
Normal file
11
src/subParsers/languageExtensions.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Run language extensions
|
||||||
|
*/
|
||||||
|
showdown.subParser('languageExtensions', function (text, config, globals) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
showdown.helper.forEach(globals.langExtensions, function (ext) {
|
||||||
|
text = showdown.subParser('runExtension')(ext, text);
|
||||||
|
});
|
||||||
|
return text;
|
||||||
|
});
|
11
src/subParsers/outputModifiers.js
Normal file
11
src/subParsers/outputModifiers.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Run language extensions
|
||||||
|
*/
|
||||||
|
showdown.subParser('outputModifiers', function (text, config, globals) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
showdown.helper.forEach(globals.outputModifiers, function (ext) {
|
||||||
|
text = showdown.subParser('runExtension')(ext, text);
|
||||||
|
});
|
||||||
|
return text;
|
||||||
|
});
|
13
src/subParsers/runExtension.js
Normal file
13
src/subParsers/runExtension.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/**
|
||||||
|
* Run language extensions
|
||||||
|
*/
|
||||||
|
showdown.subParser('runExtension', function (ext, text) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
if (ext.regex) {
|
||||||
|
var re = new RegExp(ext.regex, 'g');
|
||||||
|
return text.replace(re, ext.replace);
|
||||||
|
} else if (ext.filter) {
|
||||||
|
return ext.filter(text);
|
||||||
|
}
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user