Giter VIP home page Giter VIP logo

kramed's Introduction

kramed

A full-featured markdown parser and compiler, written in JavaScript. Built for speed.

NPM version Build Status

Install

npm install kramed --save

Why fork marked ?

marked hasn't been evolving as much as it could be lately and due to our needs with GitBook, we need features such as robust mathjax support and want to strive closer to the rising kramdown standard.

Usage

Minimal usage:

var kramed = require('kramed');
console.log(kramed('I am using __markdown__.'));
// Outputs: <p>I am using <strong>markdown</strong>.</p>

Example setting options with default values:

var kramed = require('kramed');
kramed.setOptions({
  renderer: new kramed.Renderer(),
  gfm: true,
  tables: true,
  breaks: false,
  pedantic: false,
  sanitize: true,
  smartLists: true,
  smartypants: false
});

console.log(kramed('I am using __markdown__.'));

kramed(markdownString [,options] [,callback])

markdownString

Type: string

String of markdown source to be compiled.

options

Type: object

Hash of options. Can also be set using the kramed.setOptions method as seen above.

callback

Type: function

Function called when the markdownString has been fully parsed when using async highlighting. If the options argument is omitted, this can be used as the second argument.

Options

highlight

Type: function

A function to highlight code blocks. The first example below uses async highlighting with node-pygmentize-bundled, and the second is a synchronous example using highlight.js:

var kramed = require('kramed');

var markdownString = '```js\n console.log("hello"); \n```';

// Async highlighting with pygmentize-bundled
kramed.setOptions({
  highlight: function (code, lang, callback) {
    require('pygmentize-bundled')({ lang: lang, format: 'html' }, code, function (err, result) {
      callback(err, result.toString());
    });
  }
});

// Using async version of kramed
kramed(markdownString, function (err, content) {
  if (err) throw err;
  console.log(content);
});

// Synchronous highlighting with highlight.js
kramed.setOptions({
  highlight: function (code) {
    return require('highlight.js').highlightAuto(code).value;
  }
});

console.log(kramed(markdownString));

highlight arguments

code

Type: string

The section of code to pass to the highlighter.

lang

Type: string

The programming language specified in the code block.

callback

Type: function

The callback function to call when using an async highlighter.

renderer

Type: object Default: new Renderer()

An object containing functions to render tokens to HTML.

Overriding renderer methods

The renderer option allows you to render tokens in a custom manor. Here is an example of overriding the default heading token rendering by adding an embedded anchor tag like on GitHub:

var kramed = require('kramed');
var renderer = new kramed.Renderer();

renderer.heading = function (text, level) {
  var escapedText = text.toLowerCase().replace(/[^\w]+/g, '-');

  return '<h' + level + '><a name="' +
                escapedText +
                 '" class="anchor" href="#' +
                 escapedText +
                 '"><span class="header-link"></span></a>' +
                  text + '</h' + level + '>';
},

console.log(kramed('# heading+', { renderer: renderer }));

This code will output the following HTML:

<h1>
  <a name="heading-" class="anchor" href="#heading-">
    <span class="header-link"></span>
  </a>
  heading+
</h1>

Block level renderer methods

  • code(string code, string language)
  • blockquote(string quote)
  • html(string html)
  • heading(string text, number level)
  • hr()
  • list(string body, boolean ordered)
  • listitem(string text)
  • paragraph(string text)
  • table(string header, string body)
  • tablerow(string content)
  • tablecell(string content, object flags)

flags has the following properties:

{
    header: true || false,
    align: 'center' || 'left' || 'right'
}

Inline level renderer methods

  • strong(string text)
  • em(string text)
  • codespan(string code)
  • br()
  • del(string text)
  • link(string href, string title, string text)
  • image(string href, string title, string text)

gfm

Type: boolean Default: true

Enable GitHub flavored markdown.

tables

Type: boolean Default: true

Enable GFM tables. This option requires the gfm option to be true.

breaks

Type: boolean Default: false

Enable GFM line breaks. This option requires the gfm option to be true.

pedantic

Type: boolean Default: false

Conform to obscure parts of markdown.pl as much as possible. Don't fix any of the original markdown bugs or poor behavior.

sanitize

Type: boolean Default: false

Sanitize the output. Ignore any HTML that has been input.

smartLists

Type: boolean Default: true

Use smarter list behavior than the original markdown. May eventually be default with the old behavior moved into pedantic.

smartypants

Type: boolean Default: false

Use "smart" typograhic punctuation for things like quotes and dashes.

Access to lexer and parser

You also have direct access to the lexer and parser if you so desire.

var tokens = kramed.lexer(text, options);
console.log(kramed.parser(tokens));
var lexer = new kramed.Lexer(options);
var tokens = lexer.lex(text);
console.log(tokens);
console.log(lexer.rules);

CLI

$ kramed -o hello.html
hello world
^D
$ cat hello.html
<p>hello world</p>

Philosophy behind kramed

The point of kramed was to create a markdown compiler where it was possible to frequently parse huge chunks of markdown without having to worry about caching the compiled output somehow...or blocking for an unnecesarily long time.

kramed is very concise and still implements all markdown features. It is also now fully compatible with the client-side.

kramed more or less passes the official markdown test suite in its entirety. This is important because a surprising number of markdown compilers cannot pass more than a few tests. It was very difficult to get kramed as compliant as it is. It could have cut corners in several areas for the sake of performance, but did not in order to be exactly what you expect in terms of a markdown rendering. In fact, this is why kramed could be considered at a disadvantage in the benchmarks above.

Along with implementing every markdown feature, kramed also implements GFM features.

Benchmarks

node v0.8.x

$ node test --bench
kramed completed in 3411ms.
kramed (gfm) completed in 3727ms.
kramed (pedantic) completed in 3201ms.
robotskirt completed in 808ms.
showdown (reuse converter) completed in 11954ms.
showdown (new converter) completed in 17774ms.
markdown-js completed in 17191ms.

Kramed is now faster than Discount, which is written in C.

For those feeling skeptical: These benchmarks run the entire markdown test suite 1000 times. The test suite tests every feature. It doesn't cater to specific aspects.

Pro level

You also have direct access to the lexer and parser if you so desire.

var tokens = kramed.lexer(text, options);
console.log(kramed.parser(tokens));
var lexer = new kramed.Lexer(options);
var tokens = lexer.lex(text);
console.log(tokens);
console.log(lexer.rules);
$ node
> require('kramed').lexer('> i am using kramed.')
[ { type: 'blockquote_start' },
  { type: 'paragraph',
    text: 'i am using kramed.' },
  { type: 'blockquote_end' },
  links: {} ]

Running Tests & Contributing

If you want to submit a pull request, make sure your changes pass the test suite. If you're adding a new feature, be sure to add your own test.

The kramed test suite is set up slightly strangely: test/new is for all tests that are not part of the original markdown.pl test suite (this is where your test should go if you make one). test/original is only for the original markdown.pl tests. test/tests houses both types of tests after they have been combined and moved/generated by running node test --fix or kramed --test --fix.

In other words, if you have a test to add, add it to test/new/ and then regenerate the tests with node test --fix. Commit the result. If your test uses a certain feature, for example, maybe it assumes GFM is not enabled, you can add .nogfm to the filename. So, my-test.text becomes my-test.nogfm.text. You can do this with any kramed option. Say you want line breaks and smartypants enabled, your filename should be: my-test.breaks.smartypants.text.

To run the tests:

cd kramed/
node test

