Socket
Socket
Sign inDemoInstall

marked

Package Overview
Dependencies
Maintainers
1
Versions
178
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

marked - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

bin/marked

362

lib/marked.js

@@ -6,7 +6,76 @@ /**

;(function() {
/**
* Client-Side Shim
*/
if (typeof module === 'undefined') {
var keys = Object.keys
, hop = Object.prototype.hasOwnProperty
, first = true
, a = Array.prototype;
Object.keys = function(obj) {
if (obj === inline) {
if (!first) {
return [
'autolink',
'tag',
'img',
'link',
'reflink',
'strong',
'em',
'escape',
'text'
];
}
first = false;
} else if (obj === block) {
return [
'newline',
'block',
'heading',
'lheading',
'hr',
'blockquote',
'list',
'html',
'text'
];
}
if (keys) {
return keys.call(Object, obj);
}
var out = []
, key;
for (key in obj) if (hop.call(obj, key)) {
out.push(key);
}
return out;
};
if (!a.forEach) a.forEach = function(func, context) {
var i = 0
, l = this.length;
for (; i < l; i++) {
func.call(context, this[i], i, this);
}
};
if (!a.map) a.map = function(func, context) {
var out = [];
a.forEach.call(this, function(val, i, obj) {
out.push(func.call(context, val, i, obj));
});
return out;
};
}
/**
* Block-Level Grammar
*/
var rules = {
var block = {
newline: /^\n/,

@@ -23,42 +92,25 @@ block: /^[ ]{4,}[^\n]*(?:\n[ ]{4,}[^\n]*)*/,

var keys = Object.keys(rules)
, len = keys.length;
block.keys = Object.keys(block);
/**
* Shared
* Lexer
*/
var line
, links
, token
, tokens;
block.lexer = function(str) {
var tokens = []
, links = {};
/**
* Lexer
*/
// normalize whitespace
str = str.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n');
var lex = function(str, tokens) {
if (!tokens) {
tokens = [];
line = 0;
str = str.replace(/\t/g, ' ');
// normalize whitespace
str = str.replace(/\r\n/g, '\n')
.replace(/\r/g, '\n');
// experimental
//str = str.replace(/(^|\n) +(\n|$)/g, '$1$2');
str = str.replace(/\t/g, ' ');
//str = str.replace(/(^|\n) +(\n|$)/g, '$1$2');
// get the link definitions out of
// the way as they dont compile to
// anything, this results in a boost
// to performance. we could put this
// in the "inline" function instead
// but it confuses things because
// it doesn't actually output anything
// and it causes a performance hit.
links = {};
str = str.replace(
/^ {0,3}\[([^\]]+)\]: *([^ ]+)(?: +"([^"]+)")?/gm,
function(_, id, href, title) {
// grab link definitons
str = str.replace(
/^ {0,3}\[([^\]]+)\]: *([^ ]+)(?: +"([^"]+)")?[ \t]*(?:\n|$)/gm,
function(_, id, href, title) {
links[id] = {

@@ -69,13 +121,23 @@ href: href,

return '';
});
}
}
);
tokens.links = links;
return block.token(str, tokens, 0);
};
block.token = function lex(str, tokens, line) {
var keys = block.keys
, len = keys.length;
var i
, key
, rule;
, rule
, cap;
while (str.length)
while (str.length)
for (i = 0; i < len; i++) {
key = keys[i];
rule = rules[key];
rule = block[key];

@@ -113,3 +175,3 @@ cap = rule.exec(str);

case 'block':
cap = cap[0].replace(/^ +/gm, '');
cap = cap[0].replace(/^ {4}/gm, '');
tokens.push({

@@ -150,3 +212,6 @@ type: 'block',

});
lex(item, tokens);
// recurse
lex(item, tokens, line);
tokens.push({

@@ -176,3 +241,6 @@ type: 'list_item_end',

cap = cap[0].replace(/^ *>/gm, '');
lex(cap, tokens);
// recurse
lex(cap, tokens, line);
tokens.push({

@@ -194,72 +262,121 @@ type: 'blockquote_end',

// this is really bad. i should define
// some lexemes for all of the inline stuff,
// but this was just easier for the time being.
var inline = {
autolink: /^<([^ >]*(:|@)[^ >]*)>/,
tag: /^<[^\n>]+>/,
img: /^!\[([^\]]+)\]\(([^\s\)]+)\s*([^\)]*)\)/,
link: /^\[([^\]]+)\]\(([^\)]+)\)/,
reflink: /^\[([^\]]+)\]\[([^\]]+)\]/,
strong: /^__([\s\S]+?)__|^\*\*([\s\S]+?)\*\*/,
em: /^_([^_]+)_|^\*([^*]+)\*/,
escape: /^`([^`]+)`|^``([\s\S]+?)``/
};
var inline = function(str) {
// img
str = str.replace(
/!\[([^\]]+)\]\(([^\s\)]+)\s*([^\)]*)\)/g,
function(_, alt, src, title) {
return '<img src="'
+ src + '" alt="'
+ alt + '"'
+ (title
? ' title="' + title + '"'
: '')
+ '>';
});
// super hack for performance
inline.text = new RegExp(
'^([\\s\\S]+?)(?='
+ Object.keys(inline).map(function(key) {
return inline[key].source.replace(/(^|[^\[])\^/g, '$1');
}).join('|')
+ '|$)'
);
// links
str = str.replace(
/\[([^\]]+)\]\(([^\)]+)\)/g,
'<a href="$2">$1</a>'
);
inline.keys = Object.keys(inline);
// This is [an example][id]
// reference-style link.
str = str.replace(
/\[([^\]]+)\]\[([^\]]+)\]/g,
function(_, text, id) {
var link = links[id];
return '<a href="'
+ link.href + '"'
+ (link.title
? ' title="'
+ link.title + '"'
: '')
+ '>' + text + '</a>';
});
/**
* Inline Lexer
*/
// for <http://hello.world/> links
str = str.replace(
/(?:<|&lt;)([^<>:\/ ]+:(?:\/\/)?[^>\n]+?|[^<>\n]+?(@)[^<>\n]+?)(?:&gt;|>)/g,
function(_, href, at) {
if (at) {
// according to the markdown "spec"
// we need to mangle email addresses
var href = mangle(href)
, mail = mangle('mailto:') + href;
return '<a href="' + mail + '">' + href + '</a>';
}
return '<a href="' + href + '">' + href + '</a>';
});
inline.lexer = function(str) {
var rules = inline
, keys = inline.keys
, len = keys.length
, out = ''
, links = tokens.links;
// strong
str = str.replace(/__([^_]+)__/g, '<strong>$1</strong>');
str = str.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
var i
, key
, rule
, cap
, link
, text
, href;
// em
str = str.replace(/_([^_]+)_/g, '<em>$1</em>');
str = str.replace(/\*([^*]+)\*/g, '<em>$1</em>');
while (str.length) {
for (i = 0; i < len; i++) {
key = keys[i];
rule = rules[key];
// code
str = str.replace(/`([^`]+)`/g, function(_, s) {
return '<code>' + escape(s) + '</code>';
});
cap = rule.exec(str);
if (!cap) continue;
str = str.substring(cap[0].length);
// br
str = str.replace(/ $/gm, '<br>');
switch (key) {
case 'tag':
out += cap[0];
break;
case 'img':
out += '<img src="'
+ escape(cap[2])
+ '" alt="' + escape(cap[1])
+ '"'
+ (cap[3]
? ' title="'
+ escape(cap[3])
+ '"'
: '')
+ '>';
break;
case 'link':
case 'reflink':
link = links[cap[2]] || '';
out += '<a href="'
+ escape(link.href || cap[2])
+ '"'
+ (link.title
? ' title="'
+ escape(link.title)
+ '"'
: '')
+ '>'
+ inline.lexer(cap[1])
+ '</a>';
break;
case 'autolink':
if (cap[2] === '@') {
text = mangle(cap[1]);
href = mangle('mailto:') + text;
} else {
text = escape(cap[1]);
href = text;
}
out += '<a href="' + href + '">'
+ text
+ '</a>';
break;
case 'strong':
out += '<strong>'
+ inline.lexer(cap[2] || cap[1])
+ '</strong>';
break;
case 'em':
out += '<em>'
+ inline.lexer(cap[2] || cap[1])
+ '</em>';
break;
case 'escape':
out += '<code>'
+ escape(cap[2] || cap[1])
+ '</code>';
break;
case 'text':
out += escape(cap[1]);
break;
default:
break;
}
break;
}
}
return str;
return out;
};

