[ANN] remarkable - high speed markdown parser with pluggable syntax & CommonMark support

205 views
Skip to first unread message

Vitaly Puzrin

unread,
Oct 22, 2014, 11:35:20 PM10/22/14
to nod...@googlegroups.com
Demo: http://jonschlinkert.github.io/remarkable/demo/

Repo: https://github.com/jonschlinkert/remarkable


Everyone who tried to extend existing markdown js implementations can note, that all internal logic there is pinned with nails. That makes next to impossible to write extentions. You can patch output, but that can not guaranty correct html after processing. This can be solved by external html validators, but such solutions are heavy and possible on server only.

We decided to write a new project from scratch, to solve a lot of problems at once:

1. Users should not depend on package developpers. Parser should be extendable.
2. Flexibility should not cause speed loss.
3. Follow CommonMark spec.
4. Output should be good out of box, without additional processing.
5. Browser support :)

I think, result is interesting. All critical parts of `remarkable` are written in monomorphic style. Without sugar like "typorgafer" and "linkifier" speed is faster than in `marked` & `stmd.js` (and that's with not cheap plugins system). Also, if you don't like some extentions - it's possible to restrict processing rules by whitelist.

Now we are collecting users feedback.

Enjoy!

Tom Boutell

unread,
Oct 24, 2014, 8:27:25 AM10/24/14
to nod...@googlegroups.com
Neat, I'll have to look at this. Is there support for metadata? We currently use meta-marked for that feature, which allows YAML at the top of the file to be parsed when it appears between certain delimiters.

Alex Kocharin

unread,
Oct 24, 2014, 1:05:31 PM10/24/14
to nod...@googlegroups.com
 
Not by default. But you can add a rule there:
 
```js
var YAML = require('js-yaml')
 
module.exports = meta
 
function get(state, line) {
  var pos = state.bMarks[line]
  var max = state.eMarks[line]
  return state.src.substr(pos, max - pos)
}
 
function meta(state, start, end, silent) {
  if (start !== 0 || state.blkIndent !== 0) return false
  if (state.tShift[start] < 0) return false
  if (!get(state, start).match(/^---$/)) return false
 
  var data = []
  for (var line = start + 1; line < end; line++) {
    var str = get(state, line)
    if (str.match(/^---$/)) break
    if (state.tShift[line] < 0) break
    data.push(str)
  }
 
  if (line >= end) return false
 
  // or do whatever you want with it
  console.log(YAML.safeLoad(data.join('\n')))
 
  state.line = line + 1
  return true
}
```
 
 
24.10.2014, 19:00, "Tom Boutell" <t...@punkave.com>:
--
Job board: http://jobs.nodejs.org/
New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md
Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
---
You received this message because you are subscribed to the Google Groups "nodejs" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nodejs+un...@googlegroups.com.
To post to this group, send email to nod...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/e940c721-4eca-40e5-8f92-5939d64ee1d7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Vitaly Puzrin

unread,
Oct 24, 2014, 1:13:22 PM10/24/14
to nod...@googlegroups.com
Tom, metadata is a more high abstraction level. Remarked does parse, according to defined configuration (in you case that's generated from metadata).

You can write a wrapper, if needed. But it's a bit another task. We care about more generic problem - how to make syntax extention without ass pain and with guarantee of correct output.


пятница, 24 октября 2014 г., 16:27:25 UTC+4 пользователь Tom Boutell написал:

eugene

unread,
Nov 24, 2014, 6:09:47 AM11/24/14
to nod...@googlegroups.com, al...@kocharin.ru
Hi Alex, thanks for this code. 

I've published a remarkable plugin called 'remarkable-meta' that uses this code snippet as the basis (and given you credit!), and also added some tests as well.


Thought I'd post it here in case someone else goes a googling.

I've added it into the top of the parsing rules by going before 'code' (see https://github.com/eugeneware/remarkable-meta/blob/master/index.js#L5). Not sure if that's the nicest way, but it seems to work. Also, the meta data gets tacked onto the remarkable instance as the 'meta' property for easy access.

FWIW, there's a discussion going on in commonmark.org about standardising metadata: http://talk.commonmark.org/t/metadata-in-documents/721

Doesn't sound like there's much consensus at the moment, though!

Thanks for the inspiration!

Cheers,

Eugene
Reply all
Reply to author
Forward
0 new messages