Skip to content

Commit

Permalink
add emoji parsing support to gfm
Browse files Browse the repository at this point in the history
added 'emoji' option (disabled by default)
expanded InlineLexer to look for delimited :emoji: codes
added support for multiple option values (boolean-ish, function, string)
documented option in README.md
closes markedjs#233
  • Loading branch information
Bartvds committed Jan 29, 2014
1 parent 613bf6a commit 640f829
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 1 deletion.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,34 @@ Default: `false`

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

### emoji

Type: `Boolean` / `String` / `Function`
Default: `false`

Enable replacement of colon-delimited Emoji emoticon codes like `:warning:` or `:+1:`. This option requires the `gfm` option to be true. :octocat:

* `String`: parsed as template for the replacement value, accepts the `{emoji}` variable.
* `true`: use the default <img> with a local URL prefix.
* `Function`: called with each emoji code, must return a replacement string like an <img> or <span> tag. Don't forget to use `escape(emoji)` or `encodeURIComponent(emoji)` where needed.

```js
marked.setOptions({
emoji: function (emoji) {
return '<span data-emoji="' + emoji + '"></span>';
}
});
```

The default template:

````
<img src="/graphics/emojis/warning.png" alt=":warning:" title=":warning:"
class="emoji" align="absmiddle" height="20" width="20">`
````

:warning: The images for the emoji set used by GitHub can be found [in the repos](https://github.com/arvida/emoji-cheat-sheet.com/tree/master/public/graphics/emojis) of the [emoji-cheat-sheet](http://www.emoji-cheat-sheet.com/). :point_left::+1:

## Access to lexer and parser

You also have direct access to the lexer and parser if you so desire.
Expand Down
55 changes: 54 additions & 1 deletion lib/marked.js
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ var inline = {
code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
br: /^ {2,}\n(?!\s*$)/,
del: noop,
emoji: noop,
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
};

Expand Down Expand Up @@ -491,8 +492,9 @@ inline.gfm = merge({}, inline.normal, {
escape: replace(inline.escape)('])', '~|])')(),
url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
del: /^~~(?=\S)([\s\S]*?\S)~~/,
emoji: /^:([A-Za-z0-9_\-\+]+?):/,
text: replace(inline.text)
(']|', '~]|')
(']|', ':~]|')
('|', '|https?://|')
()
});
Expand Down Expand Up @@ -531,6 +533,8 @@ function InlineLexer(links, options) {
} else if (this.options.pedantic) {
this.rules = inline.pedantic;
}

this.emojiTemplate = getEmojiTemplate(options);
}

/**
Expand Down Expand Up @@ -661,6 +665,13 @@ InlineLexer.prototype.output = function(src) {
continue;
}

// emoji (gfm)
if (cap = this.rules.emoji.exec(src)) {
src = src.substring(cap[0].length);
out += this.emoji(cap[1]);
continue;
}

// text
if (cap = this.rules.text.exec(src)) {
src = src.substring(cap[0].length);
Expand Down Expand Up @@ -690,6 +701,47 @@ InlineLexer.prototype.outputLink = function(cap, link) {
: this.renderer.image(href, title, escape(cap[1]));
};

/**
* Emoji Transformations
*/

function emojiDefaultTemplate(emoji) {
return '<img src="'
+ '/graphics/emojis/'
+ encodeURIComponent(emoji)
+ '.png"'
+ ' alt=":'
+ escape(emoji)
+ ':"'
+ ' title=":'
+ escape(emoji)
+ ':"'
+ ' class="emoji" align="absmiddle" height="20" width="20">';
}

function getEmojiTemplate(options) {
if (options.emoji) {
if (typeof options.emoji === 'function') {
return options.emoji;
}

if (typeof options.emoji === 'string') {
var emojiSplit = options.emoji.split(/\{emoji\}/g);
return function(emoji) {
return emojiSplit.join(emoji);
}
}
}
return emojiDefaultTemplate;
}

InlineLexer.prototype.emojiTemplate = emojiDefaultTemplate;
InlineLexer.prototype.emoji = function (name) {
if (!this.options.emoji) return ':' + name + ':';

return this.emojiTemplate(name);
};

/**
* Smartypants Transformations
*/
Expand Down Expand Up @@ -1208,6 +1260,7 @@ marked.setOptions = function(opt) {

marked.defaults = {
gfm: true,
emoji: false,
tables: true,
breaks: false,
pedantic: false,
Expand Down
1 change: 1 addition & 0 deletions test/new/gfm_emoji.emoji.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>note: we <img src="/graphics/emojis/heart.png" alt=":heart:" title=":heart:" class="emoji" align="absmiddle" height="20" width="20"> marked</p>
1 change: 1 addition & 0 deletions test/new/gfm_emoji.emoji.text
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
note: we :heart: marked
1 change: 1 addition & 0 deletions test/tests/gfm_emoji.emoji.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>note: we <img src="/graphics/emojis/heart.png" alt=":heart:" title=":heart:" class="emoji" align="absmiddle" height="20" width="20"> marked</p>
1 change: 1 addition & 0 deletions test/tests/gfm_emoji.emoji.text
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
note: we :heart: marked

0 comments on commit 640f829

Please sign in to comment.