mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
feat(metadata): add support for embedded metadata
A simple metadata parser can be useful in markdown documents. This commit introduces the feature, with the following syntax: --- or ««« at tstart of the document, (optionally) followed by a alphanumeric format identifier followed by key value pairs separated by a colon and a space followed by --- or  Also, adds methods for retrieving the parsed metadata, namely: getMetadata() and getMetadataFormat Closes #260
This commit is contained in:
parent
a8427c9423
commit
63d949f731
182
dist/showdown.js
vendored
182
dist/showdown.js
vendored
@ -153,10 +153,15 @@ function getDefaultOpts (simple) {
|
||||
description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
|
||||
type: 'boolean'
|
||||
},
|
||||
completeHTMLOutput: {
|
||||
completeHTMLDocument: {
|
||||
defaultValue: false,
|
||||
description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
|
||||
type: 'boolean'
|
||||
},
|
||||
metadata: {
|
||||
defaultValue: false,
|
||||
description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
|
||||
type: 'boolean'
|
||||
}
|
||||
};
|
||||
if (simple === false) {
|
||||
@ -2172,7 +2177,17 @@ showdown.Converter = function (converterOptions) {
|
||||
/**
|
||||
* The flavor set in this converter
|
||||
*/
|
||||
setConvFlavor = setFlavor;
|
||||
setConvFlavor = setFlavor,
|
||||
|
||||
/**
|
||||
* Metadata of the document
|
||||
* @type {{parsed: {}, raw: string, format: string}}
|
||||
*/
|
||||
metadata = {
|
||||
parsed: {},
|
||||
raw: '',
|
||||
format: ''
|
||||
};
|
||||
|
||||
_constructor();
|
||||
|
||||
@ -2384,7 +2399,12 @@ showdown.Converter = function (converterOptions) {
|
||||
langExtensions: langExtensions,
|
||||
outputModifiers: outputModifiers,
|
||||
converter: this,
|
||||
ghCodeBlocks: []
|
||||
ghCodeBlocks: [],
|
||||
metadata: {
|
||||
parsed: {},
|
||||
raw: '',
|
||||
format: ''
|
||||
}
|
||||
};
|
||||
|
||||
// This lets us use ¨ trema as an escape char to avoid md5 hashes
|
||||
@ -2428,6 +2448,7 @@ showdown.Converter = function (converterOptions) {
|
||||
});
|
||||
|
||||
// run the sub parsers
|
||||
text = showdown.subParser('metadata')(text, options, globals);
|
||||
text = showdown.subParser('hashPreCodeTags')(text, options, globals);
|
||||
text = showdown.subParser('githubCodeBlocks')(text, options, globals);
|
||||
text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
|
||||
@ -2444,13 +2465,15 @@ showdown.Converter = function (converterOptions) {
|
||||
text = text.replace(/¨T/g, '¨');
|
||||
|
||||
// render a complete html document instead of a partial if the option is enabled
|
||||
text = showdown.subParser('completeHTMLOutput')(text, options, globals);
|
||||
text = showdown.subParser('completeHTMLDocument')(text, options, globals);
|
||||
|
||||
// Run output modifiers
|
||||
showdown.helper.forEach(outputModifiers, function (ext) {
|
||||
text = showdown.subParser('runExtension')(ext, text, options, globals);
|
||||
});
|
||||
|
||||
// update metadata
|
||||
metadata = globals.metadata;
|
||||
return text;
|
||||
};
|
||||
|
||||
@ -2558,6 +2581,52 @@ showdown.Converter = function (converterOptions) {
|
||||
output: outputModifiers
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the metadata of the previously parsed document
|
||||
* @param raw
|
||||
* @returns {string|{}}
|
||||
*/
|
||||
this.getMetadata = function (raw) {
|
||||
if (raw) {
|
||||
return metadata.raw;
|
||||
} else {
|
||||
return metadata.parsed;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the metadata format of the previously parsed document
|
||||
* @returns {string}
|
||||
*/
|
||||
this.getMetadataFormat = function () {
|
||||
return metadata.format;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private: set a single key, value metadata pair
|
||||
* @param {string} key
|
||||
* @param {string} value
|
||||
*/
|
||||
this._setMetadataPair = function (key, value) {
|
||||
metadata.parsed[key] = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private: set metadata format
|
||||
* @param {string} format
|
||||
*/
|
||||
this._setMetadataFormat = function (format) {
|
||||
metadata.format = format;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private: set metadata raw text
|
||||
* @param {string} raw
|
||||
*/
|
||||
this._setMetadataRaw = function (raw) {
|
||||
metadata.raw = raw;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2899,18 +2968,63 @@ showdown.subParser('codeSpans', function (text, options, globals) {
|
||||
/**
|
||||
* Turn Markdown link shortcuts into XHTML <a> tags.
|
||||
*/
|
||||
showdown.subParser('completeHTMLOutput', function (text, options, globals) {
|
||||
showdown.subParser('completeHTMLDocument', function (text, options, globals) {
|
||||
'use strict';
|
||||
|
||||
if (!options.completeHTMLOutput) {
|
||||
if (!options.completeHTMLDocument) {
|
||||
return text;
|
||||
}
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLOutput.before', text, options, globals);
|
||||
text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);
|
||||
|
||||
text = '<html>\n<head>\n<meta charset="UTF-8">\n</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
|
||||
var doctype = 'html',
|
||||
doctypeParsed = '<!DOCTYPE HTML>\n',
|
||||
title = '',
|
||||
charset = '<meta charset="utf-8">\n',
|
||||
lang = '',
|
||||
metadata = '';
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLOutput.after', text, options, globals);
|
||||
if (typeof globals.metadata.parsed.doctype !== 'undefined') {
|
||||
doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n';
|
||||
doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
|
||||
if (doctype === 'html' || doctype === 'html5') {
|
||||
charset = '<meta charset="utf-8">';
|
||||
}
|
||||
}
|
||||
|
||||
for (var meta in globals.metadata.parsed) {
|
||||
if (globals.metadata.parsed.hasOwnProperty(meta)) {
|
||||
switch (meta.toLowerCase()) {
|
||||
case 'doctype':
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
title = '<title>' + globals.metadata.parsed.title + '</title>\n';
|
||||
break;
|
||||
|
||||
case 'charset':
|
||||
if (doctype === 'html' || doctype === 'html5') {
|
||||
charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n';
|
||||
} else {
|
||||
charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'language':
|
||||
case 'lang':
|
||||
lang = ' lang="' + globals.metadata.parsed[meta] + '"';
|
||||
metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
|
||||
break;
|
||||
|
||||
default:
|
||||
metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
|
||||
return text;
|
||||
});
|
||||
|
||||
@ -3886,6 +4000,56 @@ showdown.subParser('lists', function (text, options, globals) {
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse metadata at the top of the document
|
||||
*/
|
||||
showdown.subParser('metadata', function (text, options, globals) {
|
||||
'use strict';
|
||||
|
||||
if (!options.metadata) {
|
||||
return text;
|
||||
}
|
||||
|
||||
text = globals.converter._dispatch('metadata.before', text, options, globals);
|
||||
|
||||
function parseMetadataContents (content) {
|
||||
// raw is raw so it's not changed in any way
|
||||
globals.metadata.raw = content;
|
||||
|
||||
// escape chars forbidden in html attributes
|
||||
// double quotes
|
||||
content = content
|
||||
// ampersand first
|
||||
.replace(/&/g, '&')
|
||||
// double quotes
|
||||
.replace(/"/g, '"');
|
||||
|
||||
content = content.replace(/\n {4}/g, ' ');
|
||||
content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) {
|
||||
globals.metadata.parsed[key] = value;
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) {
|
||||
parseMetadataContents(content);
|
||||
return '¨M';
|
||||
});
|
||||
|
||||
text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) {
|
||||
if (format) {
|
||||
globals.metadata.format = format;
|
||||
}
|
||||
parseMetadataContents(content);
|
||||
return '¨M';
|
||||
});
|
||||
|
||||
text = text.replace(/¨M/g, '');
|
||||
|
||||
text = globals.converter._dispatch('metadata.after', text, options, globals);
|
||||
return text;
|
||||
});
|
||||
|
||||
/**
|
||||
* Remove one level of line-leading tabs or spaces
|
||||
*/
|
||||
|
2
dist/showdown.js.map
vendored
2
dist/showdown.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/showdown.min.js
vendored
2
dist/showdown.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/showdown.min.js.map
vendored
2
dist/showdown.min.js.map
vendored
File diff suppressed because one or more lines are too long
@ -43,7 +43,17 @@ showdown.Converter = function (converterOptions) {
|
||||
/**
|
||||
* The flavor set in this converter
|
||||
*/
|
||||
setConvFlavor = setFlavor;
|
||||
setConvFlavor = setFlavor,
|
||||
|
||||
/**
|
||||
* Metadata of the document
|
||||
* @type {{parsed: {}, raw: string, format: string}}
|
||||
*/
|
||||
metadata = {
|
||||
parsed: {},
|
||||
raw: '',
|
||||
format: ''
|
||||
};
|
||||
|
||||
_constructor();
|
||||
|
||||
@ -255,7 +265,12 @@ showdown.Converter = function (converterOptions) {
|
||||
langExtensions: langExtensions,
|
||||
outputModifiers: outputModifiers,
|
||||
converter: this,
|
||||
ghCodeBlocks: []
|
||||
ghCodeBlocks: [],
|
||||
metadata: {
|
||||
parsed: {},
|
||||
raw: '',
|
||||
format: ''
|
||||
}
|
||||
};
|
||||
|
||||
// This lets us use ¨ trema as an escape char to avoid md5 hashes
|
||||
@ -299,6 +314,7 @@ showdown.Converter = function (converterOptions) {
|
||||
});
|
||||
|
||||
// run the sub parsers
|
||||
text = showdown.subParser('metadata')(text, options, globals);
|
||||
text = showdown.subParser('hashPreCodeTags')(text, options, globals);
|
||||
text = showdown.subParser('githubCodeBlocks')(text, options, globals);
|
||||
text = showdown.subParser('hashHTMLBlocks')(text, options, globals);
|
||||
@ -315,13 +331,15 @@ showdown.Converter = function (converterOptions) {
|
||||
text = text.replace(/¨T/g, '¨');
|
||||
|
||||
// render a complete html document instead of a partial if the option is enabled
|
||||
text = showdown.subParser('completeHTMLOutput')(text, options, globals);
|
||||
text = showdown.subParser('completeHTMLDocument')(text, options, globals);
|
||||
|
||||
// Run output modifiers
|
||||
showdown.helper.forEach(outputModifiers, function (ext) {
|
||||
text = showdown.subParser('runExtension')(ext, text, options, globals);
|
||||
});
|
||||
|
||||
// update metadata
|
||||
metadata = globals.metadata;
|
||||
return text;
|
||||
};
|
||||
|
||||
@ -429,4 +447,50 @@ showdown.Converter = function (converterOptions) {
|
||||
output: outputModifiers
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the metadata of the previously parsed document
|
||||
* @param raw
|
||||
* @returns {string|{}}
|
||||
*/
|
||||
this.getMetadata = function (raw) {
|
||||
if (raw) {
|
||||
return metadata.raw;
|
||||
} else {
|
||||
return metadata.parsed;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the metadata format of the previously parsed document
|
||||
* @returns {string}
|
||||
*/
|
||||
this.getMetadataFormat = function () {
|
||||
return metadata.format;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private: set a single key, value metadata pair
|
||||
* @param {string} key
|
||||
* @param {string} value
|
||||
*/
|
||||
this._setMetadataPair = function (key, value) {
|
||||
metadata.parsed[key] = value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private: set metadata format
|
||||
* @param {string} format
|
||||
*/
|
||||
this._setMetadataFormat = function (format) {
|
||||
metadata.format = format;
|
||||
};
|
||||
|
||||
/**
|
||||
* Private: set metadata raw text
|
||||
* @param {string} raw
|
||||
*/
|
||||
this._setMetadataRaw = function (raw) {
|
||||
metadata.raw = raw;
|
||||
};
|
||||
};
|
||||
|
@ -151,10 +151,15 @@ function getDefaultOpts (simple) {
|
||||
description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
|
||||
type: 'boolean'
|
||||
},
|
||||
completeHTMLOutput: {
|
||||
completeHTMLDocument: {
|
||||
defaultValue: false,
|
||||
description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
|
||||
type: 'boolean'
|
||||
},
|
||||
metadata: {
|
||||
defaultValue: false,
|
||||
description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
|
||||
type: 'boolean'
|
||||
}
|
||||
};
|
||||
if (simple === false) {
|
||||
|
62
src/subParsers/completeHTMLDocument.js
Normal file
62
src/subParsers/completeHTMLDocument.js
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Turn Markdown link shortcuts into XHTML <a> tags.
|
||||
*/
|
||||
showdown.subParser('completeHTMLDocument', function (text, options, globals) {
|
||||
'use strict';
|
||||
|
||||
if (!options.completeHTMLDocument) {
|
||||
return text;
|
||||
}
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLDocument.before', text, options, globals);
|
||||
|
||||
var doctype = 'html',
|
||||
doctypeParsed = '<!DOCTYPE HTML>\n',
|
||||
title = '',
|
||||
charset = '<meta charset="utf-8">\n',
|
||||
lang = '',
|
||||
metadata = '';
|
||||
|
||||
if (typeof globals.metadata.parsed.doctype !== 'undefined') {
|
||||
doctypeParsed = '<!DOCTYPE ' + globals.metadata.parsed.doctype + '>\n';
|
||||
doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
|
||||
if (doctype === 'html' || doctype === 'html5') {
|
||||
charset = '<meta charset="utf-8">';
|
||||
}
|
||||
}
|
||||
|
||||
for (var meta in globals.metadata.parsed) {
|
||||
if (globals.metadata.parsed.hasOwnProperty(meta)) {
|
||||
switch (meta.toLowerCase()) {
|
||||
case 'doctype':
|
||||
break;
|
||||
|
||||
case 'title':
|
||||
title = '<title>' + globals.metadata.parsed.title + '</title>\n';
|
||||
break;
|
||||
|
||||
case 'charset':
|
||||
if (doctype === 'html' || doctype === 'html5') {
|
||||
charset = '<meta charset="' + globals.metadata.parsed.charset + '">\n';
|
||||
} else {
|
||||
charset = '<meta name="charset" content="' + globals.metadata.parsed.charset + '">\n';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'language':
|
||||
case 'lang':
|
||||
lang = ' lang="' + globals.metadata.parsed[meta] + '"';
|
||||
metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
|
||||
break;
|
||||
|
||||
default:
|
||||
metadata += '<meta name="' + meta + '" content="' + globals.metadata.parsed[meta] + '">\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text = doctypeParsed + '<html' + lang + '>\n<head>\n' + title + charset + metadata + '</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLDocument.after', text, options, globals);
|
||||
return text;
|
||||
});
|
@ -1,17 +0,0 @@
|
||||
/**
|
||||
* Turn Markdown link shortcuts into XHTML <a> tags.
|
||||
*/
|
||||
showdown.subParser('completeHTMLOutput', function (text, options, globals) {
|
||||
'use strict';
|
||||
|
||||
if (!options.completeHTMLOutput) {
|
||||
return text;
|
||||
}
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLOutput.before', text, options, globals);
|
||||
|
||||
text = '<html>\n<head>\n<meta charset="UTF-8">\n</head>\n<body>\n' + text.trim() + '\n</body>\n</html>';
|
||||
|
||||
text = globals.converter._dispatch('completeHTMLOutput.after', text, options, globals);
|
||||
return text;
|
||||
});
|
49
src/subParsers/metadata.js
Normal file
49
src/subParsers/metadata.js
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Parse metadata at the top of the document
|
||||
*/
|
||||
showdown.subParser('metadata', function (text, options, globals) {
|
||||
'use strict';
|
||||
|
||||
if (!options.metadata) {
|
||||
return text;
|
||||
}
|
||||
|
||||
text = globals.converter._dispatch('metadata.before', text, options, globals);
|
||||
|
||||
function parseMetadataContents (content) {
|
||||
// raw is raw so it's not changed in any way
|
||||
globals.metadata.raw = content;
|
||||
|
||||
// escape chars forbidden in html attributes
|
||||
// double quotes
|
||||
content = content
|
||||
// ampersand first
|
||||
.replace(/&/g, '&')
|
||||
// double quotes
|
||||
.replace(/"/g, '"');
|
||||
|
||||
content = content.replace(/\n {4}/g, ' ');
|
||||
content.replace(/^([\S ]+): +([\s\S]+?)$/gm, function (wm, key, value) {
|
||||
globals.metadata.parsed[key] = value;
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
text = text.replace(/^\s*«««+(\S*?)\n([\s\S]+?)\n»»»+\n/, function (wholematch, format, content) {
|
||||
parseMetadataContents(content);
|
||||
return '¨M';
|
||||
});
|
||||
|
||||
text = text.replace(/^\s*---+(\S*?)\n([\s\S]+?)\n---+\n/, function (wholematch, format, content) {
|
||||
if (format) {
|
||||
globals.metadata.format = format;
|
||||
}
|
||||
parseMetadataContents(content);
|
||||
return '¨M';
|
||||
});
|
||||
|
||||
text = text.replace(/¨M/g, '');
|
||||
|
||||
text = globals.converter._dispatch('metadata.after', text, options, globals);
|
||||
return text;
|
||||
});
|
@ -1,14 +1,15 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<p>This is a <strong>markdown</strong> file</p>
|
||||
<p>Converted into a full HTML document</p>
|
||||
<ul>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>awesome</li>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>awesome</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
8
test/features/metadata/dashes-conflict.html
Normal file
8
test/features/metadata/dashes-conflict.html
Normal file
@ -0,0 +1,8 @@
|
||||
<p><strong>some</strong> markdown text</p>
|
||||
<ul>
|
||||
<li>a list</li>
|
||||
<li>another list ---</li>
|
||||
<li>and stuff</li>
|
||||
</ul>
|
||||
<p>a paragraph --- with dashes</p>
|
||||
<hr />
|
16
test/features/metadata/dashes-conflict.md
Normal file
16
test/features/metadata/dashes-conflict.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
|
||||
---
|
||||
**some** markdown text
|
||||
|
||||
- a list
|
||||
- another list ---
|
||||
- and stuff
|
||||
|
||||
a paragraph --- with dashes
|
||||
|
||||
---
|
16
test/features/metadata/embeded-in-output.html
Normal file
16
test/features/metadata/embeded-in-output.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>This is the document title</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="language" content="en">
|
||||
<meta name="author" content="Tivie">
|
||||
<meta name="contributors" content="John, Mary, Steve">
|
||||
<meta name="description" content="This is a long text and so it spans on multiple lines. It must be indented, for showdown to parse it correctly. Markdown **such as bold** is not parsed and it will be rendered as plain text.">
|
||||
<meta name="date" content="01-01-2010">
|
||||
<meta name="keywords" content="foo, bar, baz">
|
||||
</head>
|
||||
<body>
|
||||
<p><strong>some</strong> markdown text</p>
|
||||
</body>
|
||||
</html>
|
16
test/features/metadata/embeded-in-output.md
Normal file
16
test/features/metadata/embeded-in-output.md
Normal file
@ -0,0 +1,16 @@
|
||||
«««
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown **such as bold** is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
keywords: foo, bar, baz
|
||||
»»»
|
||||
|
||||
**some** markdown text
|
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>This is the document title</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="language" content="en">
|
||||
<meta name="author" content="Tivie">
|
||||
<meta name="contributors" content="John, Mary, Steve">
|
||||
<meta name="keywords" content="foo, bar, baz">
|
||||
</head>
|
||||
<body>
|
||||
<hr />
|
||||
<p>description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown <strong>such as bold</strong> is not parsed
|
||||
and it will be rendered as plain text.</p>
|
||||
<h2 id="date01012010">date: 01-01-2010</h2>
|
||||
<p><strong>some</strong> markdown text</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,18 @@
|
||||
«««
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
keywords: foo, bar, baz
|
||||
»»»
|
||||
---
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown **such as bold** is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
---
|
||||
|
||||
**some** markdown text
|
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>This is the document title</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="language" content="en">
|
||||
<meta name="author" content="Tivie">
|
||||
<meta name="contributors" content="John, Mary, Steve">
|
||||
<meta name="keywords" content="foo, bar, baz">
|
||||
</head>
|
||||
<body>
|
||||
<hr />
|
||||
<p>description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown <strong>such as bold</strong> is not parsed
|
||||
and it will be rendered as plain text.</p>
|
||||
<h2 id="date01012010">date: 01-01-2010</h2>
|
||||
<p><strong>some</strong> markdown text</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,18 @@
|
||||
---
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
keywords: foo, bar, baz
|
||||
---
|
||||
---
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown **such as bold** is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
---
|
||||
|
||||
**some** markdown text
|
15
test/features/metadata/ignore-metadata.html
Normal file
15
test/features/metadata/ignore-metadata.html
Normal file
@ -0,0 +1,15 @@
|
||||
<hr />
|
||||
<p>title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown <strong>such as bold</strong> is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
keywords: foo, bar, baz</p>
|
||||
<hr />
|
||||
<p><strong>some</strong> markdown text</p>
|
18
test/features/metadata/ignore-metadata.md
Normal file
18
test/features/metadata/ignore-metadata.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown **such as bold** is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
keywords: foo, bar, baz
|
||||
|
||||
---
|
||||
|
||||
**some** markdown text
|
1
test/features/metadata/simple-angled-for-method.html
Normal file
1
test/features/metadata/simple-angled-for-method.html
Normal file
@ -0,0 +1 @@
|
||||
<p>some <strong>text</strong></p>
|
6
test/features/metadata/simple-angled-for-method.md
Normal file
6
test/features/metadata/simple-angled-for-method.md
Normal file
@ -0,0 +1,6 @@
|
||||
«««
|
||||
foo: bar
|
||||
baz: bazinga
|
||||
»»»
|
||||
|
||||
some **text**
|
1
test/features/metadata/simple-angled-quotes.html
Normal file
1
test/features/metadata/simple-angled-quotes.html
Normal file
@ -0,0 +1 @@
|
||||
<p><strong>some</strong> markdown text</p>
|
16
test/features/metadata/simple-angled-quotes.md
Normal file
16
test/features/metadata/simple-angled-quotes.md
Normal file
@ -0,0 +1,16 @@
|
||||
«««
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown **such as bold** is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
keywords: foo, bar, baz
|
||||
»»»
|
||||
|
||||
**some** markdown text
|
1
test/features/metadata/simple-three-dashes.html
Normal file
1
test/features/metadata/simple-three-dashes.html
Normal file
@ -0,0 +1 @@
|
||||
<p><strong>some</strong> markdown text</p>
|
16
test/features/metadata/simple-three-dashes.md
Normal file
16
test/features/metadata/simple-three-dashes.md
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
title: This is the document title
|
||||
language: en
|
||||
author: Tivie
|
||||
contributors: John, Mary, Steve
|
||||
description: This is a long text and so it
|
||||
spans on multiple lines.
|
||||
It must be indented,
|
||||
for showdown to parse it correctly.
|
||||
Markdown **such as bold** is not parsed
|
||||
and it will be rendered as plain text.
|
||||
date: 01-01-2010
|
||||
keywords: foo, bar, baz
|
||||
---
|
||||
|
||||
**some** markdown text
|
1
test/features/metadata/simple-with-format.html
Normal file
1
test/features/metadata/simple-with-format.html
Normal file
@ -0,0 +1 @@
|
||||
<p><strong>some</strong> markdown text</p>
|
9
test/features/metadata/simple-with-format.md
Normal file
9
test/features/metadata/simple-with-format.md
Normal file
@ -0,0 +1,9 @@
|
||||
---YAML
|
||||
foo: bar
|
||||
baz:
|
||||
- bazinga
|
||||
- bling
|
||||
- blang
|
||||
---
|
||||
|
||||
**some** markdown text
|
@ -27,6 +27,20 @@ describe('showdown.Converter', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('metadata methods', function () {
|
||||
var converter = new showdown.Converter();
|
||||
|
||||
it('_setMetadataPair() should set foo to bar', function () {
|
||||
converter._setMetadataPair('foo', 'bar');
|
||||
converter.getMetadata().should.eql({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('_setMetadata should set metadata to {baz: bazinga}', function () {
|
||||
converter._setMetadataRaw('{baz: bazinga}');
|
||||
converter.getMetadata(true).should.eql('{baz: bazinga}');
|
||||
});
|
||||
});
|
||||
|
||||
describe('converter.setFlavor()', function () {
|
||||
|
||||
/**
|
||||
|
@ -59,4 +59,41 @@ describe('showdown.Converter', function () {
|
||||
html.should.equal(expectedHtml);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeHtml() with option metadata', function () {
|
||||
var converter = new showdown.Converter(),
|
||||
text1 =
|
||||
'---SIMPLE\n' +
|
||||
'foo: bar\n' +
|
||||
'baz: bazinga\n' +
|
||||
'---\n',
|
||||
text2 =
|
||||
'---TIVIE\n' +
|
||||
'a: b\n' +
|
||||
'c: 123\n' +
|
||||
'---\n';
|
||||
|
||||
it('should correctly set metadata', function () {
|
||||
converter.setOption('metadata', true);
|
||||
|
||||
var expectedHtml = '',
|
||||
expectedObj = {foo: 'bar', baz: 'bazinga'},
|
||||
expectedRaw = 'foo: bar\nbaz: bazinga',
|
||||
expectedFormat = 'SIMPLE';
|
||||
converter.makeHtml(text1).should.equal(expectedHtml);
|
||||
converter.getMetadata().should.eql(expectedObj);
|
||||
converter.getMetadata(true).should.equal(expectedRaw);
|
||||
converter.getMetadataFormat().should.equal(expectedFormat);
|
||||
});
|
||||
|
||||
it('consecutive calls should reset metadata', function () {
|
||||
converter.makeHtml(text2);
|
||||
var expectedObj = {a: 'b', c: '123'},
|
||||
expectedRaw = 'a: b\nc: 123',
|
||||
expectedFormat = 'TIVIE';
|
||||
converter.getMetadata().should.eql(expectedObj);
|
||||
converter.getMetadata(true).should.equal(expectedRaw);
|
||||
converter.getMetadataFormat().should.equal(expectedFormat);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -15,7 +15,8 @@ var bootstrap = require('../bootstrap.js'),
|
||||
underlineSuite = bootstrap.getTestSuite('test/features/underline/'),
|
||||
literalMidWordUnderscoresSuite = bootstrap.getTestSuite('test/features/literalMidWordUnderscores/'),
|
||||
literalMidWordAsterisksSuite = bootstrap.getTestSuite('test/features/literalMidWordAsterisks/'),
|
||||
completeHTMLOutputSuite = bootstrap.getTestSuite('test/features/completeHTMLOutput/');
|
||||
completeHTMLOutputSuite = bootstrap.getTestSuite('test/features/completeHTMLOutput/'),
|
||||
metadataSuite = bootstrap.getTestSuite('test/features/metadata/');
|
||||
|
||||
describe('makeHtml() features testsuite', function () {
|
||||
'use strict';
|
||||
@ -233,12 +234,33 @@ describe('makeHtml() features testsuite', function () {
|
||||
}
|
||||
});
|
||||
|
||||
/** test completeHTMLOutput option **/
|
||||
describe('completeHTMLOutput option', function () {
|
||||
|
||||
/** test completeHTMLDocument option **/
|
||||
describe('completeHTMLDocument option', function () {
|
||||
var converter,
|
||||
suite = completeHTMLOutputSuite;
|
||||
for (var i = 0; i < suite.length; ++i) {
|
||||
converter = new showdown.Converter({completeHTMLOutput: true});
|
||||
converter = new showdown.Converter({completeHTMLDocument: true});
|
||||
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
});
|
||||
|
||||
/** test metadata option **/
|
||||
describe('metadata option', function () {
|
||||
var converter,
|
||||
suite = metadataSuite;
|
||||
|
||||
for (var 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') {
|
||||
converter = new showdown.Converter({metadata: true, completeHTMLDocument: true});
|
||||
} else if (suite[i].name === 'ignore-metadata') {
|
||||
converter = new showdown.Converter({metadata: false});
|
||||
} else {
|
||||
converter = new showdown.Converter({metadata: true});
|
||||
}
|
||||
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
|
||||
}
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user