Ok. Here's a version that will at least take a stab at block level elements of HTML. I also expanded the command slightly to provide a whispered and open version: !gmnote !wgmnote !gmnote-<some text> !wgmnote-<some text> It will do it's best to preserve the formatting, but short of a full HTML parser, it can't be perfect. YMMV. on('ready',function(){
'use strict';
const decodeUnicode = (str) => str.replace(/%u[0-9a-fA-F]{2,4}/g,(m)=>String.fromCharCode(parseInt(m.slice(2),16)));
const blockElements = [
'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'pre', 'address',
'blockquote', 'dl', 'div', 'fieldset', 'form', 'hr', 'noscript', 'table','br'
];
const rStart=new RegExp(`<\\s*(?:${blockElements.join('|')})\\b[^>]*>`,'ig');
const rEnd=new RegExp(`<\\s*\\/\\s*(?:${blockElements.join('|')})\\b[^>]*>`,'ig');
const getLines = (str) =>
(rStart.test(str)
? str
.replace(/[\n\r]+/g,' ')
.replace(rStart,"\r$&")
.replace(rEnd,"$&\r")
.split(/[\n\r]+/)
: str
.split(/(?:[\n\r]+|<br\/?>)/)
)
.map((s)=>s.trim())
.filter((s)=>s.length)
;
const cmdRegex = /^!(w?)gmnote(?:-(.*))?$/i;
on('chat:message',function(msg){
if('api' === msg.type && cmdRegex.test(msg.content) && playerIsGM(msg.playerid) ){
let match=msg.content.match(cmdRegex),
output = match[1].length ? '/w gm ' : '',
regex;
if(match[2]){
regex = new RegExp(`^${match[2]}`,'i');
}
_.chain(msg.selected)
.map( s => getObj('graphic',s._id))
.reject(_.isUndefined)
.reject((o)=>o.get('gmnotes').length===0)
.each( o => {
if(regex){
let lines = _.filter(
getLines(decodeURIComponent(decodeUnicode(o.get('gmnotes')))),
(l) => regex.test(l.replace(/<[^>]*>/g,''))
).join('<br>');
sendChat(o.get('name'), `${output}${lines}`);
} else {
sendChat(o.get('name'), `${output}${decodeURIComponent(decodeUnicode(o.get('gmnotes')))}`);
}
});
}
});
});