Skip to content

Commit b11179d

Browse files
dwellemarijnh
authored andcommitted
[gfm mode] Add emoji rule
1 parent 99c8d8b commit b11179d

File tree

5 files changed

+37
-5
lines changed

5 files changed

+37
-5
lines changed

mode/gfm/gfm.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ CodeMirror.defineMode("gfm", function(config, modeConfig) {
115115
var markdownConfig = {
116116
taskLists: true,
117117
fencedCodeBlocks: '```',
118-
strikethrough: true
118+
strikethrough: true,
119+
emoji: true
119120
};
120121
for (var attr in modeConfig) {
121122
markdownConfig[attr] = modeConfig[attr];

mode/gfm/index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
<script src="../htmlmixed/htmlmixed.js"></script>
1616
<script src="../clike/clike.js"></script>
1717
<script src="../meta.js"></script>
18-
<style type="text/css">.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
18+
<style type="text/css">
19+
.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}
20+
.cm-s-default .cm-emoji {color: #009688;}
21+
</style>
1922
<div id=nav>
2023
<a href="http://codemirror.net"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png"></a>
2124

@@ -73,6 +76,7 @@ <h2>GFM mode</h2>
7376
* \#Num: #1
7477
* User/#Num: mojombo#1
7578
* User/Project#Num: mojombo/god#1
79+
* emoji: :smile: (note: you must add the CSS rule yourself. Set `emoji: false` in mode options to disable)
7680

7781
See http://github.github.com/github-flavored-markdown/.
7882

mode/gfm/test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
FT("formatting_strikethrough",
3030
"foo [strikethrough&formatting&formatting-strikethrough ~~][strikethrough bar][strikethrough&formatting&formatting-strikethrough ~~]");
3131

32+
FT("formatting_emoji",
33+
"foo [emoji&formatting&formatting-emoji :smile:] foo");
34+
3235
MT("emInWordAsterisk",
3336
"foo[em *bar*]hello");
3437

@@ -231,4 +234,8 @@
231234
MT("strikethroughStrong",
232235
"[strong **][strong&strikethrough ~~foo~~][strong **]");
233236

237+
MT("emoji",
238+
"text [emoji :blush:] text [emoji :v:] text [emoji :+1:] text",
239+
":text text: [emoji :smiley_cat:]");
240+
234241
})();

mode/markdown/markdown.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
4747
if (modeCfg.strikethrough === undefined)
4848
modeCfg.strikethrough = false;
4949

50+
if (modeCfg.emoji === undefined)
51+
modeCfg.emoji = false;
52+
5053
// Allow token types to be overridden by user-provided token types.
5154
if (modeCfg.tokenTypeOverrides === undefined)
5255
modeCfg.tokenTypeOverrides = {};
@@ -69,7 +72,8 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
6972
linkHref: "string",
7073
em: "em",
7174
strong: "strong",
72-
strikethrough: "strikethrough"
75+
strikethrough: "strikethrough",
76+
emoji: "emoji"
7377
};
7478

7579
for (var tokenType in tokenTypes) {
@@ -83,7 +87,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
8387
, taskListRE = /^\[(x| )\](?=\s)/ // Must follow listRE
8488
, atxHeaderRE = modeCfg.allowAtxHeaderWithoutSpace ? /^(#+)/ : /^(#+)(?: |$)/
8589
, setextHeaderRE = /^ *(?:\={1,}|-{1,})\s*$/
86-
, textRE = /^[^#!\[\]*_\\<>` "'(~]+/
90+
, textRE = /^[^#!\[\]*_\\<>` "'(~:]+/
8791
, fencedCodeRE = new RegExp("^(" + (modeCfg.fencedCodeBlocks === true ? "~~~+|```+" : modeCfg.fencedCodeBlocks) +
8892
")[ \\t]*([\\w+#\-]*)")
8993
, punctuation = /[!\"#$%&\'()*+,\-\.\/:;<=>?@\[\\\]^_`{|}~]/
@@ -299,6 +303,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
299303
if (state.strong) { styles.push(tokenTypes.strong); }
300304
if (state.em) { styles.push(tokenTypes.em); }
301305
if (state.strikethrough) { styles.push(tokenTypes.strikethrough); }
306+
if (state.emoji) { styles.push(tokenTypes.emoji); }
302307
if (state.linkText) { styles.push(tokenTypes.linkText); }
303308
if (state.code) { styles.push(tokenTypes.code); }
304309
if (state.image) { styles.push(tokenTypes.image); }
@@ -556,6 +561,14 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
556561
}
557562
}
558563

564+
if (modeCfg.emoji && ch === ":" && stream.match(/^[a-z_\d+-]+:/)) {
565+
state.emoji = true;
566+
if (modeCfg.highlightFormatting) state.formatting = "emoji";
567+
var retType = getType(state);
568+
state.emoji = false;
569+
return retType;
570+
}
571+
559572
if (ch === ' ') {
560573
if (stream.match(/ +$/, false)) {
561574
state.trailingSpace++;
@@ -698,6 +711,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
698711
trailingSpace: 0,
699712
trailingSpaceNewLine: false,
700713
strikethrough: false,
714+
emoji: false,
701715
fencedChars: null
702716
};
703717
},
@@ -725,6 +739,7 @@ CodeMirror.defineMode("markdown", function(cmCfg, modeCfg) {
725739
em: s.em,
726740
strong: s.strong,
727741
strikethrough: s.strikethrough,
742+
emoji: s.emoji,
728743
header: s.header,
729744
hr: s.hr,
730745
taskList: s.taskList,

mode/markdown/test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
var modeOverrideClasses = CodeMirror.getMode(config, {
1515
name: "markdown",
1616
strikethrough: true,
17+
emoji: true,
1718
tokenTypeOverrides: {
1819
"header" : "override-header",
1920
"code" : "override-code",
@@ -31,7 +32,8 @@
3132
"linkHref" : "override-link-href",
3233
"em" : "override-em",
3334
"strong" : "override-strong",
34-
"strikethrough" : "override-strikethrough"
35+
"strikethrough" : "override-strikethrough",
36+
"emoji" : "override-emoji"
3537
}});
3638
function TokenTypeOverrideTest(name) { test.mode(name, modeOverrideClasses, Array.prototype.slice.call(arguments, 1)); }
3739
var modeFormattingOverride = CodeMirror.getMode(config, {
@@ -966,6 +968,9 @@
966968
TokenTypeOverrideTest("overrideStrikethrough",
967969
"[override-strikethrough ~~foo~~]");
968970

971+
TokenTypeOverrideTest("overrideEmoji",
972+
"[override-emoji :foo:]");
973+
969974
FormatTokenTypeOverrideTest("overrideFormatting",
970975
"[override-formatting-escape \\*]");
971976

0 commit comments

Comments
 (0)