Giter Site home page Giter Site logo

jonschlinkert / remarkable Goto Github PK

View Code? Open in Web Editor NEW
5.7K 92.0 369.0 1.5 MB

Markdown parser, done right. Commonmark support, extensions, syntax plugins, high speed - all in one. Gulp and metalsmith plugins available. Used by Facebook, Docusaurus and many others! Use https://github.com/breakdance/breakdance for HTML-to-markdown conversion. Use https://github.com/jonschlinkert/markdown-toc to generate a table of contents.

Home Page: https://jonschlinkert.github.io/remarkable/demo/

License: MIT License

JavaScript 99.39% Makefile 0.61%
commonmark gfm markdown parser md syntax-highlighting nodejs javascript markdown-parser node

remarkable's Introduction

remarkable

Build Status NPM version jsDelivr Hits Coverage Status

Markdown parser done right. Fast and easy to extend.

Live demo


Install

node.js:

npm install remarkable --save

browser (CDN):

Usage

import { Remarkable } from 'remarkable';
var md = new Remarkable();

console.log(md.render('# Remarkable rulezz!'));
// => <h1>Remarkable rulezz!</h1>

or with commonjs

const { Remarkable } = require('remarkable');
var md = new Remarkable();

console.log(md.render('# Remarkable rulezz!'));
// => <h1>Remarkable rulezz!</h1>

If installed globally with npm:

cat myfile.md | remarkable
remarkable --file myfile.md

# get options
remarkable -h

Documentation

See the docs directory for documentation on the following topics:

Options

By default, remarkable is configured to be similar to GFM, but with HTML disabled. This is easy to change if you prefer different settings.

There are two ways to define options.

constructor

Define options in the constructor:

// Actual default values
var md = new Remarkable({
  html:         false,        // Enable HTML tags in source
  xhtmlOut:     false,        // Use '/' to close single tags (<br />)
  breaks:       false,        // Convert '\n' in paragraphs into <br>
  langPrefix:   'language-',  // CSS language prefix for fenced blocks

  // Enable some language-neutral replacement + quotes beautification
  typographer:  false,

  // Double + single quotes replacement pairs, when typographer enabled,
  // and smartquotes on. Set doubles to '«»' for Russian, '„“' for German.
  quotes: '“”‘’',

  // Highlighter function. Should return escaped HTML,
  // or '' if the source string is not changed
  highlight: function (/*str, lang*/) { return ''; }
});

console.log(md.render('# Remarkable rulezz!'));
// => <h1>Remarkable rulezz!</h1>

.set

Or define options via the .set() method:

import { Remarkable } from 'remarkable';

var md = new Remarkable();

md.set({
  html: true,
  breaks: true
});

Note: To achieve the best possible performance, don't modify a Remarkable instance on the fly. If you need multiple configurations, create multiple instances and initialize each with a configuration that is ideal for that instance.

Presets

Remarkable offers some "presets" as a convenience to quickly enable/disable active syntax rules and options for common use cases.

commonmark

Enable strict CommonMark mode with the commonmark preset:

import { Remarkable } from 'remarkable';
var md = new Remarkable('commonmark');

full

Enable all available rules (but still with default options, if not set):

import { Remarkable } from 'remarkable';
var md = new Remarkable('full');

// Or with options:
var md = new Remarkable('full', {
  html: true,
  typographer: true
});

Syntax highlighting

Apply syntax highlighting to fenced code blocks with the highlight option:

import { Remarkable } from 'remarkable';
import hljs from 'highlight.js' // https://highlightjs.org/

// Actual default values
var md = new Remarkable({
  highlight: function (str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(lang, str).value;
      } catch (err) {}
    }

    try {
      return hljs.highlightAuto(str).value;
    } catch (err) {}

    return ''; // use external default escaping
  }
});

Syntax extensions

Enabled by default:

Disabled by default:

  • <sup> - 19^th^
  • <sub> - H~2~O
  • abbreviations
  • <ins> - ++inserted text++ (experimental)
  • <mark> - ==marked text== (experimental)

