import { saveSelection, loadSelection } from "./caret.js"; function load(textarea, div) { div.innerHTML = ''; let lines = textarea.value.split('\n'); for (let i = 0; i < lines.length; i++) { let line = lines[i]; let elem = formatLine(line); div.append(elem); } redrawTables(div, 0); } function appendData(div, data) { const selection = window.getSelection(); selection.deleteFromDocument(); let ret = saveSelection(); let line = ret[0]; let position = ret[1]; if (line == null) { return; } let lineBegin = line.innerText.substring(0, position); let lineEnd = line.innerText.substring(position, line.innerText.length); let lines = data.split('\n'); let newline; if (lines.length == 1) { newline = formatLine(lineBegin + lines[0] + lineEnd); line.parentNode.replaceChild(newline, line); position = position + lines[0].length; } else { newline = formatLine(lineBegin + lines[0]); line.parentNode.replaceChild(newline, line); let prevline = newline; for (let i = 1; i < lines.length - 1; i++) { newline = formatLine(lines[i]); prevline.after(newline); prevline = newline; } newline = formatLine(lines[lines.length - 1] + lineEnd); prevline.after(newline); position = lines[lines.length - 1].length; } loadSelection([newline, position, newline, position]); redrawTables(div, dpwidth(div)); } var _dpwidth = null; function dpwidth(div) { if (_dpwidth != null) { return _dpwidth; } let dp = document.createElement('span'); dp.classList.add('tokenfictif'); div.append(dp); dp.innerText = ':'; _dpwidth = dp.getBoundingClientRect().width; div.removeChild(dp); return _dpwidth; } function save(textarea, div) { let lines = div.children; let text = ''; for (let i = 0; i < lines.length; i++) { if (lines[i].innerText != '\n') { text += lines[i].innerText.replace(emsp(), '\t'); } if (i < lines.length - 1) { text += '\n'; } } textarea.value = text; return text; } function emsp() { return ' '; } function onlinkin(e) { let link = e.currentTarget; if (document.getElementById('cheezenotes') !== document.activeElement) { document.getElementById('cheezenotes').contentEditable = false; } } function onlink(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { e.preventDefault(); cheezenotes.contentEditable = true; let link = e.currentTarget; if (link.host !== document.location.host) { open(link.href); } else { //open(link.href, '_self'); fetch(link.href + "?data=").then((response) => { let ta = document.getElementById('ta'); response.text().then((data) => { let content = document.getElementById('content'); let left = content.scrollLeft; let top = content.scrollTop; window.history.replaceState({top: top, left: left}, ""); window.history.pushState({}, "", link.href); ta.value = data; load(document.getElementById('ta'), document.getElementById('cheezenotes')); content.scrollTop = 0; content.scrollLeft = 0; }); }).catch((error) => { alert(error); }); } return false; } else { return true; } } function onlinkout(e) { let cheezenotes = document.getElementById('cheezenotes'); if (cheezenotes.contentEditable == 'false') { cheezenotes.contentEditable = true; } } function formatLine(line) { let token = null; let elem = document.createElement('div'); elem.classList.add('cheezenotes_line'); if (line == '' || line == '\n') { elem.classList.add('body'); elem.innerHTML = '
'; return elem; } line = line.replace(/\t/, emsp()); line = line.replace('&', '&'); line = line.replace('<', '<'); let ret = removeMono(line); line = ret[0]; let listMono = ret[1]; ret = removeLink(line); line = ret[0]; let listLink = ret[1]; if (line.match(/^\s*_{3,}\s*$/)) { token = /^(\s*_{3,}\s*)$/ elem.classList.add('line'); } else if (line.match(/^\s*######(\s|$)/i)) { token = /^(\s*######(\s|$))/i; elem.classList.add('h6'); } else if (line.match(/^\s*#####(\s|$)/i)) { token = /^(\s*#####(\s|$))/i; elem.classList.add('h5'); } else if (line.match(/^\s*####(\s|$)/i)) { token = /^(\s*####(\s|$))/i; elem.classList.add('h4'); } else if (line.match(/^\s*###(\s|$)/i)) { token = /^(\s*###(\s|$))/i; elem.classList.add('h3'); } else if (line.match(/^\s*##(\s|$)/)) { token = /^(\s*##(\s|$))/i; elem.classList.add('h2'); } else if (line.match(/^\s*#(\s|$)/i)) { token = /^(\s*#(\s|$))/i; elem.classList.add('h1'); } else if (line.match(/^\s*>\s*>\s*>(\s|$)/i)) { token = /^(\s*>\s*>\s*>(\s|$))/i; elem.classList.add('bq3'); elem.classList.add('bq'); } else if (line.match(/^\s*>\s*>(\s|$)/i)) { token = /^(\s*>\s*>(\s|$))/i; elem.classList.add('bq2'); elem.classList.add('bq'); } else if (line.match(/^\s*>(\s|$)/i)) { token = /^(\s*>(\s|$))/i; elem.classList.add('bq1'); elem.classList.add('bq'); } else { elem.classList.add('body'); } if (elem.classList.contains('bq') || elem.classList.contains('body')) { if (line.match(/^\s*((>\s*){0,3}\s)?([\*\-+]\s*){3}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}([\*\-+]\s*){3}(\s|$))/i; elem.classList.add('ul3'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?([\*\-+]\s*){2}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}([\*\-+]\s*){2}(\s|$))/i; elem.classList.add('ul2'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?[\*\-+](\s|$)/i)) { token = /^(\s*(>\s*){0,3}[\*\-+](\s*|$))/; elem.classList.add('ul1'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?([0-9]+\.){3}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}(\s*|$))/; elem.classList.add('ol3'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?([0-9]+\.){2}(\s|$)/i)) { token = /^(\s*(>\s*){0,3}(\s*|$))/; elem.classList.add('ol2'); elem.classList.remove('body'); } else if (line.match(/^\s*((>\s*){0,3}\s)?[0-9]+\.(\s|$)/i)) { token = /^(\s*(>\s*){0,3}(\s*|$))/; elem.classList.add('ol1'); elem.classList.remove('body'); } } if (token != null) { line = line.replace(token, '$1'); } line = addBold(line); line = addItalic(line); line = addStrike(line); line = addTableLine(line); line = addLink(line, listLink); line = addMono(line, listMono); elem.innerHTML = line; if (elem.getElementsByClassName('tablerow').length > 0) { if (elem.childNodes[0].childNodes.length > 0) { let child = elem.childNodes[0].childNodes[0]; while (child != null) { if (child.nodeType == 3) { let newchild = document.createElement('span'); newchild.innerText = child.nodeValue; child.parentNode.replaceChild(newchild, child); child = newchild; } child = child.nextSibling; } } elem.classList.remove('body'); elem.classList.add('tablerow'); } let links = elem.getElementsByClassName('link'); for (let i = 0; i < links.length; i++) { let link = links[i]; link.addEventListener('mouseover', onlinkin); link.addEventListener('click', onlink); link.addEventListener('mouseout', onlinkout); } return elem; } function addTableLine(line) { if (line.match(/^\s*\|:{0,1}(\s*.*?:{0,1}\|:{0,1})*/)) { let cpt = 0; let re = /:{0,1}\|:{0,1}/g; let match; let matches = []; let lengthes = [] while ((match = re.exec(line)) != null) { matches[cpt] = match; if (cpt > 1000) { continue; } cpt++; } matches = matches.reverse(); for (let i = 0; i < matches.length; i++) { let match = matches[i]; if (i == matches.length - 1) { // premier | let leftdp = ' data-dp="false"'; if (match[0].length == 2) { leftdp = ' data-dp="true"'; } let line1 = line.substring(0, match.index); let line2 = '' + match[0] + '' let line3 = line.substring(match.index + match[0].length, line.length); line = line1 + line2 + line3; } else if (i == 0 && match.index == line.length - 1) { // dernier | let rightdp = ' data-dp="false"'; if (match[0].charAt(0) == ':') { rightdp = ' data-dp="true"'; } let line1 = line.substring(0, match.index); let line2 = '' + match[0] + '' let line3 = line.substring(match.index + match[0].length, line.length); line = line1 + line2 + line3; } else { let rightdp = ' data-dp="false"'; let leftdp = ' data-dp="false"'; if (match[0].length == 3) { rightdp = ' data-dp="true"'; leftdp = ' data-dp="true"'; } else if (match[0].length == 2) { if (match[0].charAt(0) == ':') { rightdp = ' data-dp="true"'; } else { leftdp = ' data-dp="true"'; } } let line1 = line.substring(0, match.index); let line2 = '' + match[0] + ''; let line3 = line.substring(match.index + match[0].length, line.length); line = line1 + line2 + line3; } } line = '' + line + ''; } return line; } function redrawTables(cheezenotes, dpwidth = 0) { if (cheezenotes.childNodes.length == 0) { return; } let child = cheezenotes.childNodes[0]; let firsttableline = null; while (child != null) { if (firsttableline == null) { if (child.classList.contains('tablerow')) { firsttableline = child; } } else { if (!child.classList.contains('tablerow')) { formatTable(firsttableline, dpwidth); firsttableline = null; } } child = child.nextSibling; } if (firsttableline != null) { formatTable(firsttableline, dpwidth); } } function formatTable(line, dpwidth = 0) { if (!line.classList.contains('tablerow')) { return; } let firstline = line; let lastline = line; while (firstline.previousSibling !== null && firstline.previousSibling.classList.contains('tablerow')) { firstline = firstline.previousSibling; firstline.classList.remove('firsttablerow'); firstline.classList.remove('lasttablerow'); } while (lastline.nextSibling !== null && lastline.nextSibling.classList.contains('tablerow')) { lastline = lastline.nextSibling; lastline.classList.remove('firsttablerow'); lastline.classList.remove('lasttablerow'); } firstline.classList.add('firsttablerow'); lastline.classList.add('lasttablerow'); resizeTableCols(firstline, lastline, dpwidth) } function resizeTableCols(firstline, lastline, dpwidth) { let colsmaxwidth = []; let colsjustif = []; let currentline = firstline; while (currentline !== null && currentline.classList.contains('tablerow')) { let tablerow = currentline.getElementsByClassName('tablerow')[0]; let childNodes = tablerow.childNodes; let currentwidth = 0; let col = 0; let currentleft; for (let i = 0; i < childNodes.length; i++) { let child = childNodes[i]; if (child.classList != null && child.classList.contains('lefttablespacer')) { currentleft = child; } else if (child.classList != null && child.classList.contains('righttablespacer')) { let leftdp = currentleft.getAttribute('data-dp'); let rightdp = child.getAttribute('data-dp'); if (colsjustif[col] == null) { if (leftdp == 'true' && rightdp == 'true') { colsjustif[col] = 'c'; } else if (leftdp == 'true' && rightdp == 'false') { colsjustif[col] = 'l'; } else if (leftdp == 'false' && rightdp == 'true') { colsjustif[col] = 'r'; } } if (colsmaxwidth[col] == null || colsmaxwidth[col] < currentwidth) { colsmaxwidth[col] = currentwidth; } child.dataWidth = currentwidth; currentleft.dataWidth = currentwidth; currentleft = null; currentwidth = 0; col += 1; } else if (currentleft != null) { let width = child.getBoundingClientRect().width; currentwidth += width; } } currentline = currentline.nextSibling; } for (let i = 0; i < colsmaxwidth.length; i++) { if (colsjustif[i] == null) { colsjustif[i] = 'l'; } } currentline = firstline; while (currentline !== null && currentline.classList.contains('tablerow')) { let tablerow = currentline.getElementsByClassName('tablerow')[0]; let childNodes = tablerow.childNodes; let col = 0; let currentleft; for (let i = 0; i < childNodes.length; i++) { let child = childNodes[i]; if (child.classList != null && child.classList.contains('lefttablespacer')) { currentleft = child; } else if (child.classList != null && child.classList.contains('righttablespacer')) { let lplus = dpwidth; let rplus = dpwidth; let justif = 'l'; let leftdp = currentleft.getAttribute('data-dp'); let rightdp = child.getAttribute('data-dp'); if (leftdp == 'true' && rightdp == 'true') { justif = 'c'; lplus = 0; rplus = 0; } else if (leftdp == 'true' && rightdp == 'false') { justif = 'l'; lplus = 0; } else if (leftdp == 'false' && rightdp == 'true') { justif = 'r'; rplus = 0; } else { justif = colsjustif[col]; } colsjustif[col] = justif; let leftwidth = 10 + lplus; let rightwidth = Math.round(colsmaxwidth[col] - child.dataWidth + 10 + rplus); if (justif == 'c') { leftwidth = Math.round((colsmaxwidth[col] - child.dataWidth) / 2 + 10 + lplus); rightwidth = Math.round((colsmaxwidth[col] - child.dataWidth) / 2 + 10 + rplus); } else if (justif == 'r') { leftwidth = Math.round(colsmaxwidth[col] - child.dataWidth + 10 + lplus); rightwidth = 10 + rplus; } currentleft.style.width = '' + leftwidth + 'px'; child.style.width = '' + rightwidth + 'px'; currentleft = null; col += 1; } } currentline = currentline.nextSibling; } } function removeMono(line) { let listMono = line.match(/`(`|.*?)`/g); if (listMono == null) { return [line, null]; } line = line.replace(/`(`|.*?)`/g, "``"); return [line, listMono.reverse()]; } function addMono(line, listMono) { if (listMono == null) { return line; } let cpt = 0; let match; let matches = []; let re = /``/g; while ((match = re.exec(line)) != null) { matches[cpt] = match.index; if (cpt > 1000) { continue; } cpt++; } matches = matches.reverse(); for (let i = 0; i < matches.length; i++) { let mono = listMono[i]; mono = mono.substring(1, mono.length - 1); line = line.substring(0, matches[i]) + '`' + mono + '`' + line.substring(matches[i] + 2, line.length); } return line; } function removeLink(line) { let listLink = line.match(/(\[([^\]]*?)\]\(([^\)]*?)\))/g); if (listLink == null) { return [line, null]; } line = line.replace(/(\[([^\]]*?)\]\(([^\)]*?)\))/g, "[]()"); return [line, listLink.reverse()]; } function addLink(line, listLink) { if (listLink == null) { return line; } let cpt = 0; let match; let matches = []; let re = /\[\]\(\)/g; while ((match = re.exec(line)) != null) { matches[cpt] = match.index; if (cpt > 1000) { continue; } cpt++; } matches = matches.reverse(); for (let i = 0; i < matches.length; i++) { line = line.substring(0, matches[i]) + formatLink(listLink[i]) + line.substring(matches[i] + 4, line.length); } return line; } function formatLink(line) { line = line.replace(/(\[!([^\]]*?)\]\(([^\)]+?)\))/ig, '[!$2]($3)'); line = line.replace(/(\[([^\]]+?)\]\(([^\)]+?)\))/ig, '[$2]($3)'); line = line.replace(/(\[([^\]]+?)\]\(\))/ig, '[$2]()'); line = line.replace(/(\[\]\(([^\)]+?)\))/ig, '[]($2)'); return line; } function addBold(line) { line = line.replace(/\*\*([^\s].*?)\*\*/ig, '**$1**'); line = line.replace(/__([^\s].*?)__/ig, '__$1__'); return line; } function addItalic(line) { line = line.replace(/(^|[^\*])\*([^\*\s].*?[^\*\s]|[^\*\s])\*([^\*]|$)/ig, '$1*$2*$3'); line = line.replace(/(^|[\s^*])_([^_\s].*?[^_\s]|[^_\s])_([^_]|$)/ig, '$1_$2_$3'); return line; } function addStrike(line) { line = line.replace(/~~([^\s].*?)~~/ig, '~~$1~~'); return line; } export { load, save, formatLine, formatTable, redrawTables, dpwidth, appendData };