TODO

  • Refactor code to have greater modularity
  • Strive for kramdown compatibility (it's the new standard)
  • Improve, improve, improve ...

Contribution and License Agreement

If you contribute code to this project, you are implicitly allowing your code to be distributed under the MIT license. You are also implicitly verifying that all code is your original work. </legalese>

License

Marked: Copyright (c) 2011-2014, Christopher Jeffrey. (MIT License) Kramed: Copyright (c) 2014, Aaron O'Mullan. (MIT Licensed)

See LICENSE for more info.

kramed's People

Contributors

13protons avatar aarono avatar aepstein avatar apaleslimghost avatar briancavalier avatar chjj avatar chriswren avatar comuttun avatar fengmk2 avatar guybedford avatar ianstormtaylor avatar ifraixedes avatar isaacs avatar jasonkarns avatar juliantaylor avatar kitsonk avatar lepture avatar matsko avatar mikeal avatar minrk avatar mithgol avatar mkozhukh avatar moox avatar odbol avatar samypesse avatar selfcontained avatar session-zz avatar thejhh avatar wzr1337 avatar zaggino avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kramed's Issues

Outdated highlight example in README

The README says that this should be possible:

// Synchronous highlighting with highlight.js
kramed.setOptions({
  highlight: function (code) {
    return require('highlight.js').highlightAuto(code).value;
  }
});

console.log(kramed(markdownString));

but it's not (anymore).

As far as I can tell, the default Renderer instance doesn't get the updated options passed in any way. I'm currently using

var options = {
  renderer: new kramed.Renderer({
    highlight: code => hljs.highlightAuto(code).value,
  }),
};

console.log(kramed(markdownString, options));

Not sure whether the README version is still supposed to work or not, but it seems that I have to explicitly create a Renderer instance if I want to pass options to it (seems inconvenient), and pass it to kramed instead of calling setOptions.

Rendering the table in list

The following markdown text doesn't work:

1. this is a
   - this is b1

   | Name | age|
   |----  |----|
   | Tom  | 16 |

   - this is b2
   - this is b3

It should be rendered to:

  1. this is a

    • this is b1
    Name age
    Tom 16
    • this is b2
    • this is b3

The actual output is as follows

  1. this is a

    • this is b1

    | Name | age| |---- |----| | Tom | 16 |

    • this is b2
    • this is b3

related issue

markedjs/marked#1246

GitbookIO/gitbook#794

Inline scripts are not correctly processed

For example:

**Proof:** If <script type="math/tex; ">g</script> is concave, then <script type="math/tex; ">g(x)\\leq g(\\mu)+(x-\\mu)\'\\eta(\\mu),</script>
where <script type="math/tex; ">\\eta(\\mu)</script> is an arbitrary element of the
subgradient of ..

is returned as:

<p><strong>Proof:</strong> If <script type="math/tex; ">g</script> is concave, then <script type="math/tex; ">g(x)\leq g(\mu)+(x-\mu)\&#39;\eta(\mu),</script>
where <script type="math/tex; ">\eta(\mu)</script> is an arbitrary element of the
subgradient of ..</p>

(' is escaped in the script).

<script type="math/tex; ">g(x)\leq g(\mu)+(x-\mu)\&#39;\eta(\mu),</script> tag is processed as 2 tags (https://github.com/GitbookIO/kramed/blob/master/lib/lex/inline.js#L108), and its content is escaped

enclosing <p> tag

As stated in the README, the most basic example

var kramed = require('kramed');
console.log(kramed('I am using __markdown__.'))

spits out

<p>I am using <strong>markdown</strong>.</p> 

I'm puzzled why one should insert paragraph tags (<p>) here; I can find no such indication in the input string I am using __markdown__.. In fact, the added <p> tag makes it impossible for me to use kramed without a subsequent line break, so I'd like to cast my vote for removing it.

Inconsistency in heading linking

Consider:

#Hello World.

The id will be generated as hello-world and the link as hello-world- because of the dot I assume. In marked this works fine.

TypeError - Cannot call method 'toLowerCase' of undefined

I have been primarily using the web editor, so I am not sure what would cause this particular error. The first chapter of my book failed to build.

--Output dump--

Downloading source
Extracting source
GitBook version is 2.6.3
Tweaking book.json
Installing plugins
info: 2 plugins to install
info: No version specified, resolve plugin comment
info: install plugin comment from npm (gitbook-plugin-comment) with version 0.2.0
[email protected] node_modules/gitbook-plugin-comment
info: >> plugin comment installed with success
info: No version specified, resolve plugin autocover
info: install plugin autocover from npm (gitbook-plugin-autocover) with version 1.2.1
info: >> plugin autocover installed with success

Done, without error
Building Site, will upload
info: loading book configuration....OK
info: load plugin gitbook-plugin-comment ....OK
info: load plugin gitbook-plugin-autocover ....OK
info: load plugin gitbook-plugin-highlight ....OK
info: load plugin gitbook-plugin-search ....OK
info: load plugin gitbook-plugin-sharing ....OK
info: load plugin gitbook-plugin-fontsettings ....OK
info: >> 6 plugins loaded
info: start generation with website generator
info: clean website generatorOK

TypeError: Cannot call method 'toLowerCase' of undefined
Please report this to https://github.com/GitbookIO/kramed. (In file 'README.md')

Mathematics - display should be allowed within paragraphs

Yup. That sounds contradictory, but due to the fact that it is accepted to treat mathematics as part of sentences, it totally makes sense for mathematical equations, even display/block mathematics, to be inside a paragraph.

Have a look at the image in this page to get the idea:
http://superuser.com/questions/601042/how-to-insert-display-equations-in-a-word-document-without-breaking-a-paragraph

Here's a small discussion about it in MathJax google groups:
https://groups.google.com/forum/#!topic/mathjax-users/hnNmdpAm_4Q

From what I saw in kramed.js, it looks like you can only use double dollar signs $$ for maths delimiters: both display and inline, determined by whether it is separated from the paragraph or not. This could possibly be solved with/along with GitbookIO/plugin-mathjax#5.

Thanks!

parse_block_html is not supported

<div>

1. list1
2. list2
3. list3

</div>

is always parsed like <div>1. list1 2. list2 3. list3 </div> no matter what i do:
set parse_block_html: true to kramed options
or write {::options parse_block_html="true" /} in html code before the opening div.

Very poor implemetation of kramdown you have.

TypeError: Cannot call method 'toLowerCase' of undefined

Hi I'm getting the following error due building my book on gitbook

TypeError: Cannot call method 'toLowerCase' of undefined
Please report this to https://github.com/GitbookIO/kramed. (In file 'module_0x1__basic/README.md')

please advice

Kramdown Class Support

Classes are not being parsed from Kramdown:

This following kramdown:

> text content
{: .class1 .class2 }

should output:

<blockquote class="class1 class2">text content</blockquote>

but instead is outputting:

 <blockquote>text content {: .class1 .class2  }</blockquote>

It should set the classes on the preceding element and not include the markdown class declaration in the content.

On a possibly related note, I am still seeing issue #4 rendering incorrectly while using version 0.4.6.

Bulleted List and Numbered List merged

While writing using GitBook I wanted to have a numbered list and in one of the items have a list of bullet points. If they are writen at the same level numbered and bulleted get merged into a unique numbered list. As you can see in the next screenshot:

capture

A workaround for now is tab the bulleted list it will work correctly (just the style of the bullets is not the level 1 type).

Is this repo still alive?

no activity for 8 months but some of the open issues seemed to hint development would continue & address current limitations.

Can we expect development to continue or is this project abandoned? Cheers

convert links to footnotes

Add option so inline links are converted and rendered as footnotes. This would allow to show them when printing. Also, instead of just convert them as footnotes, they could be arranged in a structure and collected with other ones so GitBook could use it to create a bibliography appendix.

extension for symbolic links?

I've written a markup parser in the past (http://symplewiki.org, based on creole), and found it handy for users to be able to use symbolic links in place of references:

{{Pictures:mypicture.jpg | my awesome picture}} 

in kramed I presume this would be

![my awesome picture](Pictures:mypicture.jpg)

and for a link:

[[Documents:mydoc.xls | my spreadsheet]]

in kramed:

[my spreadsheet](Documents:mydoc.xls)

...whereby there is an internal (database) lookup and expansion of 'Pictures:' -> /uploads/images/ and 'Documents:'-> /uploads/documents/ (or whatever).

Is such a custom extension possible in kramed? it looks like it...

Blockquotes seem to incorrectly transform the insides into html

Given the following input markdown:

> Quote!
> - Quote speaker

The actual outputted kramed HTML is the following:

<blockquote>
  <p>Quote!</p>
  <ul>
   <li>Quote speaker</li>
  </ul>
</blockquote>

When Kramdown ends up outputting the following instead (what I would expect):

<blockquote>
  <p>Quote!<br>
  - Quote speaker</p>
</blockquote>

We've tried flipping the smartLists flag on and off without seeing any change in this behavior.

Identical headings output identical id's

The following Markdown will produce <h1> with identical ids. Maybe an internal counter should be kept:

Implementation
============

Implementation
============
<h1 id="implementation">Implementation</h1>
<h1 id="implementation">Implementation</h1>

latex not compatible with kramdown when $$ and $ in the same line

take a sample.md file with the below content

every $\beta_i$ under the basis $\alpha_1,\dots,\alpha_n$ have coordinate: $$\begin{pmatrix}
c_{1i} \\
c_{2i} \\
... \\
c_{ni}
\end{pmatrix}$$
transition matrix: $C=(C_{ij})_{n\times n}$

using kramed 0.5.5 we get

$ ./bin/kramed ../../tmp/sample.md 

<p>every $\beta<em>i$ under the basis $\alpha_1,\dots,\alpha_n$ have coordinate: $$\begin{pmatrix}
c</em>{1i} \
c<em>{2i} \
... \
c</em>{ni}
\end{pmatrix}$$
transition matrix: $C=(C<em>{ij})</em>{n\times n}$</p>

using kramdown 1.5 we get

$ kramdown sample.md

<p>every $\beta_i$ under the basis $\alpha_1,\dots,\alpha_n$ have coordinate: <script type="math/tex">\begin{pmatrix}
c_{1i} \\
c_{2i} \\
... \\
c_{ni}
\end{pmatrix}</script>
transition matrix: $C=(C_{ij})_{n\times n}$</p>

I could rewrite the $$ block in a new line instead but I do need some inline function. Hope this could be fixed.

Header ID's Parsing Behavior

Header ID parsing technically works, but there are missing details.

This input markdown:

#hi {#one}

Results in this markup:

<h1 id="hi-one-">hi {#one}</h1>

But I'd expect it to result in this:

<h1 id="one">hi</h1>

That is

  • remove the trailing hyphen hi-one- becomes hi-one
  • replace the header ID with the specified one instead of concatenating - one vs hi-one-
  • remove the attribute block {#one} from the resulting output

Support definition lists

Kramdown supports definition lists in this format:

Item
: Definition
: Definiton

Item
: Definition
: Defintion

This isn't supported in kramed, and incorrectly is parsed as:

<p>Item
: Def1
: Def2</p>
<p>Item2
: Def3</p>

Error with latex $||^$

I change default renderer to hexo-render-kramed and then change some render rules in node_modules\kramed\lib\rules\inline.js :

//  escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,
  escape: /^\\([`*\[\]()#$+\-.!_>])/,

//  em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
  em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

and I found there is a error when rendering latex code ||x||^2.
Is there any other way except using {||}^2 ?

Issue with table rendering

The table is followed by "\n"

var kramed = require('kramed');
console.log(kramed(`
| Name | Description | Profile |
| ---- | ----------- | ------- |
| format  | Specifies the input format. Returns the inserted archives in the same format. |  |
| token  | The token that allows you to use this API. |  |
| entity  | The entity objects (they must be valid, and may have profile dependent additional information). |  |
`));
Name Description Profile
format Specifies the input format. Returns the inserted archives in the same format.
token The token that allows you to use this API.
entity The entity objects (they must be valid, and may have profile dependent additional information).

see: GitbookIO/gitbook#1062

bower registration?

When including kramed into my bower.json,

"dependencies": {
  "kramed": "0.4.6"
}

I'm getting

bower kramed#0.4.6                           ENOTFOUND Package kramed not found

Has it been registered yet?

Also, it appears that the version in kramed's bower.json is somewhat outdated (0.4.6 vs. 0.5.1 in package.json).

Trailing space not preserved in inline codeblock

Markdown (note the space after \t):

It defaults to `\r\n\t `

Generated markup:

It defaults to <code>\r\n\t</code>

The whitespace got removed, although it should be protected because it's inside the code snippet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.