Merge pull request #305 from megawac/style-parser
Full mIRC color and style compliance
This commit is contained in:
commit
9c8f804d45
|
@ -879,41 +879,54 @@ button {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Colors
|
* IRC Message Styling
|
||||||
* http://clrs.cc/
|
* https://github.com/megawac/irc-style-parser
|
||||||
*/
|
* Colours are credit to http://clrs.cc/
|
||||||
.color-0, .color-00 { color: #fff; }
|
*/
|
||||||
.color-1, .color-01 { color: #000; }
|
.irc-fg0 { color: #fff; }
|
||||||
.color-2, .color-02 { color: #001f3f; }
|
.irc-fg1 { color: #000; }
|
||||||
.color-3, .color-03 { color: #2ecc40; }
|
.irc-fg2 { color: #001f3f; }
|
||||||
.color-4, .color-04 { color: #ff4136; }
|
.irc-fg3 { color: #2ecc40; }
|
||||||
.color-5, .color-05 { color: #85144b; }
|
.irc-fg4 { color: #ff4136; }
|
||||||
.color-6, .color-06 { color: #b10dc9; }
|
.irc-fg5 { color: #85144b; }
|
||||||
.color-7, .color-07 { color: #ff851b; }
|
.irc-fg6 { color: #b10dc9; }
|
||||||
.color-8, .color-08 { color: #ffdc00; }
|
.irc-fg7 { color: #ff851b; }
|
||||||
.color-9, .color-09 { color: #01ff70; }
|
.irc-fg8 { color: #ffdc00; }
|
||||||
.color-10 { color: #39cccc; }
|
.irc-fg9 { color: #01ff70; }
|
||||||
.color-11 { color: #7fdbff; }
|
.irc-fg10 { color: #39cccc; }
|
||||||
.color-12 { color: #0074d9; }
|
.irc-fg11 { color: #7fdbff; }
|
||||||
.color-13 { color: #f012be; }
|
.irc-fg12 { color: #0074d9; }
|
||||||
.color-14 { color: #aaa; }
|
.irc-fg13 { color: #f012be; }
|
||||||
.color-15 { color: #ddd; }
|
.irc-fg14 { color: #aaa; }
|
||||||
.bg-0, .bg-00 { background: #fff; }
|
.irc-fg15 { color: #ddd; }
|
||||||
.bg-1, .bg-01 { background: #000; }
|
.irc-bg0 { background: #fff; }
|
||||||
.bg-2, .bg-02 { background: #001f3f; }
|
.irc-bg1 { background: #000; }
|
||||||
.bg-3, .bg-03 { background: #2ecc40; }
|
.irc-bg2 { background: #001f3f; }
|
||||||
.bg-4, .bg-04 { background: #ff4136; }
|
.irc-bg3 { background: #2ecc40; }
|
||||||
.bg-5, .bg-05 { background: #85144b; }
|
.irc-bg4 { background: #ff4136; }
|
||||||
.bg-6, .bg-06 { background: #b10dc9; }
|
.irc-bg5 { background: #85144b; }
|
||||||
.bg-7, .bg-07 { background: #ff851b; }
|
.irc-bg6 { background: #b10dc9; }
|
||||||
.bg-8, .bg-08 { background: #ffdc00; }
|
.irc-bg7 { background: #ff851b; }
|
||||||
.bg-9, .bg-09 { background: #01ff70; }
|
.irc-bg8 { background: #ffdc00; }
|
||||||
.bg-10 { background: #39cccc; }
|
.irc-bg9 { background: #01ff70; }
|
||||||
.bg-11 { background: #7fdbff; }
|
.irc-bg10 { background: #39cccc; }
|
||||||
.bg-12 { background: #0074d9; }
|
.irc-bg11 { background: #7fdbff; }
|
||||||
.bg-13 { background: #f012be; }
|
.irc-bg12 { background: #0074d9; }
|
||||||
.bg-14 { background: #aaa; }
|
.irc-bg13 { background: #f012be; }
|
||||||
.bg-15 { background: #ddd; }
|
.irc-bg14 { background: #aaa; }
|
||||||
|
.irc-bg15 { background: #ddd; }
|
||||||
|
|
||||||
|
.irc-bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.irc-underline {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.irc-italic {
|
||||||
|
font-style:italic
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TrackpadScrollEmulator
|
* TrackpadScrollEmulator
|
||||||
|
|
|
@ -48,46 +48,96 @@ function uri(text) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var regex = {
|
|
||||||
color: /\003([0-9]{1,2})[,]?([0-9]{1,2})?([^\003]+)/,
|
/**
|
||||||
terminator: /\x0D/,
|
* MIRC compliant colour and style parser
|
||||||
styles: [
|
* Unfortuanately this is a non trivial operation
|
||||||
[/\002([^\002]+)(\002)?/, ["<b>", "</b>"]],
|
* See this branch for source and tests
|
||||||
[/\037([^\037]+)(\037)?/, ["<u>", "</u>"]],
|
* https://github.com/megawac/irc-style-parser/tree/shout
|
||||||
]
|
*/
|
||||||
};
|
var styleCheck_Re = /[\x00-\x1F]/,
|
||||||
function colors(text) {
|
back_re = /^(\d{1,2})(,(\d{1,2}))?/,
|
||||||
if (!text) {
|
colourKey = "\x03", colour_re = /\x03/g,
|
||||||
return text;
|
// breaks all open styles ^O (\x0F)
|
||||||
}
|
styleBreak = "\x0F";
|
||||||
if (regex.terminator.test(text)) {
|
|
||||||
return $.map(text.split(regex.terminator), colors);
|
|
||||||
}
|
function styleTemplate(settings) {
|
||||||
if (regex.color.test(text)) {
|
return "<span class='" + settings.style + "'>" + settings.text + "</span>";
|
||||||
var match, bg;
|
}
|
||||||
while (match = regex.color.exec(text)) {
|
|
||||||
var color = "color-" + match[1];
|
var styles = [
|
||||||
if (match[2]) {
|
["normal", "\x00", ""], ["underline", "\x1F"],
|
||||||
bg = match[2];
|
["bold", "\x02"], ["italic", "\x1D"]
|
||||||
}
|
].map(function(style) {
|
||||||
if (bg) {
|
var escaped = encodeURI(style[1]).replace("%", "\\x");
|
||||||
color += " bg-" + bg;
|
return {
|
||||||
}
|
name: style[0],
|
||||||
var text = text.replace(
|
style: style[2] != null ? style[2] : "irc-" + style[0],
|
||||||
match[0],
|
key: style[1],
|
||||||
"<span class='" + color + "'>" + match[3] + "</span>"
|
keyregex: new RegExp(escaped + "(.*?)(" + escaped + "|$)")
|
||||||
);
|
};
|
||||||
}
|
});
|
||||||
}
|
|
||||||
for (var i in regex.styles) {
|
//http://www.mirc.com/colors.html
|
||||||
var pattern = regex.styles[i][0];
|
var colourMap = {};
|
||||||
var style = regex.styles[i][1];
|
for (var colour = 0; colour < 16; colour++) {
|
||||||
if (pattern.test(text)) {
|
colourMap[colour] = {
|
||||||
var match;
|
fore: "irc-fg" + colour,
|
||||||
while (match = pattern.exec(text)) {
|
back: "irc-bg" + colour
|
||||||
text = text.replace(match[0], style[0] + match[1] + style[1]);
|
};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
function colors(line) {
|
||||||
return text;
|
// http://www.mirc.com/colors.html
|
||||||
|
// http://www.aviran.org/stripremove-irc-client-control-characters/
|
||||||
|
// https://github.com/perl6/mu/blob/master/examples/rules/Grammar-IRC.pm
|
||||||
|
// regexs are cruel to parse this thing
|
||||||
|
|
||||||
|
// already done?
|
||||||
|
if (!styleCheck_Re.test(line)) return line;
|
||||||
|
|
||||||
|
// split up by the irc style break character ^O
|
||||||
|
if (line.indexOf(styleBreak) >= 0) {
|
||||||
|
return line.split(styleBreak).map(colors).join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = line;
|
||||||
|
var parseArr = result.split(colourKey);
|
||||||
|
var text, match, colour, background = "";
|
||||||
|
for (var i = 0; i < parseArr.length; i++) {
|
||||||
|
text = parseArr[i];
|
||||||
|
match = text.match(back_re);
|
||||||
|
colour = match && colourMap[+match[1]];
|
||||||
|
if (!match || !colour) {
|
||||||
|
// ^C (no colour) ending. Escape current colour and carry on
|
||||||
|
background = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// set the background colour
|
||||||
|
// we don't overide the background local var to support nesting
|
||||||
|
if (colourMap[+match[3]]) {
|
||||||
|
background = " " + colourMap[+match[3]].back;
|
||||||
|
}
|
||||||
|
// update the parsed text result
|
||||||
|
result = result.replace(colourKey + text, styleTemplate({
|
||||||
|
style: colour.fore + background,
|
||||||
|
text: text.slice(match[0].length)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matching styles (italics/bold/underline)
|
||||||
|
// if only colours were this easy...
|
||||||
|
styles.forEach(function(style) {
|
||||||
|
if (result.indexOf(style.key) < 0) return;
|
||||||
|
result = result.replace(style.keyregex, function(match, text) {
|
||||||
|
return styleTemplate({
|
||||||
|
"style": style.style,
|
||||||
|
"text": text
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//replace the reminent colour terminations and be done with it
|
||||||
|
return result.replace(colour_re, "");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue