2015-05-03 21:50:25 -07:00
"use strict" ;
( function main ( ) {
// DOM elements
var markdown = document . getElementById ( "markdown" ) ;
var markup = document . getElementById ( "markup" ) ;
var numbered = document . getElementById ( "numbered" ) ;
var violations = document . getElementById ( "violations" ) ;
var form = document . getElementsByTagName ( "form" ) [ 0 ] ;
var openFile = document . getElementById ( "openFile" ) ;
2015-05-05 00:00:04 -07:00
// Variables
2015-09-26 16:55:33 -07:00
var markdownit = window . markdownit ( { "html" : true } ) ;
2015-05-03 21:50:25 -07:00
var newLineRe = /\r\n|\r|\n/ ;
2015-05-05 00:00:04 -07:00
var rulesMd = "https://github.com/DavidAnson/markdownlint" +
"/blob/master/doc/Rules.md" ;
2015-05-03 21:50:25 -07:00
2016-10-16 21:46:02 -07:00
// Sanitize string for HTML display
function sanitize ( str ) {
return str
. replace ( /&/g , "&" )
. replace ( /</g , "<" )
. replace ( />/g , ">" ) ;
}
2015-05-03 21:50:25 -07:00
// Handle input
function onMarkdownInput ( ) {
// Markdown
var content = markdown . value ;
// Markup
markup . innerHTML = markdownit . render ( content ) ;
// Numbered
2015-05-05 00:00:04 -07:00
var lines = content . split ( newLineRe ) ;
var padding = lines . length . toString ( ) . replace ( /\d/g , " " ) ;
numbered . innerHTML = lines
2015-05-03 21:50:25 -07:00
. map ( function mapNumberedLine ( line , index ) {
2016-10-16 21:46:02 -07:00
line = sanitize ( line ) ;
2015-05-05 00:00:04 -07:00
index ++ ;
var paddedIndex = ( padding + index ) . slice ( - padding . length ) ;
return "<span id='l" + index + "'><em>" + paddedIndex + "</em>: " +
line + "</span>" ;
2015-05-03 21:50:25 -07:00
} ) . join ( "\n" ) ;
// Violations
var options = {
"strings" : {
"content" : content
2015-05-07 09:15:41 -07:00
} ,
"config" : {
"MD013" : false
2017-07-05 21:53:21 -07:00
}
2015-05-03 21:50:25 -07:00
} ;
2016-10-16 21:46:02 -07:00
var results = window . markdownlint . sync ( options ) ;
violations . innerHTML = results . content . map ( function mapResult ( result ) {
2018-01-12 23:21:06 -08:00
var ruleName = result . ruleNames [ 0 ] ;
var ruleRef = rulesMd + "#" + ruleName . toLowerCase ( ) + "---" +
2018-01-22 20:54:26 -08:00
result . ruleDescription . toLowerCase ( )
. replace ( / /g , "-" )
. replace ( /[()]/g , "" ) ;
2016-10-16 21:46:02 -07:00
return "<a href='#" + result . lineNumber + "'><em>" + result . lineNumber +
2018-01-12 23:21:06 -08:00
"</em></a> - <a href='" + ruleRef + "'>" + ruleName + "</a> " +
2016-10-16 21:46:02 -07:00
result . ruleDescription +
( result . errorDetail ?
" [<span class='detail'>" +
sanitize ( result . errorDetail ) +
"</span>]" :
"" ) +
( result . errorContext ?
" [<span class='detail'>Context: \"" +
sanitize ( result . errorContext ) +
"\"</span>]" :
"" ) ;
2017-11-07 22:00:53 -08:00
// + (result.errorRange ?
// " <u style='white-space: pre-wrap'>" +
// lines[result.lineNumber - 1].substr(
// result.errorRange[0] - 1, result.errorRange[1]) +
// "</u>" :
// "");
2016-10-16 21:46:02 -07:00
} ) . join ( "<br/>" ) ;
2015-05-03 21:50:25 -07:00
}
// Load from a string or File object
function loadMarkdown ( source ) {
// Reset input element
form . reset ( ) ;
if ( typeof source === "string" ) {
// Update from string
markdown . value = source ;
onMarkdownInput ( ) ;
} else {
// Update from File object
var reader = new FileReader ( ) ;
2019-03-30 14:36:04 -07:00
reader . onload = function onload ( e ) {
2015-05-03 21:50:25 -07:00
markdown . value = e . target . result ;
onMarkdownInput ( ) ;
} ;
reader . readAsText ( source ) ;
}
}
// Handle drag-and-drop
function onDragOver ( e ) {
if ( e . dataTransfer && e . dataTransfer . dropEffect ) {
e . dataTransfer . dropEffect = "link" ;
e . preventDefault ( ) ;
}
}
function onDrop ( e ) {
if ( e . dataTransfer && e . dataTransfer . files ) {
loadMarkdown ( e . dataTransfer . files [ 0 ] ) ;
e . preventDefault ( ) ;
}
}
// Handle file open
function onOpenFileChange ( e ) {
if ( e . target && e . target . files ) {
loadMarkdown ( e . target . files [ 0 ] ) ;
}
}
2015-05-05 00:00:04 -07:00
// Handle violation navigation
function onLineNumberClick ( e ) {
2015-05-08 09:27:25 -07:00
var line = document . getElementById ( "l" + e . target . textContent ) ;
2015-05-05 00:00:04 -07:00
if ( line ) {
var highlighted = document . getElementsByClassName ( "highlight" ) ;
Array . prototype . forEach . call ( highlighted , function forElement ( element ) {
element . classList . remove ( "highlight" ) ;
} ) ;
line . classList . add ( "highlight" ) ;
line . scrollIntoView ( ) ;
e . preventDefault ( ) ;
}
}
2015-05-03 21:50:25 -07:00
// Add event listeners
document . body . addEventListener ( "dragover" , onDragOver ) ;
document . body . addEventListener ( "drop" , onDrop ) ;
openFile . addEventListener ( "change" , onOpenFileChange ) ;
markdown . addEventListener ( "input" , onMarkdownInput ) ;
2015-05-05 00:00:04 -07:00
violations . addEventListener ( "click" , onLineNumberClick , true ) ;
2015-05-07 09:15:41 -07:00
2015-09-26 22:22:22 -07:00
/* eslint-disable max-len */
2015-05-07 09:15:41 -07:00
markdown . value = [
"## Introduction" ,
"" ,
2019-02-10 11:38:01 -08:00
"`markdownlint` is a [Node.js](https://nodejs.org/)/[io.js](https://iojs.org/) style checker and lint tool for [Markdown](https://en.wikipedia.org/wiki/Markdown)/[CommonMark](https://commonmark.org/) files to automatically validate content, prevent rendering problems, and promote consistency." ,
2015-05-07 09:15:41 -07:00
"This page offers an easy way to try it out interactively!" ,
"" ,
"#### Instructions" ,
"" ,
"Type or paste `Markdown ` content in the upper-left box, drag-and-drop a file, or open one with the chooser at the top." ,
"Content gets parsed and displayed in the upper-right box; rule violations (if any) show up in the lower-right box." ,
"Click a violation for information about it or click its line number to highlighted it in the lower-left box." ,
"" ,
"> *Note*: [All rules](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md) are enabled except for [MD013 Line length](https://github.com/DavidAnson/markdownlint/blob/master/doc/Rules.md#md013---line-length). " ,
"" ,
"" ,
"#### Resources" ,
"* [`markdownlint` on GitHub](https://github.com/DavidAnson/markdownlint)" ,
"* [`markdownlint` on npm](https://www.npmjs.com/package/markdownlint)" ,
2019-02-10 11:38:01 -08:00
"* [Markdown specification](https://daringfireball.net/projects/markdown/)" ,
"*\t[CommonMark specification](https://commonmark.org/)" ,
2015-05-07 09:15:41 -07:00
"" ,
"#### Thanks" ,
"" ,
2017-06-18 15:49:33 -07:00
"[`markdownlint/Ruby`](https://github.com/markdownlint/markdownlint) for the inspiration and [`markdown-it`](https://github.com/markdown-it/markdown-it) for the parser and interactive demo idea!"
2015-05-07 09:15:41 -07:00
] . join ( "\n" ) ;
2015-09-26 22:22:22 -07:00
/* eslint-enable max-len */
2015-05-07 09:15:41 -07:00
onMarkdownInput ( ) ;
2015-05-03 21:50:25 -07:00
} ( ) ) ;