mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
Merge branch 'master' into feature-table-extension
Conflicts: README.md src/showdown.js
This commit is contained in:
commit
dc28410a3b
94
README.md
94
README.md
|
@ -1,10 +1,6 @@
|
||||||
|
# NOTE -- Showdown on GitHub
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/pdeschen/showdown.png)](https://travis-ci.org/pdeschen/showdown])
|
**Please note** that I, Corey, am not the author of Showdown. Rather, I found it
|
||||||
|
|
||||||
NOTE -- Showdown on GitHub
|
|
||||||
==========================
|
|
||||||
|
|
||||||
Please note that I, Corey, am not the author of Showdown. Rather, I found it
|
|
||||||
some time back at <http://attacklab.net/showdown/>
|
some time back at <http://attacklab.net/showdown/>
|
||||||
(website removed, see: <http://wayback.archive.org/web/*/http://attacklab.net/showdown>)
|
(website removed, see: <http://wayback.archive.org/web/*/http://attacklab.net/showdown>)
|
||||||
and wanted to see it available on GitHub.
|
and wanted to see it available on GitHub.
|
||||||
|
@ -23,8 +19,7 @@ Cheers,<br/>
|
||||||
Corey
|
Corey
|
||||||
|
|
||||||
|
|
||||||
Showdown -- A JavaScript port of Markdown
|
# Showdown -- A JavaScript port of Markdown
|
||||||
=========================================
|
|
||||||
|
|
||||||
Showdown Copyright (c) 2007 John Fraser.
|
Showdown Copyright (c) 2007 John Fraser.
|
||||||
<http://www.attacklab.net/>
|
<http://www.attacklab.net/>
|
||||||
|
@ -36,21 +31,18 @@ Redistributable under a BSD-style open source license.
|
||||||
See license.txt for more information.
|
See license.txt for more information.
|
||||||
|
|
||||||
|
|
||||||
Quick Example
|
## Quick Example
|
||||||
-------------
|
|
||||||
|
|
||||||
``` js
|
```js
|
||||||
var Showdown = require('showdown');
|
var Showdown = require('showdown');
|
||||||
var converter = new Showdown.converter();
|
var converter = new Showdown.converter();
|
||||||
|
|
||||||
converter.makeHtml('#hello markdown!');
|
converter.makeHtml('#hello markdown!');
|
||||||
|
|
||||||
// <h1 id="hellomarkdown">hello, markdown</h1>
|
// <h1 id="hellomarkdown">hello, markdown</h1>
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
What's it for?
|
## What's it for?
|
||||||
--------------
|
|
||||||
|
|
||||||
Developers can use Showdown to:
|
Developers can use Showdown to:
|
||||||
|
|
||||||
|
@ -92,23 +84,21 @@ Developers can use Showdown to:
|
||||||
Markdown.)
|
Markdown.)
|
||||||
|
|
||||||
|
|
||||||
Browser Compatibility
|
## Browser Compatibility
|
||||||
---------------------
|
|
||||||
|
|
||||||
Showdown has been tested successfully with:
|
Showdown has been tested successfully with:
|
||||||
|
|
||||||
- Firefox 1.5 and 2.0
|
* Firefox 1.5 and 2.0
|
||||||
- Internet Explorer 6 and 7
|
* Internet Explorer 6 and 7
|
||||||
- Safari 2.0.4
|
* Safari 2.0.4
|
||||||
- Opera 8.54 and 9.10
|
* Opera 8.54 and 9.10
|
||||||
- Netscape 8.1.2
|
* Netscape 8.1.2
|
||||||
- Konqueror 3.5.4
|
* Konqueror 3.5.4
|
||||||
|
|
||||||
In theory, Showdown will work in any browser that supports ECMA 262 3rd Edition (JavaScript 1.5). The converter itself might even work in things that aren't web browsers, like Acrobat. No promises.
|
In theory, Showdown will work in any browser that supports ECMA 262 3rd Edition (JavaScript 1.5). The converter itself might even work in things that aren't web browsers, like Acrobat. No promises.
|
||||||
|
|
||||||
|
|
||||||
Extensions
|
## Extensions
|
||||||
----------
|
|
||||||
|
|
||||||
Showdown allows additional functionality to be loaded via extensions.
|
Showdown allows additional functionality to be loaded via extensions.
|
||||||
|
|
||||||
|
@ -118,7 +108,7 @@ Showdown allows additional functionality to be loaded via extensions.
|
||||||
<script src="src/showdown.js" />
|
<script src="src/showdown.js" />
|
||||||
<script src="src/extensions/twitter.js" />
|
<script src="src/extensions/twitter.js" />
|
||||||
|
|
||||||
var converter = new Showdown().converter({ extensions: ['twitter'] });
|
var converter = new Showdown.converter({ extensions: 'twitter' });
|
||||||
```
|
```
|
||||||
|
|
||||||
### Server-side Extension Usage
|
### Server-side Extension Usage
|
||||||
|
@ -126,20 +116,17 @@ var converter = new Showdown().converter({ extensions: ['twitter'] });
|
||||||
```js
|
```js
|
||||||
// Using a bundled extension
|
// Using a bundled extension
|
||||||
var Showdown = require('showdown');
|
var Showdown = require('showdown');
|
||||||
var converter = new Showdown().converter({ extensions: ['twitter'] });
|
var converter = new Showdown.converter({ extensions: ['twitter'] });
|
||||||
|
|
||||||
// Using a custom extension
|
// Using a custom extension
|
||||||
var mine = require('./custom-extensions/mine');
|
var mine = require('./custom-extensions/mine');
|
||||||
var converter = new Showdown().converter({ extensions: ['twitter', mine] });
|
var converter = new Showdown.converter({ extensions: ['twitter', mine] });
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Known Differences in Output
|
||||||
|
|
||||||
Known Differences in Output
|
In most cases, Showdown's output is identical to that of Perl Markdown v1.0.2b7. What follows is a list of all known deviations. Please file an issue if you find more.
|
||||||
---------------------------
|
|
||||||
|
|
||||||
In most cases, Showdown's output is identical to that of Perl Markdown v1.0.2b7. What follows is a list of all known deviations. Please email me if you find more.
|
|
||||||
|
|
||||||
|
|
||||||
* This release uses the HTML parser from Markdown 1.0.2b2,
|
* This release uses the HTML parser from Markdown 1.0.2b2,
|
||||||
which means it fails `Inline HTML (Advanced).text` from
|
which means it fails `Inline HTML (Advanced).text` from
|
||||||
|
@ -151,7 +138,6 @@ In most cases, Showdown's output is identical to that of Perl Markdown v1.0.2b7.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
* Showdown doesn't support the markdown="1" attribute:
|
* Showdown doesn't support the markdown="1" attribute:
|
||||||
|
|
||||||
<div markdown="1">
|
<div markdown="1">
|
||||||
|
@ -221,8 +207,7 @@ In most cases, Showdown's output is identical to that of Perl Markdown v1.0.2b7.
|
||||||
Showdown won't. But still, don't do that.
|
Showdown won't. But still, don't do that.
|
||||||
|
|
||||||
|
|
||||||
Tests
|
## Tests
|
||||||
---------------------------
|
|
||||||
A suite of tests is available which require node.js. Once node is installed, run the following command from the project root to install the development dependencies:
|
A suite of tests is available which require node.js. Once node is installed, run the following command from the project root to install the development dependencies:
|
||||||
|
|
||||||
npm install --dev
|
npm install --dev
|
||||||
|
@ -234,21 +219,20 @@ Once installed the tests can be run from the project root using:
|
||||||
New test cases can easily be added. Create a markdown file (ending in `.md`) which contains the markdown to test. Create a `.html` file of the exact same name. It will automatically be tested when the tests are executed with `mocha`.
|
New test cases can easily be added. Create a markdown file (ending in `.md`) which contains the markdown to test. Create a `.html` file of the exact same name. It will automatically be tested when the tests are executed with `mocha`.
|
||||||
|
|
||||||
|
|
||||||
Creating Markdown Extensions
|
## Creating Markdown Extensions
|
||||||
----------------------------
|
|
||||||
|
|
||||||
A showdown extension is simply a function which returns an array of extensions. Each single extension can be one of two types:
|
A showdown extension is simply a function which returns an array of extensions. Each single extension can be one of two types:
|
||||||
|
|
||||||
- Language Extension -- Language extensions are ones that that add new markdown syntax to showdown. For example, say you wanted `^^youtube http://www.youtube.com/watch?v=oHg5SJYRHA0` to automatically render as an embedded YouTube video, that would be a language extension.
|
* Language Extension -- Language extensions are ones that that add new markdown syntax to showdown. For example, say you wanted `^^youtube http://www.youtube.com/watch?v=oHg5SJYRHA0` to automatically render as an embedded YouTube video, that would be a language extension.
|
||||||
- Output Modifiers -- After showdown has run, and generated HTML, an output modifier would change that HTML. For example, say you wanted to change `<div class="header">` to be `<header>`, that would be an output modifier.
|
* Output Modifiers -- After showdown has run, and generated HTML, an output modifier would change that HTML. For example, say you wanted to change `<div class="header">` to be `<header>`, that would be an output modifier.
|
||||||
|
|
||||||
Each extension can provide two combinations of interfaces for showdown.
|
Each extension can provide two combinations of interfaces for showdown.
|
||||||
|
|
||||||
#### Regex/Replace
|
### Regex/Replace
|
||||||
|
|
||||||
Regex/replace style extensions are very similar to javascripts `string.replace` function. Two properties are given, `regex` and `replace`. `regex` is a string and `replace` can be either a string or a function. If `replace` is a string, it can use the `$1` syntax for group substituation, exactly as if it were making use of `string.replace` (internally it does this actually); The value of `regex` is assumed to be a global replacement.
|
Regex/replace style extensions are very similar to javascripts `string.replace` function. Two properties are given, `regex` and `replace`. `regex` is a string and `replace` can be either a string or a function. If `replace` is a string, it can use the `$1` syntax for group substitution, exactly as if it were making use of `string.replace` (internally it does this actually); The value of `regex` is assumed to be a global replacement.
|
||||||
|
|
||||||
#### Regex/Replace Example
|
**Example:**
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
var demo = function(converter) {
|
var demo = function(converter) {
|
||||||
|
@ -259,11 +243,11 @@ var demo = function(converter) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Filter
|
### Filter
|
||||||
|
|
||||||
Alternately, if you'd just like to do everything yourself, you can specify a filter which is a callback with a single input parameter, text (the current source text within the showdown engine).
|
Alternately, if you'd just like to do everything yourself, you can specify a filter which is a callback with a single input parameter, text (the current source text within the showdown engine).
|
||||||
|
|
||||||
#### Filter Example
|
**Example:**
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
var demo = function(converter) {
|
var demo = function(converter) {
|
||||||
|
@ -276,9 +260,9 @@ var demo = function(converter) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Implementation Concerns
|
### Implementation Concerns
|
||||||
|
|
||||||
One bit which should be taken into account is maintaining both client-side and server-side compatibility. This can be achieved with a few lines of boilerplate code. First, to prevent polluting the global scope for client-side code, the extension definition should be wrapped in a self executing function.
|
One bit which should be taken into account is maintaining both client-side and server-side compatibility. This can be achieved with a few lines of boilerplate code. First, to prevent polluting the global scope for client-side code, the extension definition should be wrapped in a self-executing function.
|
||||||
|
|
||||||
``` js
|
``` js
|
||||||
(function(){
|
(function(){
|
||||||
|
@ -301,7 +285,7 @@ Second, client-side extensions should add a property onto `Showdown.extensions`
|
||||||
}());
|
}());
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Testing Extensions
|
### Testing Extensions
|
||||||
|
|
||||||
The showdown test runner is setup to automatically test cases for extensions. To add test cases for an extension, create a new folder under `./test/extensions` which matches the name of the `.js` file in `./src/extensions`. Place any test cases into the filder using the md/html format and they will automatically be run when tests are run.
|
The showdown test runner is setup to automatically test cases for extensions. To add test cases for an extension, create a new folder under `./test/extensions` which matches the name of the `.js` file in `./src/extensions`. Place any test cases into the filder using the md/html format and they will automatically be run when tests are run.
|
||||||
|
|
||||||
|
@ -314,11 +298,13 @@ Credits
|
||||||
Author of Showdown
|
Author of Showdown
|
||||||
* [John Gruber](http://daringfireball.net/projects/markdown/):<br/>
|
* [John Gruber](http://daringfireball.net/projects/markdown/):<br/>
|
||||||
Author of Markdown
|
Author of Markdown
|
||||||
* Maintenance
|
* Maintenance/Contributions
|
||||||
* [Corey Innis](http://github.com/coreyti):<br/>
|
* [Corey Innis](http://github.com/coreyti):<br/>
|
||||||
GitHub project maintainer
|
GitHub project maintainer
|
||||||
* [Remy Sharp](http://remysharp.com/):<br/>
|
* [Remy Sharp](https://github.com/remy/):<br/>
|
||||||
CommonJS-compatibility and more
|
CommonJS-compatibility and more
|
||||||
|
* [Konstantin Käfer](https://github.com/kkaefer/):<br/>
|
||||||
|
CommonJS packaging
|
||||||
* [Roger Braun](https://github.com/rogerbraun):<br/>
|
* [Roger Braun](https://github.com/rogerbraun):<br/>
|
||||||
Github-style code blocks
|
Github-style code blocks
|
||||||
* [Dominic Tarr](https://github.com/dominictarr):<br/>
|
* [Dominic Tarr](https://github.com/dominictarr):<br/>
|
||||||
|
@ -326,5 +312,13 @@ Credits
|
||||||
* [Cat Chen](https://github.com/CatChen):<br/>
|
* [Cat Chen](https://github.com/CatChen):<br/>
|
||||||
Export fix
|
Export fix
|
||||||
* [Titus Stone](https://github.com/tstone):<br/>
|
* [Titus Stone](https://github.com/tstone):<br/>
|
||||||
Mocha tests + bug fixes
|
**Mocha tests**, **extension mechanism**, and bug fixes
|
||||||
|
* [Rob Sutherland](https://github.com/roberocity):<br/>
|
||||||
|
The idea that lead to extensions
|
||||||
|
* [Pavel Lang](https://github.com/langpavel):<br/>
|
||||||
|
Code cleanup
|
||||||
|
* [Ben Combee](https://github.com/unwiredben):<br/>
|
||||||
|
Regex optimization
|
||||||
|
* [Adam Backstrom](https://github.com/abackstrom):<br/>
|
||||||
|
WebKit bugfix
|
||||||
|
|
||||||
|
|
5
compressed/extensions/github.js
Normal file
5
compressed/extensions/github.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
//
|
||||||
|
// Github Extension (WIP)
|
||||||
|
// ~~strike-through~~ -> <del>strike-through</del>
|
||||||
|
//
|
||||||
|
(function(){var a=function(a){return[{type:"lang",regex:"(~T){2}([^~]+)(~T){2}",replace:function(a,b,c,d){return"<del>"+c+"</del>"}}]};typeof window!="undefined"&&window.Showdown&&window.Showdown.extensions&&(window.Showdown.extensions.github=a),typeof module!="undefined"&&(module.exports=a)})();
|
6
compressed/extensions/google-prettify.js
Normal file
6
compressed/extensions/google-prettify.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//
|
||||||
|
// Google Prettify
|
||||||
|
// A showdown extension to add Google Prettify (http://code.google.com/p/google-code-prettify/)
|
||||||
|
// hints to showdown's HTML output.
|
||||||
|
//
|
||||||
|
(function(){var a=function(a){return[{type:"output",filter:function(a){return a.replace(/(<pre>)?<code>/gi,function(a,b){return b?'<pre class="prettyprint linenums" tabIndex="0"><code data-inner="1">':'<code class="prettyprint">'})}}]};typeof window!="undefined"&&window.Showdown&&window.Showdown.extensions&&(window.Showdown.extensions.googlePrettify=a),typeof module!="undefined"&&(module.exports=a)})();
|
6
compressed/extensions/twitter.js
Normal file
6
compressed/extensions/twitter.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//
|
||||||
|
// Twitter Extension
|
||||||
|
// @username -> <a href="http://twitter.com/username">@username</a>
|
||||||
|
// #hashtag -> <a href="http://twitter.com/search/%23hashtag">#hashtag</a>
|
||||||
|
//
|
||||||
|
(function(){var a=function(a){return[{type:"lang",regex:"\\B(\\\\)?@([\\S]+)\\b",replace:function(a,b,c){return b==="\\"?a:'<a href="http://twitter.com/'+c+'">@'+c+"</a>"}},{type:"lang",regex:"\\B(\\\\)?#([\\S]+)\\b",replace:function(a,b,c){return b==="\\"?a:'<a href="http://twitter.com/search/%23'+c+'">#'+c+"</a>"}},{type:"lang",regex:"\\\\@",replace:"@"}]};typeof window!="undefined"&&window.Showdown&&window.Showdown.extensions&&(window.Showdown.extensions.twitter=a),typeof module!="undefined"&&(module.exports=a)})();
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "showdown",
|
"name": "showdown",
|
||||||
"version": "0.2.0",
|
"version": "0.3.0",
|
||||||
"author": "John Fraser",
|
"author": "John Fraser",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha ./test/run.js"
|
"test": "mocha ./test/run.js"
|
||||||
|
@ -14,7 +14,11 @@
|
||||||
"Roger Braun",
|
"Roger Braun",
|
||||||
"Dominic Tarr",
|
"Dominic Tarr",
|
||||||
"Cat Chen",
|
"Cat Chen",
|
||||||
"Titus Stone"
|
"Titus Stone",
|
||||||
|
"Rob Sutherland",
|
||||||
|
"Pavel Lang",
|
||||||
|
"Ben Combee",
|
||||||
|
"Adam Backstrom"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
25
src/extensions/github.js
Normal file
25
src/extensions/github.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//
|
||||||
|
// Github Extension (WIP)
|
||||||
|
// ~~strike-through~~ -> <del>strike-through</del>
|
||||||
|
//
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
var github = function(converter) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
// strike-through
|
||||||
|
// NOTE: showdown already replaced "~" with "~T", so we need to adjust accordingly.
|
||||||
|
type : 'lang',
|
||||||
|
regex : '(~T){2}([^~]+)(~T){2}',
|
||||||
|
replace : function(match, prefix, content, suffix) {
|
||||||
|
return '<del>' + content + '</del>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Client-side export
|
||||||
|
if (typeof window !== 'undefined' && window.Showdown && window.Showdown.extensions) { window.Showdown.extensions.github = github; }
|
||||||
|
// Server-side export
|
||||||
|
if (typeof module !== 'undefined') module.exports = github;
|
||||||
|
}());
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
//
|
//
|
||||||
// Google Prettify
|
// Google Prettify
|
||||||
// A showdown extension to add Google Prettify (http://code.google.com/p/google-code-prettify/)
|
// A showdown extension to add Google Prettify (http://code.google.com/p/google-code-prettify/)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
//
|
//
|
||||||
// Twitter Extension
|
// Twitter Extension
|
||||||
// @username -> <a href="http://twitter.com/username">@username</a>
|
// @username -> <a href="http://twitter.com/username">@username</a>
|
||||||
|
|
|
@ -128,7 +128,7 @@ if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof req
|
||||||
return file.replace(/\.js$/, '');
|
return file.replace(/\.js$/, '');
|
||||||
});
|
});
|
||||||
// Load extensions into Showdown namespace
|
// Load extensions into Showdown namespace
|
||||||
extensions.forEach(function(ext){
|
Showdown.forEach(extensions, function(ext){
|
||||||
var name = stdExtName(ext);
|
var name = stdExtName(ext);
|
||||||
Showdown.extensions[name] = require('./extensions/' + ext);
|
Showdown.extensions[name] = require('./extensions/' + ext);
|
||||||
});
|
});
|
||||||
|
@ -139,11 +139,11 @@ if (typeof module !== 'undefind' && typeof exports !== 'undefined' && typeof req
|
||||||
// Options:
|
// Options:
|
||||||
//
|
//
|
||||||
|
|
||||||
// Parse extensinos options into separate arrays
|
// Parse extensions options into separate arrays
|
||||||
if (converter_options && converter_options.extensions) {
|
if (converter_options && converter_options.extensions) {
|
||||||
|
|
||||||
// Iterate over each plugin
|
// Iterate over each plugin
|
||||||
forEach(converter_options.extensions, function(plugin){
|
Showdown.forEach(converter_options.extensions, function(plugin){
|
||||||
|
|
||||||
// Assume it's a bundled plugin if a string is given
|
// Assume it's a bundled plugin if a string is given
|
||||||
if (typeof plugin === 'string') {
|
if (typeof plugin === 'string') {
|
||||||
|
@ -152,7 +152,7 @@ if (converter_options && converter_options.extensions) {
|
||||||
|
|
||||||
if (typeof plugin === 'function') {
|
if (typeof plugin === 'function') {
|
||||||
// Iterate over each extension within that plugin
|
// Iterate over each extension within that plugin
|
||||||
plugin(this).forEach(function(ext){
|
Showdown.forEach(plugin(this), function(ext){
|
||||||
// Sort extensions by type
|
// Sort extensions by type
|
||||||
if (ext.type) {
|
if (ext.type) {
|
||||||
if (ext.type === 'language' || ext.type === 'lang') {
|
if (ext.type === 'language' || ext.type === 'lang') {
|
||||||
|
@ -215,7 +215,7 @@ this.makeHtml = function(text) {
|
||||||
text = text.replace(/^[ \t]+$/mg,"");
|
text = text.replace(/^[ \t]+$/mg,"");
|
||||||
|
|
||||||
// Run language extensions
|
// Run language extensions
|
||||||
g_lang_extensions.forEach(function(x){
|
Showdown.forEach(g_lang_extensions, function(x){
|
||||||
text = _ExecuteExtension(x, text);
|
text = _ExecuteExtension(x, text);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ this.makeHtml = function(text) {
|
||||||
text = text.replace(/~T/g,"~");
|
text = text.replace(/~T/g,"~");
|
||||||
|
|
||||||
// Run output modifiers
|
// Run output modifiers
|
||||||
g_output_modifiers.forEach(function(x){
|
Showdown.forEach(g_output_modifiers, function(x){
|
||||||
text = _ExecuteExtension(x, text);
|
text = _ExecuteExtension(x, text);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -286,7 +286,11 @@ var _StripLinkDefinitions = function(text) {
|
||||||
/gm,
|
/gm,
|
||||||
function(){...});
|
function(){...});
|
||||||
*/
|
*/
|
||||||
var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,
|
|
||||||
|
// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
|
||||||
|
text += "~0";
|
||||||
|
|
||||||
|
text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|(?=~0))/gm,
|
||||||
function (wholeMatch,m1,m2,m3,m4) {
|
function (wholeMatch,m1,m2,m3,m4) {
|
||||||
m1 = m1.toLowerCase();
|
m1 = m1.toLowerCase();
|
||||||
g_urls[m1] = _EncodeAmpsAndAngles(m2); // Link IDs are case-insensitive
|
g_urls[m1] = _EncodeAmpsAndAngles(m2); // Link IDs are case-insensitive
|
||||||
|
@ -303,6 +307,9 @@ var _StripLinkDefinitions = function(text) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// attacklab: strip sentinel
|
||||||
|
text = text.replace(/~0/,"");
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,13 +368,13 @@ var _HashHTMLBlocks = function(text) {
|
||||||
\b // word break
|
\b // word break
|
||||||
// attacklab: hack around khtml/pcre bug...
|
// attacklab: hack around khtml/pcre bug...
|
||||||
[^\r]*? // any number of lines, minimally matching
|
[^\r]*? // any number of lines, minimally matching
|
||||||
.*</\2> // the matching end tag
|
</\2> // the matching end tag
|
||||||
[ \t]* // trailing spaces/tabs
|
[ \t]* // trailing spaces/tabs
|
||||||
(?=\n+) // followed by a newline
|
(?=\n+) // followed by a newline
|
||||||
) // attacklab: there are sentinel newlines at end of document
|
) // attacklab: there are sentinel newlines at end of document
|
||||||
/gm,function(){...}};
|
/gm,function(){...}};
|
||||||
*/
|
*/
|
||||||
text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
|
text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
|
||||||
|
|
||||||
// Special case just for <hr />. It was easier to make a special case than
|
// Special case just for <hr />. It was easier to make a special case than
|
||||||
// to make the other regex more complicated.
|
// to make the other regex more complicated.
|
||||||
|
|
4
test/cases/github-style-linebreaks.html
Normal file
4
test/cases/github-style-linebreaks.html
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
<pre><code>code can go here
|
||||||
|
this is rendered on a second line
|
||||||
|
</code></pre>
|
4
test/cases/github-style-linebreaks.md
Normal file
4
test/cases/github-style-linebreaks.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
```
|
||||||
|
code can go here
|
||||||
|
this is rendered on a second line
|
||||||
|
```
|
|
@ -13,4 +13,11 @@
|
||||||
|
|
||||||
<aside>ignore me</aside>
|
<aside>ignore me</aside>
|
||||||
|
|
||||||
|
<article>read
|
||||||
|
me</article>
|
||||||
|
|
||||||
|
<aside>
|
||||||
|
ignore me
|
||||||
|
</aside>
|
||||||
|
|
||||||
<p>the end</p>
|
<p>the end</p>
|
|
@ -7,5 +7,10 @@ These HTML5 tags should pass through just fine.
|
||||||
<nav>navigation</nav>
|
<nav>navigation</nav>
|
||||||
<article>read me</article>
|
<article>read me</article>
|
||||||
<aside>ignore me</aside>
|
<aside>ignore me</aside>
|
||||||
|
<article>read
|
||||||
|
me</article>
|
||||||
|
<aside>
|
||||||
|
ignore me
|
||||||
|
</aside>
|
||||||
|
|
||||||
the end
|
the end
|
5
test/extensions/github/basic.html
Normal file
5
test/extensions/github/basic.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<p><a href="http://github.github.com/github-flavored-markdown/">github-flavored markdown</a> adds support for:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><del>strike-through text</del></li>
|
||||||
|
</ul>
|
3
test/extensions/github/basic.md
Normal file
3
test/extensions/github/basic.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[github-flavored markdown](http://github.github.com/github-flavored-markdown/) adds support for:
|
||||||
|
|
||||||
|
* ~~strike-through text~~
|
|
@ -14,7 +14,7 @@ var runTestsInDir = function(dir, converter) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Run each test case (markdown -> html)
|
// Run each test case (markdown -> html)
|
||||||
cases.forEach(function(test){
|
showdown.forEach(cases, function(test){
|
||||||
var name = test.replace(/[-.]/g, ' ');
|
var name = test.replace(/[-.]/g, ' ');
|
||||||
it (name, function(){
|
it (name, function(){
|
||||||
var mdpath = path.join(dir, test + '.md'),
|
var mdpath = path.join(dir, test + '.md'),
|
||||||
|
@ -70,7 +70,7 @@ if (path.existsSync('test/extensions')) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Run tests in each extension sub-folder
|
// Run tests in each extension sub-folder
|
||||||
extensions.forEach(function(ext){
|
showdown.forEach(extensions, function(ext){
|
||||||
// Make sure extension exists
|
// Make sure extension exists
|
||||||
var src = 'src/extensions/' + ext + '.js';
|
var src = 'src/extensions/' + ext + '.js';
|
||||||
if (!path.existsSync(src)) {
|
if (!path.existsSync(src)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user