HEADS UP!: Experimental extensions can be changed later for something like Critic Markup, but you will still be able to use old-style rules via external plugins if you prefer.

Manage rules

var md = new Remarkable();
md.inline.ruler.enable([ 'ins', 'mark' ]);
md.block.ruler.disable([ 'table', 'footnote' ]);

// Enable everything
md = new Remarkable('full', {
  html: true,
  typographer: true,
});

//
// Manually enable rules, disabled by default:
//
var md = new Remarkable();
md.core.ruler.enable([
  'abbr'
]);
md.block.ruler.enable([
  'footnote',
  'deflist'
]);
md.inline.ruler.enable([
  'footnote_inline',
  'ins',
  'mark',
  'sub',
  'sup'
]);

Typographer

Although full-weight typographical replacements are language specific, remarkable provides coverage for the most common and universal use cases:

import { Remarkable } from 'remarkable';
var md = new Remarkable({
  typographer: true,
  quotes: '“”‘’'
});

// Disable rules at all:
md.core.ruler.disable([ 'replacements', 'smartquotes' ]);

// Actual default replacements:
//
// '' → ‘’
// "" → “”. Set '«»' for Russian, '„“' for German, empty to disable
// (c) (C) → ©
// (tm) (TM) → ™
// (r) (R) → ®
// +- → ±
// (p) (P) -> §
// ... → … (also ?.... → ?.., !.... → !..)
// ???????? → ???, !!!!! → !!!, `,,` → `,`
// -- → &ndash;, --- → &mdash;
//

Of course, you can also add your own rules or replace the defaults with something more advanced or specific to your language.

Plugins

Easily load plugins with the .use() method:

var md = new Remarkable();

md.use(plugin1)
  .use(plugin2, opts)
  .use(plugin3);

Please refer to the plugin documentation to create your own plugins.

linkify plugin

Autoconvert URL-like text to links

import { Remarkable } from 'remarkable';
import { linkify } from 'remarkable/linkify';

var md = new Remarkable().use(linkify);

UMD

UMD bundle provides linkify out of the box

const { Remarkable, linkify, utils } = window.remarkable;

References / Thanks

Big thanks to John MacFarlane for his work on the CommonMark spec and reference implementations. His work saved us a lot of time during this project's development.

Related Links:

  1. https://github.com/jgm/CommonMark - reference CommonMark implementations in C & JS, also contains latest spec & online demo.
  2. http://talk.commonmark.org - CommonMark forum, good place to collaborate developers' efforts.

Development / Modification

Parser consists of several responsibility chains filled with rules. You can reconfigure any of them as you wish. Renderer also can be modified and extended. See source code to understand details. Pay attention to these properties:

Remarkable.core
Remarkable.core.ruler
Remarkable.block
Remarkable.block.ruler
Remarkable.inline
Remarkable.inline.ruler
Remarkable.renderer
Remarkable.renderer.rules

Benchmark

Here is result of CommonMark spec parse at Core i5 2.4 GHz (i5-4258U):

$ benchmark/benchmark.js spec
Selected samples: (1 of 27)
 > spec

Sample: spec.txt (110610 bytes)
 > commonmark-reference x 40.42 ops/sec ±4.07% (51 runs sampled)
 > current x 74.99 ops/sec ±4.69% (67 runs sampled)
 > current-commonmark x 93.76 ops/sec ±1.23% (79 runs sampled)
 > marked-0.3.2 x 22.92 ops/sec ±0.79% (41 runs sampled)

As you can see, remarkable doesn't pay with speed for its flexibility. Because it's written in monomorphic style and uses JIT inline caches effectively.

Authors

License

MIT

remarkable's People

Contributors

