@ -2,101 +2,49 @@
/ *
/ *
* to - markdown - an HTML to Markdown converter
* to - markdown - an HTML to Markdown converter
*
*
* Copyright 2011 -15 , Dom Christie
* Copyright 2011 + , Dom Christie
* Licenced under the MIT licence
* Licenced under the MIT licence
*
*
* /
* /
'use strict' ;
'use strict'
var toMarkdown ;
var converters ;
var mdConverters = require ( './lib/md-converters' ) ;
var gfmConverters = require ( './lib/gfm-converters' ) ;
var collapse = require ( 'collapse-whitespace' ) ;
/ *
var toMarkdown
* Set up window and document for Node . js
var converters
* /
var mdConverters = require ( './lib/md-converters' )
var gfmConverters = require ( './lib/gfm-converters' )
var _window = ( typeof window !== 'undefined' ? window : this ) , _document ;
var HtmlParser = require ( './lib/html-parser' )
if ( typeof document === 'undefined' ) {
var collapse = require ( 'collapse-whitespace' )
_document = require ( 'jsdom' ) . jsdom ( ) ;
}
else {
_document = document ;
}
/ *
/ *
* Utilities
* Utilities
* /
* /
function trim ( string ) {
return string . replace ( /^[ \r\n\t]+|[ \r\n\t]+$/g , '' ) ;
}
var blocks = [ 'address' , 'article' , 'aside' , 'audio' , 'blockquote' , 'body' ,
var blocks = [ 'address' , 'article' , 'aside' , 'audio' , 'blockquote' , 'body' ,
'canvas' , 'center' , 'dd' , 'dir' , 'div' , 'dl' , 'dt' , 'fieldset' , 'figcaption' ,
'canvas' , 'center' , 'dd' , 'dir' , 'div' , 'dl' , 'dt' , 'fieldset' , 'figcaption' ,
'figure' , 'footer' , 'form' , 'frameset' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' ,
'figure' , 'footer' , 'form' , 'frameset' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' ,
'header' , 'hgroup' , 'hr' , 'html' , 'isindex' , 'li' , 'main' , 'menu' , 'nav' ,
'header' , 'hgroup' , 'hr' , 'html' , 'isindex' , 'li' , 'main' , 'menu' , 'nav' ,
'noframes' , 'noscript' , 'ol' , 'output' , 'p' , 'pre' , 'section' , 'table' ,
'noframes' , 'noscript' , 'ol' , 'output' , 'p' , 'pre' , 'section' , 'table' ,
'tbody' , 'td' , 'tfoot' , 'th' , 'thead' , 'tr' , 'ul'
'tbody' , 'td' , 'tfoot' , 'th' , 'thead' , 'tr' , 'ul'
] ;
]
function isBlock ( node ) {
function isBlock ( node ) {
return blocks . indexOf ( node . nodeName . toLowerCase ( ) ) !== - 1 ;
return blocks . indexOf ( node . nodeName . toLowerCase ( ) ) !== - 1
}
}
var voids = [
var voids = [
'area' , 'base' , 'br' , 'col' , 'command' , 'embed' , 'hr' , 'img' , 'input' ,
'area' , 'base' , 'br' , 'col' , 'command' , 'embed' , 'hr' , 'img' , 'input' ,
'keygen' , 'link' , 'meta' , 'param' , 'source' , 'track' , 'wbr'
'keygen' , 'link' , 'meta' , 'param' , 'source' , 'track' , 'wbr'
] ;
]
function isVoid ( node ) {
function isVoid ( node ) {
return voids . indexOf ( node . nodeName . toLowerCase ( ) ) !== - 1 ;
return voids . indexOf ( node . nodeName . toLowerCase ( ) ) !== - 1
}
}
/ *
* Parsing HTML strings
* /
function canParseHtml ( ) {
var Parser = _window . DOMParser , canParse = false ;
// Adapted from https://gist.github.com/1129031
// Firefox/Opera/IE throw errors on unsupported types
try {
// WebKit returns null on unsupported types
if ( new Parser ( ) . parseFromString ( '' , 'text/html' ) ) {
canParse = true ;
}
} catch ( e ) { }
return canParse ;
}
function createHtmlParser ( ) {
var Parser = function ( ) { } ;
Parser . prototype . parseFromString = function ( string ) {
var newDoc = _document . implementation . createHTMLDocument ( '' ) ;
if ( string . toLowerCase ( ) . indexOf ( '<!doctype' ) > - 1 ) {
newDoc . documentElement . innerHTML = string ;
}
else {
newDoc . body . innerHTML = string ;
}
return newDoc ;
} ;
return Parser ;
}
var HtmlParser = canParseHtml ( ) ? _window . DOMParser : createHtmlParser ( ) ;
function htmlToDom ( string ) {
function htmlToDom ( string ) {
var tree = new HtmlParser ( ) . parseFromString ( string , 'text/html' ) ;
var tree = new HtmlParser ( ) . parseFromString ( string , 'text/html' )
collapse ( tree , isBlock ) ;
collapse ( tree . documentElement , isBlock )
return tree ;
return tree
}
}
/ *
/ *
@ -104,20 +52,22 @@ function htmlToDom(string) {
* /
* /
function bfsOrder ( node ) {
function bfsOrder ( node ) {
var inqueue = [ node ] ,
var inqueue = [ node ]
outqueue = [ ] ,
var outqueue = [ ]
elem , children , i ;
var elem
var children
var i
while ( inqueue . length > 0 ) {
while ( inqueue . length > 0 ) {
elem = inqueue . shift ( ) ;
elem = inqueue . shift ( )
outqueue . push ( elem ) ;
outqueue . push ( elem )
children = elem . childNodes ;
children = elem . childNodes
for ( i = 0 ; i < children . length ; i ++ ) {
for ( i = 0 ; i < children . length ; i ++ ) {
if ( children [ i ] . nodeType === 1 ) { inqueue . push ( children [ i ] ) ; }
if ( children [ i ] . nodeType === 1 ) inqueue . push ( children [ i ] )
}
}
}
}
outqueue . shift ( ) ;
outqueue . shift ( )
return outqueue ;
return outqueue
}
}
/ *
/ *
@ -125,17 +75,15 @@ function bfsOrder(node) {
* /
* /
function getContent ( node ) {
function getContent ( node ) {
var text = '' ;
var text = ''
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
if ( node . childNodes [ i ] . nodeType === 1 ) {
if ( node . childNodes [ i ] . nodeType === 1 ) {
text += node . childNodes [ i ] . _replacement ;
text += node . childNodes [ i ] . _replacement
}
} else if ( node . childNodes [ i ] . nodeType === 3 ) {
else if ( node . childNodes [ i ] . nodeType === 3 ) {
text += node . childNodes [ i ] . data
text += node . childNodes [ i ] . data ;
} else continue
}
}
else { continue ; }
return text
}
return text ;
}
}
/ *
/ *
@ -143,63 +91,62 @@ function getContent(node) {
* /
* /
function outer ( node , content ) {
function outer ( node , content ) {
return node . cloneNode ( false ) . outerHTML . replace ( '><' , '>' + content + '<' ) ;
return node . cloneNode ( false ) . outerHTML . replace ( '><' , '>' + content + '<' )
}
}
function canConvert ( node , filter ) {
function canConvert ( node , filter ) {
if ( typeof filter === 'string' ) {
if ( typeof filter === 'string' ) {
return filter === node . nodeName . toLowerCase ( ) ;
return filter === node . nodeName . toLowerCase ( )
}
}
if ( Array . isArray ( filter ) ) {
if ( Array . isArray ( filter ) ) {
return filter . indexOf ( node . nodeName . toLowerCase ( ) ) !== - 1 ;
return filter . indexOf ( node . nodeName . toLowerCase ( ) ) !== - 1
}
} else if ( typeof filter === 'function' ) {
else if ( typeof filter === 'function' ) {
return filter . call ( toMarkdown , node )
return filter . call ( toMarkdown , node ) ;
} else {
}
throw new TypeError ( '`filter` needs to be a string, array, or function' )
else {
throw new TypeError ( '`filter` needs to be a string, array, or function' ) ;
}
}
}
}
function isFlankedByWhitespace ( side , node ) {
function isFlankedByWhitespace ( side , node ) {
var sibling , regExp , isFlanked ;
var sibling
var regExp
var isFlanked
if ( side === 'left' ) {
if ( side === 'left' ) {
sibling = node . previousSibling ;
sibling = node . previousSibling
regExp = / $/ ;
regExp = / $/
}
} else {
else {
sibling = node . nextSibling
sibling = node . nextSibling ;
regExp = /^ /
regExp = /^ / ;
}
}
if ( sibling ) {
if ( sibling ) {
if ( sibling . nodeType === 3 ) {
if ( sibling . nodeType === 3 ) {
isFlanked = regExp . test ( sibling . nodeValue ) ;
isFlanked = regExp . test ( sibling . nodeValue )
}
} else if ( sibling . nodeType === 1 && ! isBlock ( sibling ) ) {
else if ( sibling . nodeType === 1 && ! isBlock ( sibling ) ) {
isFlanked = regExp . test ( sibling . textContent )
isFlanked = regExp . test ( sibling . textContent ) ;
}
}
}
}
return isFlanked ;
return isFlanked
}
}
function flankingWhitespace ( node ) {
function flankingWhitespace ( node , content ) {
var leading = '' , trailing = '' ;
var leading = ''
var trailing = ''
if ( ! isBlock ( node ) ) {
if ( ! isBlock ( node ) ) {
var hasLeading = /^[ \r\n\t]/ . test ( node. innerHTML ) ,
var hasLeading = /^[ \r\n\t]/ . test ( content)
hasTrailing = /[ \r\n\t]$/ . test ( node . innerHTML ) ;
var hasTrailing = /[ \r\n\t]$/ . test ( content )
if ( hasLeading && ! isFlankedByWhitespace ( 'left' , node ) ) {
if ( hasLeading && ! isFlankedByWhitespace ( 'left' , node ) ) {
leading = ' ' ;
leading = ' '
}
}
if ( hasTrailing && ! isFlankedByWhitespace ( 'right' , node ) ) {
if ( hasTrailing && ! isFlankedByWhitespace ( 'right' , node ) ) {
trailing = ' ' ;
trailing = ' '
}
}
}
}
return { leading : leading , trailing : trailing } ;
return { leading : leading , trailing : trailing }
}
}
/ *
/ *
@ -208,153 +155,157 @@ function flankingWhitespace(node) {
* /
* /
function process ( node ) {
function process ( node ) {
var replacement , content = getContent ( node ) ;
var replacement
var content = getContent ( node )
// Remove blank nodes
// Remove blank nodes
if ( ! isVoid ( node ) && ! /A /. test ( node . nodeName ) && /^\s*$/i . test ( content ) ) {
if ( ! isVoid ( node ) && ! /A |TH|TD /. test ( node . nodeName ) && /^\s*$/i . test ( content ) ) {
node . _replacement = '' ;
node . _replacement = ''
return ;
return
}
}
for ( var i = 0 ; i < converters . length ; i ++ ) {
for ( var i = 0 ; i < converters . length ; i ++ ) {
var converter = converters [ i ] ;
var converter = converters [ i ]
if ( canConvert ( node , converter . filter ) ) {
if ( canConvert ( node , converter . filter ) ) {
if ( typeof converter . replacement !== 'function' ) {
if ( typeof converter . replacement !== 'function' ) {
throw new TypeError (
throw new TypeError (
'`replacement` needs to be a function that returns a string'
'`replacement` needs to be a function that returns a string'
) ;
)
}
}
var whitespace = flankingWhitespace ( node );
var whitespace = flankingWhitespace ( node , content )
if ( whitespace . leading || whitespace . trailing ) {
if ( whitespace . leading || whitespace . trailing ) {
content = trim( content ) ;
content = content. trim ( )
}
}
replacement = whitespace . leading +
replacement = whitespace . leading +
converter . replacement . call ( toMarkdown , content , node ) +
converter . replacement . call ( toMarkdown , content , node ) +
whitespace . trailing ;
whitespace . trailing
break ;
break
}
}
}
}
node . _replacement = replacement ;
node . _replacement = replacement
}
}
toMarkdown = function ( input , options ) {
toMarkdown = function ( input , options ) {
options = options || { } ;
options = options || { }
if ( typeof input !== 'string' ) {
if ( typeof input !== 'string' ) {
throw new TypeError ( input + ' is not a string' ) ;
throw new TypeError ( input + ' is not a string' )
}
if ( input === '' ) {
return ''
}
}
// Escape potential ol triggers
// Escape potential ol triggers
input = input . replace ( /(\d+)\. /g , '$1\\. ' ) ;
input = input . replace ( /(\d+)\. /g , '$1\\. ' )
var clone = htmlToDom ( input ) . body ,
var clone = htmlToDom ( input ) . body
nodes = bfsOrder ( clone ) ,
var nodes = bfsOrder ( clone )
output ;
var output
converters = mdConverters . slice ( 0 ) ;
converters = mdConverters . slice ( 0 )
if ( options . gfm ) {
if ( options . gfm ) {
converters = gfmConverters . concat ( converters ) ;
converters = gfmConverters . concat ( converters )
}
}
if ( options . converters ) {
if ( options . converters ) {
converters = options . converters . concat ( converters ) ;
converters = options . converters . concat ( converters )
}
}
// Process through nodes in reverse (so deepest child elements are first).
// Process through nodes in reverse (so deepest child elements are first).
for ( var i = nodes . length - 1 ; i >= 0 ; i -- ) {
for ( var i = nodes . length - 1 ; i >= 0 ; i -- ) {
process ( nodes [ i ] ) ;
process ( nodes [ i ] )
}
}
output = getContent ( clone ) ;
output = getContent ( clone )
return output . replace ( /^[\t\r\n]+|[\t\r\n\s]+$/g , '' )
return output . replace ( /^[\t\r\n]+|[\t\r\n\s]+$/g , '' )
. replace ( /\n\s+\n/g , '\n\n' )
. replace ( /\n\s+\n/g , '\n\n' )
. replace ( /\n{3,}/g , '\n\n' ) ;
. replace ( /\n{3,}/g , '\n\n' )
} ;
}
toMarkdown . isBlock = isBlock ;
toMarkdown . isBlock = isBlock
toMarkdown . isVoid = isVoid ;
toMarkdown . isVoid = isVoid
toMarkdown . trim = trim ;
toMarkdown . outer = outer
toMarkdown . outer = outer ;
module . exports = toMarkdown ;
module . exports = toMarkdown
} , { "./lib/gfm-converters" : 2 , "./lib/ md-converters": 3 , "collapse-whitespace" : 4 , "jsdom ": 7 } ] , 2 : [ function ( require , module , exports ) {
} , { "./lib/gfm-converters" : 2 , "./lib/ html-parser": 3 , "./lib/md-converters" : 4 , "collapse-whitespace ": 7 } ] , 2 : [ function ( require , module , exports ) {
'use strict' ;
'use strict'
function cell ( content , node ) {
function cell ( content , node ) {
var index = Array . prototype . indexOf . call ( node . parentNode . childNodes , node ) ;
var index = Array . prototype . indexOf . call ( node . parentNode . childNodes , node )
var prefix = ' ' ;
var prefix = ' '
if ( index === 0 ) { prefix = '| ' ; }
if ( index === 0 ) prefix = '| '
return prefix + content + ' |' ;
return prefix + content + ' |'
}
}
var highlightRegEx = /highlight highlight-(\S+)/ ;
var highlightRegEx = /highlight highlight-(\S+)/
module . exports = [
module . exports = [
{
{
filter : 'br' ,
filter : 'br' ,
replacement : function ( ) {
replacement : function ( ) {
return '\n' ;
return '\n'
}
}
} ,
} ,
{
{
filter : [ 'del' , 's' , 'strike' ] ,
filter : [ 'del' , 's' , 'strike' ] ,
replacement : function ( content ) {
replacement : function ( content ) {
return '~~' + content + '~~' ;
return '~~' + content + '~~'
}
}
} ,
} ,
{
{
filter : function ( node ) {
filter : function ( node ) {
return node . type === 'checkbox' && node . parentNode . nodeName === 'LI' ;
return node . type === 'checkbox' && node . parentNode . nodeName === 'LI'
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
return ( node . checked ? '[x]' : '[ ]' ) + ' ' ;
return ( node . checked ? '[x]' : '[ ]' ) + ' '
}
}
} ,
} ,
{
{
filter : [ 'th' , 'td' ] ,
filter : [ 'th' , 'td' ] ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
return cell ( content , node ) ;
return cell ( content , node )
}
}
} ,
} ,
{
{
filter : 'tr' ,
filter : 'tr' ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var borderCells = '' ;
var borderCells = ''
var alignMap = { left : ':--' , right : '--:' , center : ':-:' } ;
var alignMap = { left : ':--' , right : '--:' , center : ':-:' }
if ( node . parentNode . nodeName === 'THEAD' ) {
if ( node . parentNode . nodeName === 'THEAD' ) {
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
var align = node . childNodes [ i ] . attributes . align ;
var align = node . childNodes [ i ] . attributes . align
var border = '---' ;
var border = '---'
if ( align ) { border = alignMap [ align . value ] || border ; }
if ( align ) border = alignMap [ align . value ] || border
borderCells += cell ( border , node . childNodes [ i ] ) ;
borderCells += cell ( border , node . childNodes [ i ] )
}
}
}
}
return '\n' + content + ( borderCells ? '\n' + borderCells : '' ) ;
return '\n' + content + ( borderCells ? '\n' + borderCells : '' )
}
}
} ,
} ,
{
{
filter : 'table' ,
filter : 'table' ,
replacement : function ( content ) {
replacement : function ( content ) {
return '\n\n' + content + '\n\n' ;
return '\n\n' + content + '\n\n'
}
}
} ,
} ,
{
{
filter : [ 'thead' , 'tbody' , 'tfoot' ] ,
filter : [ 'thead' , 'tbody' , 'tfoot' ] ,
replacement : function ( content ) {
replacement : function ( content ) {
return content ;
return content
}
}
} ,
} ,
@ -363,10 +314,10 @@ module.exports = [
filter : function ( node ) {
filter : function ( node ) {
return node . nodeName === 'PRE' &&
return node . nodeName === 'PRE' &&
node . firstChild &&
node . firstChild &&
node . firstChild . nodeName === 'CODE' ;
node . firstChild . nodeName === 'CODE'
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
return '\n\n```\n' + node . firstChild . textContent + '\n```\n\n' ;
return '\n\n```\n' + node . firstChild . textContent + '\n```\n\n'
}
}
} ,
} ,
@ -375,232 +326,356 @@ module.exports = [
filter : function ( node ) {
filter : function ( node ) {
return node . nodeName === 'PRE' &&
return node . nodeName === 'PRE' &&
node . parentNode . nodeName === 'DIV' &&
node . parentNode . nodeName === 'DIV' &&
highlightRegEx . test ( node . parentNode . className ) ;
highlightRegEx . test ( node . parentNode . className )
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var language = node . parentNode . className . match ( highlightRegEx ) [ 1 ] ;
var language = node . parentNode . className . match ( highlightRegEx ) [ 1 ]
return '\n\n```' + language + '\n' + node . textContent + '\n```\n\n' ;
return '\n\n```' + language + '\n' + node . textContent + '\n```\n\n'
}
}
} ,
} ,
{
{
filter : function ( node ) {
filter : function ( node ) {
return node . nodeName === 'DIV' &&
return node . nodeName === 'DIV' &&
highlightRegEx . test ( node . className ) ;
highlightRegEx . test ( node . className )
} ,
} ,
replacement : function ( content ) {
replacement : function ( content ) {
return '\n\n' + content + '\n\n' ;
return '\n\n' + content + '\n\n'
}
}
}
}
] ;
]
} , { } ] , 3 : [ function ( require , module , exports ) {
} , { } ] , 3 : [ function ( require , module , exports ) {
'use strict' ;
/ *
* Set up window for Node . js
* /
var _window = ( typeof window !== 'undefined' ? window : this )
/ *
* Parsing HTML strings
* /
function canParseHtmlNatively ( ) {
var Parser = _window . DOMParser
var canParse = false
// Adapted from https://gist.github.com/1129031
// Firefox/Opera/IE throw errors on unsupported types
try {
// WebKit returns null on unsupported types
if ( new Parser ( ) . parseFromString ( '' , 'text/html' ) ) {
canParse = true
}
} catch ( e ) { }
return canParse
}
function createHtmlParser ( ) {
var Parser = function ( ) { }
// For Node.js environments
if ( typeof document === 'undefined' ) {
var jsdom = require ( 'jsdom' )
Parser . prototype . parseFromString = function ( string ) {
return jsdom . jsdom ( string , {
features : {
FetchExternalResources : [ ] ,
ProcessExternalResources : false
}
} )
}
} else {
if ( ! shouldUseActiveX ( ) ) {
Parser . prototype . parseFromString = function ( string ) {
var doc = document . implementation . createHTMLDocument ( '' )
doc . open ( )
doc . write ( string )
doc . close ( )
return doc
}
} else {
Parser . prototype . parseFromString = function ( string ) {
var doc = new window . ActiveXObject ( 'htmlfile' )
doc . designMode = 'on' // disable on-page scripts
doc . open ( )
doc . write ( string )
doc . close ( )
return doc
}
}
}
return Parser
}
function shouldUseActiveX ( ) {
var useActiveX = false
try {
document . implementation . createHTMLDocument ( '' ) . open ( )
} catch ( e ) {
if ( window . ActiveXObject ) useActiveX = true
}
return useActiveX
}
module . exports = canParseHtmlNatively ( ) ? _window . DOMParser : createHtmlParser ( )
} , { "jsdom" : 6 } ] , 4 : [ function ( require , module , exports ) {
'use strict'
module . exports = [
module . exports = [
{
{
filter : 'p' ,
filter : 'p' ,
replacement : function ( content ) {
replacement : function ( content ) {
return '\n\n' + content + '\n\n' ;
return '\n\n' + content + '\n\n'
}
} ,
{
filter : 'div' ,
replacement : function ( content ) {
return content + '\n' ;
}
}
} ,
} ,
{
{
filter : 'br' ,
filter : 'br' ,
replacement : function ( ) {
replacement : function ( ) {
return ' \n' ;
return ' \n'
}
}
} ,
} ,
{
{
filter : [ 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' ] ,
filter : [ 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' ] ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var hLevel = node . nodeName . charAt ( 1 ) ;
var hLevel = node . nodeName . charAt ( 1 )
var hPrefix = '' ;
var hPrefix = ''
for ( var i = 0 ; i < hLevel ; i ++ ) {
for ( var i = 0 ; i < hLevel ; i ++ ) {
hPrefix += '#' ;
hPrefix += '#'
}
}
return '\n\n' + hPrefix + ' ' + content + '\n\n' ;
return '\n\n' + hPrefix + ' ' + content + '\n\n'
}
}
} ,
} ,
{
{
filter : 'hr' ,
filter : 'hr' ,
replacement : function ( ) {
replacement : function ( ) {
return '\n\n* * *\n\n' ;
return '\n\n* * *\n\n'
}
}
} ,
} ,
{
{
filter : [ 'em' , 'i' ] ,
filter : [ 'em' , 'i' ] ,
replacement : function ( content ) {
replacement : function ( content ) {
return '*' + content + '*' ;
return '_' + content + '_'
}
} ,
{
filter : [ 'strong' , 'b' ] ,
replacement : function ( content ) {
return '**' + content + '**'
}
}
} ,
} ,
{
{
filter : [ 'u' ] ,
filter : [ 'u' ] ,
replacement : function ( content ) {
replacement : function ( content ) {
return '_' + content + '_' ;
return '_' + content + '_'
}
}
} ,
} ,
{
{
filter : [ 'strong' , 'b' ] ,
filter : [ ' del', 's' , 'strike '] ,
replacement : function ( content ) {
replacement : function ( content ) {
return '**' + content + '**' ;
return ' ~~' + content + '~~'
}
}
} ,
} ,
{
{
filter : [ 'strike' , 's' ] ,
filter : 'div' ,
replacement : function ( content ) {
replacement : function ( content ) {
return '~~' + content + '~~' ;
return content + '\n\n'
}
}
} ,
} ,
// Inline code
// Inline code
{
{
filter : function ( node ) {
filter : function ( node ) {
var hasSiblings = node . previousSibling || node . nextSibling ;
var hasSiblings = node . previousSibling || node . nextSibling
var isCodeBlock = node . parentNode . nodeName === 'PRE' && ! hasSiblings ;
var isCodeBlock = node . parentNode . nodeName === 'PRE' && ! hasSiblings
return node . nodeName === 'CODE' && ! isCodeBlock ;
return node . nodeName === 'CODE' && ! isCodeBlock
} ,
} ,
replacement : function ( content ) {
replacement : function ( content ) {
return '`' + content + '`' ;
return '`' + content + '`'
}
}
} ,
} ,
{
{
filter : function ( node ) {
filter : function ( node ) {
return node . nodeName === 'A' && node . getAttribute ( 'href' ) ;
return node . nodeName === 'A' && node . getAttribute ( 'href' )
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var titlePart = node . title ? ' "' + node . title + '"' : '' ;
var titlePart = node . title ? ' "' + node . title + '"' : ''
return '[' + content + '](' + node . getAttribute ( 'href' ) + titlePart + ')' ;
return '[' + content + '](' + node . getAttribute ( 'href' ) + titlePart + ')'
}
}
} ,
} ,
{
{
filter : 'video' ,
filter : 'video' ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var alt = node . getAttribute ( "alt" ) || '' ;
var alt = node . getAttribute ( 'alt' ) || ''
var src ;
var src
for ( var i = 0 ; i < node . childNodes . length ; i ++ )
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
{
if ( node . childNodes [ i ] . localName === 'source' ) {
if ( node . childNodes [ i ] . localName == 'source' ) {
src = node . childNodes [ i ] . getAttribute ( 'src' )
src = node . childNodes [ i ] . getAttribute ( 'src' ) ;
break
break ;
} }
}
var title = node . title || ''
}
var titlePart = title ? ' "' + title + '"' : ''
var title = node . title || '' ;
return src ? '![video:' + alt + ']' + '(' + src + titlePart + ')' : ''
var titlePart = title ? ' "' + title + '"' : '' ;
return src ? '![video:' + alt + ']' + '(' + src + titlePart + ')' : '' ;
}
}
} ,
} ,
{
{
filter : 'audio' ,
filter : 'audio' ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var alt = node . getAttribute ( "alt" ) || '' ;
var alt = node . getAttribute ( 'alt' ) || ''
var src = node . getAttribute ( 'src' ) || '' ;
var src = node . getAttribute ( 'src' ) || ''
if ( ! src )
if ( ! src ) {
for ( var i = 0 ; i < node . childNodes . length ; i ++ )
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
{
if ( node . childNodes [ i ] . localName === 'source' ) {
if ( node . childNodes [ i ] . localName == 'source' ) {
src = node . childNodes [ i ] . getAttribute ( 'src' )
src = node . childNodes [ i ] . getAttribute ( 'src' ) ;
break
break ;
} } }
}
var title = node . title || ''
}
var titlePart = title ? ' "' + title + '"' : ''
var title = node . title || '' ;
return src ? '![audio:' + alt + ']' + '(' + src + titlePart + ')' : ''
var titlePart = title ? ' "' + title + '"' : '' ;
return src ? '![audio:' + alt + ']' + '(' + src + titlePart + ')' : '' ;
}
}
} ,
} ,
{
{
filter : 'img' ,
filter : 'img' ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var alt = node . getAttribute( " alt") || '' ;
var alt = node . alt || ''
var src = node . getAttribute ( 'src' ) || '' ;
var src = node . getAttribute ( 'src' ) || ''
var title = node . getAttribute( ' title') || '' ;
var title = node . title || ''
var titlePart = title ? ' "' + title + '"' : '' ;
var titlePart = title ? ' "' + title + '"' : ''
return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : '' ;
return src ? '![' + alt + ']' + '(' + src + titlePart + ')' : ''
}
}
} ,
} ,
// Code blocks
// Code blocks
{
{
filter : function ( node ) {
filter : function ( node ) {
return node . nodeName === 'PRE' && node . firstChild . nodeName === 'CODE' ;
return node . nodeName === 'PRE' && node . firstChild . nodeName === 'CODE'
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
return '\n\n ' + node . firstChild . textContent . replace ( /\n/g , '\n ' ) + '\n\n' ;
return '\n\n ' + node . firstChild . textContent . replace ( /\n/g , '\n ' ) + '\n\n'
}
}
} ,
} ,
{
{
filter : 'blockquote' ,
filter : 'blockquote' ,
replacement : function ( content ) {
replacement : function ( content ) {
content = this . trim ( content ) ;
content = content . trim ( )
content = content . replace ( /\n{3,}/g , '\n\n' ) ;
content = content . replace ( /\n{3,}/g , '\n\n' )
content = content . replace ( /^/gm , '> ' ) ;
content = content . replace ( /^/gm , '> ' )
return '\n\n' + content + '\n\n' ;
return '\n\n' + content + '\n\n'
}
}
} ,
} ,
{
{
filter : 'li' ,
filter : 'li' ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
content = content . replace ( /^\s+/ , '' ) . replace ( /\n/gm , '\n ' ) ;
content = content . replace ( /^\s+/ , '' ) . replace ( /\n/gm , '\n ' )
var prefix = '* ' ;
var prefix = '* '
var parent = node . parentNode ;
var parent = node . parentNode
var index = Array . prototype . indexOf . call ( parent . children , node ) + 1 ;
var index = Array . prototype . indexOf . call ( parent . children , node ) + 1
prefix = /ol/i . test ( parent . nodeName ) ? index + '. ' : '* ' ;
prefix = /ol/i . test ( parent . nodeName ) ? index + '. ' : '* '
return prefix + content ;
return prefix + content
}
}
} ,
} ,
{
{
filter : [ 'ul' , 'ol' ] ,
filter : [ 'ul' , 'ol' ] ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
var strings = [ ] ;
var strings = [ ]
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
for ( var i = 0 ; i < node . childNodes . length ; i ++ ) {
strings . push ( node . childNodes [ i ] . _replacement ) ;
strings . push ( node . childNodes [ i ] . _replacement )
}
}
if ( /li/i . test ( node . parentNode . nodeName ) ) {
if ( /li/i . test ( node . parentNode . nodeName ) ) {
return '\n' + strings . join ( '\n' ) ;
return '\n' + strings . join ( '\n' )
}
}
return '\n\n' + strings . join ( '\n' ) + '\n\n' ;
return '\n\n' + strings . join ( '\n' ) + '\n\n'
}
}
} ,
} ,
{
{
filter : function ( node ) {
filter : function ( node ) {
return this . isBlock ( node ) ;
return this . isBlock ( node )
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
return '\n\n' + this . outer ( node , content ) + '\n\n' ;
return '\n\n' + this . outer ( node , content ) + '\n\n'
}
}
} ,
} ,
// Anything else!
// Anything else!
{
{
filter : function ( ) {
filter : function ( ) {
return true ;
return true
} ,
} ,
replacement : function ( content , node ) {
replacement : function ( content , node ) {
return this . outer ( node , content ) ;
return this . outer ( node , content )
}
}
}
}
]
} , { } ] , 5 : [ function ( require , module , exports ) {
/ * *
* This file automatically generated from ` build.js ` .
* Do not manually edit .
* /
module . exports = [
"address" ,
"article" ,
"aside" ,
"audio" ,
"blockquote" ,
"canvas" ,
"dd" ,
"div" ,
"dl" ,
"fieldset" ,
"figcaption" ,
"figure" ,
"footer" ,
"form" ,
"h1" ,
"h2" ,
"h3" ,
"h4" ,
"h5" ,
"h6" ,
"header" ,
"hgroup" ,
"hr" ,
"main" ,
"nav" ,
"noscript" ,
"ol" ,
"output" ,
"p" ,
"pre" ,
"section" ,
"table" ,
"tfoot" ,
"ul" ,
"video"
] ;
] ;
} , { } ] , 4 : [ function ( require , module , exports ) {
} , { } ] , 6 : [ function ( require , module , exports ) {
} , { } ] , 7 : [ function ( require , module , exports ) {
'use strict' ;
'use strict' ;
var voidElements = require ( 'void-elements' ) ;
var voidElements = require ( 'void-elements' ) ;
@ -738,51 +813,7 @@ function next(prev, current) {
module . exports = collapseWhitespace ;
module . exports = collapseWhitespace ;
} , { "block-elements" : 5 , "void-elements" : 6 } ] , 5 : [ function ( require , module , exports ) {
} , { "block-elements" : 5 , "void-elements" : 8 } ] , 8 : [ function ( require , module , exports ) {
/ * *
* This file automatically generated from ` build.js ` .
* Do not manually edit .
* /
module . exports = [
"address" ,
"article" ,
"aside" ,
"audio" ,
"blockquote" ,
"canvas" ,
"dd" ,
"div" ,
"dl" ,
"fieldset" ,
"figcaption" ,
"figure" ,
"footer" ,
"form" ,
"h1" ,
"h2" ,
"h3" ,
"h4" ,
"h5" ,
"h6" ,
"header" ,
"hgroup" ,
"hr" ,
"main" ,
"nav" ,
"noscript" ,
"ol" ,
"output" ,
"p" ,
"pre" ,
"section" ,
"table" ,
"tfoot" ,
"ul" ,
"video"
] ;
} , { } ] , 6 : [ function ( require , module , exports ) {
/ * *
/ * *
* This file automatically generated from ` pre-publish.js ` .
* This file automatically generated from ` pre-publish.js ` .
* Do not manually edit .
* Do not manually edit .
@ -807,7 +838,5 @@ module.exports = {
"wbr" : true
"wbr" : true
} ;
} ;
} , { } ] , 7 : [ function ( require , module , exports ) {
} , { } ] } , { } , [ 1 ] ) ( 1 )
} , { } ] } , { } , [ 1 ] ) ( 1 )
} ) ;
} ) ;