function repeatWhileDifferent(text, func) {
let oldText;
do
oldText = text;
while ((text = func(text)) != oldText);
return text;
}
function applyBBCode(text) {
let map = {'&': '&', '<': '<', '>': '>', '\n': '<br>', '\x01': '\x03', '\x02': '\x03'};
let lastSpoilerID = 0;
let noCode = [];
let regExpList = [
[/\[nocode\](.*?)\[\/nocode\]/isg, (s, p) => '\x01' + noCode.push(p) + '\x02'],
[/\[(b|i|u|s|left|center|right|code)\](.+?)\[\/\1\]/isg, "<span class='text_$1'>$2</span>"],
[/\[url=['\"]*(http\:\/\/.+?|https\:\/\/.+?|\/.*?)['\"]*\](.+?)\[\/url\]/isg, (s, p1, p2) => `<a href='${eqsc(p1)}' rel='nofollow' target='_blank'>${p2}</a>`],
[/\[url\](http\:\/\/.+?|https\:\/\/.+?|\/.*?)\[\/url\]/isg, (s, p1) => `<a href='${eqsc(p1)}' rel='nofollow' target='_blank'>${p1}</a>`],
[/\[img\](http\:\/\/.+?|https\:\/\/.+?|\/.*?)\[\/img\]/isg, (s, p1) => `<img src='${eqsc(p1)}' alt='Изображение'>`],
[/\[spoiler=(.+)](.+?)\[\/spoiler\]/isg, (s, p1, p2) => {
let id = ++window.bbCode_lastSpoilerID;
return `<a href='' onclick='return toggleSpoiler("${id}");'>${p1}</a><div id='${id}' style='display: none;'>${p2}</div>`;
}],
[/\[font=([^'\"]+)\](.+?)\[\/font\]/isg, `<span style='font-family: "$1", serif;'>$2</span>`],
[/\[size=([1-9]|[1-9]\d|[1-4]\d\d)\](.+?)\[\/size\]/isg, "<span style='font-size: $1%;'>$2</span>"],
[/\[color=([a-zA-Z]+|\#?[0-9a-fA-F]{6})\](.+?)\[\/color\]/isg, "<span style='color: $1;'>$2</span>"],
[/\[youtube\](.+?)\[\/youtube\]/isg, (s, p) => {
let lastAmpersand = p.length - 1;
while ((lastAmpersand >= 0) && (p[lastAmpersand] != '&'))
lastAmpersand--;
if ((lastAmpersand >= 0) && p.slice(lastAmpersand).startsWith('&t='))
p = p.slice(0, lastAmpersand);
let id = p.slice(-11);
if (!/^[a-zA-Z0-9]+$/.test(id))
return "";
else
return `<iframe allowfullscreen allow='fullscreen; picture-in-picture' title='YouTube video player' width='640' height='385' src='https://youtube.com/embed/${id}'></iframe>`;
}],
[/\[table\](.+?)\[\/table\]/isg, "<table class='normal_table'>$1</table>"],
[/\[table=0\](.+?)\[\/table\]/isg, "<table>$1</table>"],
[/\[(tr|td)\](.*?)\[\/\1\]/isg, "<$1>$2</$1>"],
[/\x01(\d+)\x02/g, (s, num) => noCode[num - 1]]
];
HTML = text.replace(/[&<>\n]/g, s => map[s]);
for (let regexp of regExpList)
HTML = repeatWhileDifferent(HTML, (str) => str.replace(regexp[0], regexp[1]));
return HTML;
}
function eqsc(str) {
let quotesSemiColonMap = {"'": ''', '"': '"', ';': ';', ':': ':'};
return str.replace(/['\";:]/g, s => quotesSemiColonMap[s]);
}
function toggleSpoiler(id) {
let element = document.getElementById(id);
element.style.display = (element.style.display == 'block') ? 'none' : 'block';
return false;
}