akaroml avatar akuma avatar bcbcb avatar danielpclin avatar denis-sokolov avatar dohliam avatar dominykas avatar joeybaker avatar jonschlinkert avatar kasperpeulen avatar leeyeh avatar lemoinem avatar leonaves avatar loveencounterflow avatar lparry avatar lukasdrgon avatar lukehorvat avatar maruilian11 avatar mathiasbynens avatar matthewmueller avatar medikoo avatar nikolas avatar pdehaan avatar rentzsch avatar rlidwka avatar shockey avatar sumito3478 avatar tmcw avatar tombyrer avatar trysound 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  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

remarkable's Issues

repo to-dos

  • migrate tests (use should instead of chai - okay with you @puzrin?)
  • migrate issues

Docs generation

  1. Any preferences for code comments style and so on? We use ndoc but it's not well known. I don't like thinks like js-doc, because it does not allow to write examples.
  2. Need advices on how to split info:
    • readme (i'd prefer to keep is small, with only key points & quick start sample)
    • examples (is it needed if we have live demo?)
    • live demo (how to make it easy to use)
    • internals api docs (is it needed if we have live demo and well commented code?)

Sort out remarked fixtures

@jonschlinkert , i've experimented with different test data, and it seems more productive to continue with remarked tests. Problem is, that they all are unsorted and placed in one folder.

Could you split those by folder, like stmd done? First level is package + mode, then categories with files.

Example:

  • test/fixtures/remarked/headers/atx.md
  • test/fixtures/remarked_pedantic/code/...
  • test/fixtures/remarked_no_tables/code/...

Demo - add sync scrolling

Depends on #36

It would be nice if right half of demo window change position automatically, when user scroll left half.

How should it work:

  1. If user scroll source, html should be scrolled with precision of block elements
  2. if user scroll html, source should stay intact.
  3. If user clicks on html result, left part should scroll to appropriate position.
  4. Source string can be long and take multiple lines. That should be calculated properly. For example, via ace editor (or with phantom container + div-s with the same style as text)

HTML - what features required and why?

I need examples, when you need add HTML to markdown in real life. "Unlimited" html support is not a problem, but requires separate validator, to protect result from security vulnerabilities. That's too complex for smart projects, where only restricted subset of html requred.

Here is attempt to categorize real requirements, to design restricted mode. In remarked i've seen big list of simple tags. But don't know are those really needed or added just because someone expected that "it could be useful sometime". Or for crazy marketing acheivements like "this parser supports 100500 tags!!!!111!!!1" :)

PS. I remember, that promissed to add block macros, to support things like spoilers, uml diagrams and other things. And here we need to check, if you use HTML just because of poor parser extendability, of for some other reasons.

feature wishlists

from jonschlinkert/remarked#12 (comment)


upd by @puzrin:

No questions! No discussions! Only feature name + link to details. This issue is used by devs to keep archtecture in sync with possible needs. If you wish to discuss any feature - just create new a ticket.

Inlines parse: refactor emphasis

The last really bad place in remarkable is token pairs matching in emphasis / strikethrough and so on.

  • do better algorithm
  • make sure rules code is not close coupled
  • make sure markup pairs are extendable (will add sub / sup / ins very soon)

Problem is, that some tokens can have multiple meaning and require lookahead to determine exact value. Solution is to scan such tokens in light mode first, to find how to split input data.

Add sourcemap info (line numbers?)

AFAIK this feature is only required for sync scroll. To reduce complecity, we can add only line numbers to blocks. If someone wish precision up to columt and values for inline tags - PR is welcome.

Suggested property:

lines: [begin, end + 1]

Perf: need more effective maxNesting termination

example

This example cause significant freeze in demo. Probably, we need more effective termination when maxNesting exceeded. I'm not sure, if anyone really need correct output for such case. May be, it's better to dump inline as pure text.

website: comparison

Add a comparison of remarkable to marked, auto-generated from the unit tests/benchmarks. I'll work on this, not sure of the most effective approach. @puzrin thoughts?

Release 1.1.0 tail

  • StateBlock - try to replace binary flags with parent (string)
  • Optimize loose rendering - try to add loose property to paragraph
  • Add lines ranges

perf: try to use positional search instead of string splits

