diff --git a/server/core/BookConverter/index.js b/server/core/BookConverter/index.js index 488ada24..2dbfa1c4 100644 --- a/server/core/BookConverter/index.js +++ b/server/core/BookConverter/index.js @@ -97,7 +97,7 @@ class BookConverter { newParagraph(); const newPara = new Set(['tr', 'br', 'br/', 'dd', 'p', 'title', '/title', 'h1', 'h2', 'h3', '/h1', '/h2', '/h3']); - const onTextNode = (text, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onTextNode = (text, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars if (!cutCounter) { growParagraph(text); } @@ -106,7 +106,7 @@ class BookConverter { title = text; }; - const onStartNode = (tag, tail, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onStartNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars if (!cutCounter) { if (newPara.has(tag)) newParagraph(); @@ -116,7 +116,7 @@ class BookConverter { inTitle = true; }; - const onEndNode = (tag, tail, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onEndNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars if (tag == 'title') inTitle = false; }; @@ -225,7 +225,7 @@ class BookConverter { newParagraph(); - const onStartNode = (elemName, tail, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onStartNode = (elemName, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars if (elemName == '') return; if (!inText) { @@ -253,7 +253,7 @@ class BookConverter { } }; - const onEndNode = (elemName, tail, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onEndNode = (elemName, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars if (!inText) { const oldPath = path; let t = ''; @@ -286,14 +286,14 @@ class BookConverter { } }; - const onComment = (text, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onComment = (text) => {// eslint-disable-line no-unused-vars if (text == '--------- Собственно произведение -------------') inText = true; if (text == '-----------------------------------------------') inText = false; }; - const onTextNode = (text, left, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars + const onTextNode = (text) => {// eslint-disable-line no-unused-vars if (text != ' ' && text.trim() == '') text = text.trim(); diff --git a/server/core/BookConverter/sax.js b/server/core/BookConverter/sax.js index c2fa877b..712d4a05 100644 --- a/server/core/BookConverter/sax.js +++ b/server/core/BookConverter/sax.js @@ -29,6 +29,7 @@ function parseSync(xstr, options) { while (i < len) { inCdata = false; inComment = false; + let singleTag = false; let left = xstr.indexOf('<', i); if (left < 0) @@ -70,14 +71,18 @@ function parseSync(xstr, options) { if (rightData < 0) break; right = rightData; + if (xstr[right - 1] === '/') { + singleTag = true; + rightData--; + } } let tagData = xstr.substr(leftData + 1, rightData - leftData - 1); if (inCdata) { - onCdata(tagData, left, cutCounter, cutTag); + onCdata(tagData, cutCounter, cutTag); } else if (inComment) { - onComment(tagData, left, cutCounter, cutTag); + onComment(tagData, cutCounter, cutTag); } else { let tag = ''; let tail = ''; @@ -92,16 +97,18 @@ function parseSync(xstr, options) { const text = xstr.substr(i, left - i); - onTextNode(text, left, cutCounter, cutTag); + onTextNode(text, cutCounter, cutTag); - let endTag = ''; + let endTag = (singleTag ? tag : ''); if (tag === '' || tag[0] !== '/') { - onStartNode(tag, tail, left, cutCounter, cutTag); + onStartNode(tag, tail, singleTag, cutCounter, cutTag); } else { endTag = tag.substr(1); - onEndNode(endTag, tail, left, cutCounter, cutTag); } + if (endTag) + onEndNode(endTag, tail, singleTag, cutCounter, cutTag); + if (innerCut.has(tag) && (!cutCounter || cutTag === tag)) { if (!cutCounter) cutTag = tag; @@ -116,8 +123,7 @@ function parseSync(xstr, options) { } if (right >= nextProg) { - const prog = Math.round(right/(len + 1)*100); - onProgress((prog >= 100 ? 99 : prog)); + onProgress(Math.round(right/(len + 1)*100)); nextProg += progStep; } i = right + 1; @@ -125,154 +131,22 @@ function parseSync(xstr, options) { if (i < len) { if (inCdata) { - onCdata(xstr.substr(i, len - i), len - 1, cutCounter, cutTag); + onCdata(xstr.substr(i, len - i), cutCounter, cutTag); } else if (inComment) { - onComment(xstr.substr(i, len - i), len - 1, cutCounter, cutTag); + onComment(xstr.substr(i, len - i), cutCounter, cutTag); } else { - onTextNode(xstr.substr(i, len - i), len - 1, cutCounter, cutTag); + onTextNode(xstr.substr(i, len - i), cutCounter, cutTag); } } onProgress(100); } -//асинхронная копия parseSync async function parse(xstr, options) { - let {onStartNode, onEndNode, onTextNode, onCdata, onComment, onProgress, innerCut} = options; - - if (!onStartNode) - onStartNode = () => {}; - if (!onEndNode) - onEndNode = () => {}; - if (!onTextNode) - onTextNode = () => {}; - if (!onCdata) - onCdata = () => {}; - if (!onComment) - onComment = () => {}; - if (!onProgress) - onProgress = () => {}; - - if (!innerCut) - innerCut = new Set(); - - let i = 0; - const len = xstr.length; - const progStep = len/10; - let nextProg = 0; - - let cutCounter = 0; - let cutTag = ''; - let inCdata; - let inComment; - while (i < len) { - inCdata = false; - inComment = false; - - let left = xstr.indexOf('<', i); - if (left < 0) - break; - let leftData = left; - - if (left < len - 2 && xstr[left + 1] == '!') { - if (xstr[left + 2] == '-') { - const leftComment = xstr.indexOf('', leftData + 1); - if (rightData < 0) - break; - right = rightData + 2; - } else { - rightData = xstr.indexOf('>', leftData + 1); - if (rightData < 0) - break; - right = rightData; - } - - let tagData = xstr.substr(leftData + 1, rightData - leftData - 1); - - if (inCdata) { - await onCdata(tagData, left, cutCounter, cutTag); - } else if (inComment) { - await onComment(tagData, left, cutCounter, cutTag); - } else { - let tag = ''; - let tail = ''; - const firstSpace = tagData.indexOf(' '); - if (firstSpace >= 0) { - tail = tagData.substr(firstSpace); - tag = tagData.substr(0, firstSpace); - } else { - tag = tagData; - } - tag = tag.toLowerCase(); - - const text = xstr.substr(i, left - i); - - await onTextNode(text, left, cutCounter, cutTag); - - let endTag = ''; - if (tag === '' || tag[0] !== '/') { - await onStartNode(tag, tail, left, cutCounter, cutTag); - } else { - endTag = tag.substr(1); - await onEndNode(endTag, tail, left, cutCounter, cutTag); - } - - if (innerCut.has(tag) && (!cutCounter || cutTag === tag)) { - if (!cutCounter) - cutTag = tag; - cutCounter++; - } - - if (cutTag === endTag) { - cutCounter = (cutCounter > 0 ? cutCounter - 1 : 0); - if (!cutCounter) - cutTag = ''; - } - } - - if (right >= nextProg) { - const prog = Math.round(right/(len + 1)*100); - await onProgress((prog >= 100 ? 99 : prog)); - nextProg += progStep; - } - i = right + 1; - } - - if (i < len) { - if (inCdata) { - await onCdata(xstr.substr(i, len - i), len - 1, cutCounter, cutTag); - } else if (inComment) { - await onComment(xstr.substr(i, len - i), len - 1, cutCounter, cutTag); - } else { - await onTextNode(xstr.substr(i, len - i), len - 1, cutCounter, cutTag); - } - } - - await onProgress(100); + return new Promise((resolve) => { + parseSync(xstr, options); + resolve(); + }); } module.exports = {