91 lines
2.5 KiB
JavaScript
91 lines
2.5 KiB
JavaScript
/* eslint-disable no-useless-escape, no-control-regex */
|
|
|
|
// Shamelessly copied from https://github.com/megawac/irc-style-parser/
|
|
// Lol, I just gave credit, didn't I..
|
|
// Dammit, well, there's that.
|
|
|
|
import { el } from './utility'
|
|
|
|
const styleCheckRe = /[\x00-\x1F]/
|
|
const backRe = /^(\d{1,2})(,(\d{1,2}))?/
|
|
const colourKey = '\x03'
|
|
const colourRe = /\x03/g
|
|
const styleBreak = '\x0F' // breaks all open styles ^O (\x0F)
|
|
|
|
let styles = [
|
|
['normal', '\x00', ''], ['underline', '\x1F'],
|
|
['bold', '\x02'], ['italic', '\x1D']
|
|
].map(function (style) {
|
|
var escaped = encodeURI(style[1]).replace('%', '\\x')
|
|
return {
|
|
name: style[0],
|
|
style: style[2] != null ? style[2] : 'irc-' + style[0],
|
|
key: style[1],
|
|
keyregex: new RegExp(escaped + '(.*?)(' + escaped + '|$)')
|
|
}
|
|
})
|
|
|
|
// http://www.mirc.com/colors.html
|
|
let colors = [
|
|
'white', 'black', 'navy', 'green', 'red', 'brown',
|
|
'purple', 'olive', 'yellow', 'lightgreen', 'teal',
|
|
'cyan', 'blue', 'pink', 'gray', 'lightgrey'
|
|
].reduce(function (memo, name, index) {
|
|
memo[index] = {
|
|
name: name,
|
|
fore: 'irc-fg' + index,
|
|
back: 'irc-bg' + index,
|
|
key: index
|
|
}
|
|
return memo
|
|
}, {})
|
|
|
|
function stylize (line) {
|
|
// Recheck
|
|
if (!styleCheckRe.test(line)) return line
|
|
|
|
// split up by the irc style break character ^O
|
|
if (line.indexOf(styleBreak) >= 0) {
|
|
return line.split(styleBreak).map(stylize).join('')
|
|
}
|
|
|
|
let result = line
|
|
let parseArr = result.split(colourKey)
|
|
|
|
let text
|
|
let match
|
|
let colour
|
|
let background = ''
|
|
for (let i = 0; i < parseArr.length; i++) {
|
|
text = parseArr[i]
|
|
match = text.match(backRe)
|
|
colour = match && colors[+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 (colors[+match[3]]) {
|
|
background = ' ' + colors[+match[3]].back
|
|
}
|
|
// update the parsed text result
|
|
result = result.replace(colourKey + text, el('span', text.slice(match[0].length), [colour.fore + background]))
|
|
}
|
|
|
|
// Matching styles (italics/bold/underline)
|
|
// if only colors were this easy...
|
|
styles.forEach(function (style) {
|
|
if (result.indexOf(style.key) < 0) return
|
|
result = result.replace(style.keyregex, function (match, text) {
|
|
return el('span', text, [style.style])
|
|
})
|
|
})
|
|
|
|
// replace the reminent colour terminations and be done with it
|
|
return result.replace(colourRe, '')
|
|
}
|
|
|
|
export default stylize
|