That's only assumption, and I’m uncertain if it can do things faster.

Strings & regexps allow to define base offset for search:

  • String.indexOf(pattern, startOffset)
  • RegExp.lastIndexOf + RegExp.exec()

Try if it do things better, if we use offset instead of slice. Need to update benchmark samples first.

benchmarks

In the benchmarks, we should change the word current to remarkable and current-commonmark to remarkable-commonmark so that anyone who does screen captures or posts those results will see the actual project name.

Smartypants logic

Logic in marked is too simple. For example, it will fail with such case "monitor 21"". Try something better.

References:

Full list: http://rmcreative.ru/blog/post/vse-tipografy

Note:

  • JS regex-es do not support unicode!!!
  • consider if we can implement logic without letter classes
  • Full unicode support xregex takes 24kb gzipped, not acceptable (remarked now takes 22kb gzipped, mostly because of entities).
  • consider if we can compile required ranges for our rules
  • (!) consider simple logic for core and leave advanced for plugin.

Autoreplacer design

This component works ONLY with text nodes. Common tasks:

  • autoreplace links & emails
  • autoreplace smiles
  • typorgaph (replace quotes, (c), ->, ...)
  • ??? simple inline macros

Limitations:

  • markup in source not allowed (only pure text)
  • macros must guarantee valid self-closing html markup

Advantage:

  • significant parser simplification
  • no complex regexps

Questions:

  • how to avoid interleaving ranges, if multiple patterns found (the most stupid way - recursive parse avter each match)
  • do we need "nestable" rules (like copyright sign in quotes)?
  • interface to add/remove rules
  • is it enougth for inline macros? Example: $$mathjax$$ <- content can be escaped, we should unescape it back or process such macros on parse stage.

Linkifier incorrectly composing links (w/ example)

Hard for me to actually determine why this is happening, but I am seeing Remarkable not compose a detected link properly.

The problematic string is: (www.example.org版权所有,如需转载,注明出处)

After being parsed by Remarkable, the resulting output is:

<p>(www.example.org版权所有,如需转载,注明出处<a href="http://www.example.org">http://www.example.org</a>如需转载,注明出处)</p>

Please note the repeated text.

I have determined that the problem does not lie with Autolinker:

> autolinker.link('(www.example.org版权所有,如需转载,注明出处)')
'(<a href="http://www.example.org" target="_blank">example.org</a>版权所有,如需转载,注明出处)'

P.S. For ease of debugging, this also happens w/ Latin characters: (www.example.orgabcabc, defdef, ghighi)

Example of Custom Rule, and appropriate renderer.

Please, make an example of writing custom rule and renderer.
Say I want to render: %[Video](http://youtu.be/mUJ6TOv2LAM?list=PLrzrNeNx3kNHsaPfrpPo0AlW-MhJE6gOA)
As an iframe tag.
Just an example with a deep explanation.
Need it so much!

token stream & ast - design notes.

"clasic" parser design has several abstraction layers (http://stackoverflow.com/a/380487).

We MUST have internal representation, to strictly separate rendering and parse stages. Problem is to select AST or event (token) stream. AST is more convenient for renderer, but event stream is more convenient for optimizations. In theory, we should have both... but let's try to cheat for speed :)

  • design tokens format. Something like:
    • [children]
    • (image, text node)
  • design stacked events rollback, then unclosed tokens detected
  • check that renderer is ok with event stream
  • make shure inline text chars are scanned fast
  • try to add AST generation phase and benchmark performance loss

Release 1.0.0 queue

  • remove [ backtracking in links/defs
  • smartypants.
  • tables review
  • tests
    • smartypants
    • pending remarked (regression branch)
  • docs/demo update & english check

API: `.set()`

@puzrin, unless set will be doing more than options handling. perhaps we should consider using .option() instead?

e.g.

remarked.option('xhtml', true);
// or
remarked.option({
  codeLangPrefix: 'language-',
  xhtml: true
});

this feels more natural IMHO

Link validator - what do you need ?

Stmd spec allow too many freedom in link format. Also, it doesn't require to check // after http:// and other things.

I think, that's all not secure, and we need more restrictions (by default or not). My personal needs are:

  • http://
  • https://
  • ftp://
  • // for ssl-safe http/https links
  • option to disable relative links

Please, post real examples, what you really need to be supported, if i missed something.

I not yet decided, if that will be an option or something else, on or off by default. Waiting fo your feedback. Examples from real are preferred.

Perf: linkifier + typographer

Current linkifier & typographer calls significantly reduce performance (2..3x times). Not a big deal, but would be interesting to improve.

front matter

per #2 (comment)

Jekyll has a great thing called front-matter which makes it a sane process to use Markdown files as the structure of a document.

I vote no on this. This is something that should not be in a markdown parser. I've published a number of front matter libs, including: https://github.com/jonschlinkert/gray-matter, it's a core feature assemble and verb, and @puzrin did js-yaml, which is probably used by the majority of front matter libs.

Track recursion level

This is note for future, when architecture become stable.

Remarkable has recursive subcalls. It's possible to form input, that will cause deep recursion and eat resources or cause exception on "stack overflow". There should be hard limit for such case. On practice, nobody needs nesting > 10. Also, no needs to make it tunable option, this can be hardcoded.

plugin: table of contents (toc)

TOC generation is something that should be done with a remarkable plugin, not supported directly.

There are so many different approaches to implementing a table of contents, with so many different options, I'd rather focus on making it easier for implementors to create their own TOC plugins for remarkable.

@puzrin thoughts? feel free to close this when you have a decision.

Allow unicode output ?

I don't know, is it universal, but in modern web it looks strange to use thinkgs like &#37 instead of direct chars. Such solutions were used for 2 reasons:

  • easy typing
  • help to poor regexp-based parsers (avoid collisions)

I think, it would be safe to add options { unicode: true } to automatically convert such thins to direct chars. This option will be on by default, and:

  • convert all valid digital codes (except < 0x20) to chars
  • convert all known html entities (like ©) to chars. Exclusion is for <, > and may be ".

Any objections? If someone wish old legacy bulletprof output, he can turn this option off.

gfm: del

Related to: #11 (comment)

Fixture:

hello ~~hi~~ world

Rendering comparison:

remarked

<p>hello <del>hi</del> world</p>

remarkable

<p>hello ~~hi~~ world</p>

Assuming we are supporting gfm, my vote is that the remarked result is correct.

tables: pipe chars ("|") in cells

example

First  | Second 
------ | ------
cell 1 | cell 2
qweqrt | find &#124; grep "test"
qweqrt | find \| grep "test"
qweqrt | `find &#124; grep "test"` second column
qweqrt | `find \| grep "test"` second column
qweqrt | `find | grep "test"` second column

There are no way to easy define | in table cells.

html limitations

Correct html support without restrictions requires full featured html parser. That will do thing to complex. I suggest reasonable limitation, which should simplify lexer design:

  • html tags can not cross single markdown block
    • Example: if you have complex html markup, it should not contain empty lines
  • on block end not closed tags will be auto-closed automatically
  • other complex things like collapsable spoilers can be implemented via block macros

Questions:

  1. Is it enougth? Do anyone has example, when html tags should contain multiple markdown blocks?
  2. Is auto-close policy ok or should we use auto- escape unmatched tags to show as text?

gfm: links

Related to: #11 (comment)

Fixture:

This should be a link: http://example.com/hello-world.

Rendering comparison:

remarked

<p>This should be a link: <a href="http://example.com/hello-world">http://example.com/hello-world</a>.</p>

remarkable

<p>This should be a link: http://example.com/hello-world.</p>

Assuming we are supporting gfm, my vote is that the remarked result is correct.

Perhaps this could be a series of tools that live under one umbrella

I see all this great work going on and what looks to be a fantastic parser built for speed. After watching the "CommonMark" project for a while I can see that the JavaScript implementation is neglected. I wonder if it makes sense to keep the parser itself only focused on evolving specification. Things like on/off HTML still make sense.

Rather than trying to make the core of this accommodate all of the peripheral use cases, start another project that is designed to daisy chain all these ideas together. Then you could have a project for Macros, a project for Meta-data and so on. Think of it as assemble.io for parsing a single block of text.

I'd love using something like that :)

Live demo

Probably, we need to provide live demo, like js-yaml does http://nodeca.github.io/js-yaml/ . There can be different code snippets & editable pre-filled examples. Users like, when they can touch result with hands :)

Any ideas about content?

"linkify" only functions if "typographer" is also enabled

It seems url-like text is not linkified unless typographer is enabled.

If the settings hash is:

{
    'html': false,
    'xhtmlOut': true,
    'breaks': true,
    'langPrefix': 'language-',
    'linkify': true,
    'typographer': false
}

Linkification of urls does not work, but if typographer is set to true, it works fine.

Macros

Except custom extentions, which can change everything, it would be nice to have generic syntax for marcos. Because that will simplify adding new commands with minimal efforts.

Now it's easy to modufy ``` behavior (write custom renderer), but that's not enougth:

  • those can not be nested (to be precise, only 2-level nesting allowed, with ``` + ~~~)
  • those can have params on block mode only

What we need:

  1. block macro. Example - spoiler, math formula, diagram, sidebar and so on.
  2. inline macro. Example - inline formula
  3. ??? (don't know) self-closed block. Example - blog entry cut marker
  4. ??? (don't know) self-closed inline element. Example - don't know.

(3,4) are under very big question, and can be done via autoreplacer. For example. <cut> -> <!--cut-->

Feel free to suggest alternate formats. Just post your example, or link to implementation or discussion in other repo. If you don't like existing example - just suggest a better one, to be constructive


Draft

block macro

Generic form:

!!:name <anything, used as params>
...
... content ...
...
!!
  • it can be nested
  • unknown macro name or unmanched closing pair will be rendered as simple markdown text.

Example 1:

!!:spoiler Click me to expand
content
!!

Example 2:

!!:float left
content
!!

inline macro

TBD. Still no ideas about good human-readable form

See https://github.com/jonschlinkert/markdown-symbols . Probably, inline macro do not need name-based approach, and will be ok with custom delimiters for each case.

Top level API design

Suggestion: no global singletons - that's a great way to fuckup everything.

var Remarkable = require('remarkable');
var remarkable = new Remarkable(/* options */);

// change instance options
remarkable.set(/* options */ /*, reset */); // reset = true -> disable everything else
  • Do we need call without new? (i think not)
  • Do we need to export Lexer, Parser & Renderer classes? User can modify local instances via properties of remarkable exemplar.

Options:

{
  blocksep: '\n',   // ?
  innersep: '\n',   // ?
  softbreak: '\n',  // ?
  langprefix: 'language-', // css prefix for fenced code blocks 
  xhtml: false,     // ? <hr /> instead or <hr>
  html: false       // disable html blocks/tags by default
}

1.1.1+ Batch

  • Plugins examples / tutorials #48
  • Demo synk scroll #37
  • CDN #33
  • Advice migration to remarkable. You know where :) #34

These tickets are the most significant to make remarkable "solid".

Improve loose/tight paragraphs logic

Loose/Tight paragraph logic now stay in renderer. Not critical but dirty.

It's better to set tight markers directly to paragraph tokens, after list generation. Also remove appropriate flags from list tokens.

Is browser build size significant?

Current size is 24K gzipped. If it's critical - it's possible to reduce (code for node and browser will be different):

  1. Decode named entities via textarea -> 16K gzipped
    • Remove autolinker or make it more stupid (simple regex) -> 12.3K gzipped

Entity decode for browser:

var ta;

function decodeEntities(input) {
  ta = ta || document.createElement('textarea');
  ta.innerHTML = input;
  return y.value;
}

Thechnically - move decode fn to separate file & define replacement rule for browserify

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.