@@ -271,2 +388,5 @@

var tokens
, token;
var next = function() {

@@ -282,3 +402,3 @@ return token = tokens.pop();

return '<h' + token.depth + '>'
+ inline(token.text)
+ inline.lexer(token.text)
+ '</h' + token.depth + '>';

@@ -309,4 +429,6 @@ case 'block':

while (next().type !== 'list_item_end') {
// TODO incorporate paragraph
// list items here
if (token.type === 'text') {
body.push(inline(token.text));
body.push(inline.lexer(token.text));
} else {

@@ -320,3 +442,3 @@ body.push(tok());

case 'html':
return inline(token.text);
return inline.lexer(token.text);
case 'text':

@@ -333,3 +455,3 @@ var body = []

return '<p>'
+ inline(body.join(' '))
+ inline.lexer(body.join(' '))
+ '</p>';

@@ -349,6 +471,4 @@ }

token = null;
links = null;
line = null;
return out.join('\n');
return out.join(' ');
};

@@ -360,5 +480,5 @@

var escape = function(html, d) {
var escape = function(html) {
return html
.replace(d ? /&(?![^;\n]+;)/ : /&/g, '&amp;')
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')

@@ -377,4 +497,4 @@ .replace(/>/g, '&gt;')

for (; i < l; i++) {
ch = str[i].charCodeAt(0);
if (Math.random() > .5) {
ch = str.charCodeAt(i);
if (Math.random() > 0.5) {
ch = 'x' + ch.toString(16);

@@ -392,9 +512,15 @@ }

exports = function(str) {
return parse(lex(str));
var marked = function(str) {
return parse(block.lexer(str));
};
exports.parser = parse;
exports.lexer = lex;
marked.parser = parse;
marked.lexer = block.lexer;
module.exports = exports;
if (typeof module !== 'undefined') {
module.exports = marked;
} else {
this.marked = marked;
}
}).call(this);

@@ -5,6 +5,7 @@ {

"author": "Christopher Jeffrey",
"version": "0.0.1",
"version": "0.0.2",
"main": "./lib/marked.js",
"bin": { "marked": "./bin/marked" },
"repository": "git://github.com/chjj/marked.git",
"keywords": [ "markdown", "markup" ]
}
}

@@ -8,6 +8,8 @@ # marked

$ node test/bench
marked: 6260ms
showdown: 21665ms
markdownjs: 69168ms
``` bash
$ node test/bench
marked: 6260ms
showdown: 21665ms
markdownjs: 69168ms
```

@@ -22,13 +24,19 @@ The point of marked was to create a markdown compiler where it was possible to

$ npm install marked
``` bash
$ npm install marked
```
## Usage
var marked = require('marked');
console.log(marked('i am using __markdown__.'));
``` js
var marked = require('marked');
console.log(marked('i am using __markdown__.'));
```
You also have direct access to the lexer and parser if you so desire.
var tokens = md.lexer(str);
console.log(md.parser(tokens));
``` js
var tokens = marked.lexer(str);
console.log(marked.parser(tokens));
```

@@ -44,4 +52,2 @@ ## Todo (& notes to self)

be possible.
- Write actual rules for inline markup (links, em, strong, etc). Currently,
only blocks are tokenized.
- Possibly add some

@@ -56,5 +62,3 @@ [ReMarkable](http://camendesign.com/code/remarkable/documentation.html)

- Add an explicit pretty printing and minification feature.
- Handle escaping of HTML entities better.
- Client-side compatibility.
I've still just begun to write this. I expect I will be updating it frequently.
I've still just begun to write this. I expect I will be updating it frequently.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc