diff --git a/client/components/Reader/share/BookParser.js b/client/components/Reader/share/BookParser.js index 8afe9875..8dec76b3 100644 --- a/client/components/Reader/share/BookParser.js +++ b/client/components/Reader/share/BookParser.js @@ -240,6 +240,7 @@ export default class BookParser { newParagraph(' ', 1); isFirstTitlePara = true; bold = true; + center = true; } if (tag == 'epigraph') { @@ -282,6 +283,7 @@ export default class BookParser { if (tag == 'subtitle') { isFirstTitlePara = false; bold = false; + center = false; } if (tag == 'epigraph') { @@ -367,11 +369,10 @@ export default class BookParser { tClose += (bold ? '' : ''); tClose += (center ? '' : ''); - if (path.indexOf('/fictionbook/body/title') == 0) { - growParagraph(`${tOpen}${text}${tClose}`, text.length); - } - - if (path.indexOf('/fictionbook/body/section') == 0) { + if (path.indexOf('/fictionbook/body/title') == 0 || + path.indexOf('/fictionbook/body/section') == 0 || + path.indexOf('/fictionbook/body/epigraph') == 0 + ) { growParagraph(`${tOpen}${text}${tClose}`, text.length); } diff --git a/client/components/Reader/versionHistory.js b/client/components/Reader/versionHistory.js index c0cfa7e5..158095e5 100644 --- a/client/components/Reader/versionHistory.js +++ b/client/components/Reader/versionHistory.js @@ -1,4 +1,15 @@ export const versionHistory = [ +{ + showUntil: '2019-11-24', + header: '0.7.8 (2019-11-25)', + content: +` + +` +}, + { showUntil: '2019-11-10', header: '0.7.7 (2019-11-06)', diff --git a/package.json b/package.json index 1db3c398..7c310770 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Liberama", - "version": "0.7.7", + "version": "0.7.8", "engines": { "node": ">=10.0.0" }, diff --git a/server/core/Reader/BookConverter/ConvertHtml.js b/server/core/Reader/BookConverter/ConvertHtml.js index facb1954..4131436f 100644 --- a/server/core/Reader/BookConverter/ConvertHtml.js +++ b/server/core/Reader/BookConverter/ConvertHtml.js @@ -39,16 +39,19 @@ class ConvertHtml extends ConvertBase { let title = ''; let inTitle = false; + let inSubTitle = false; let inImage = false; let image = {}; let bold = false; let italic = false; + let begining = true; let spaceCounter = []; const repCrLfTab = (text) => text.replace(/[\n\r]/g, '').replace(/\t/g, ' '); const newParagraph = () => { + begining = false; pars.push({_n: 'p', _t: ''}); }; @@ -58,6 +61,8 @@ class ConvertHtml extends ConvertBase { const l = pars.length; pars[l - 1]._t += text; + if (inSubTitle) + pars[l - 1]._n = ''; //посчитаем отступы у текста, чтобы выделить потом параграфы const lines = text.split('\n'); @@ -77,16 +82,21 @@ class ConvertHtml extends ConvertBase { } }; - const newPara = new Set(['tr', '/table', 'hr', 'br', 'br/', 'li', 'dt', 'dd', 'p', 'title', '/title', 'h1', 'h2', 'h3', '/h1', '/h2', '/h3']); + const newPara = new Set(['tr', '/table', 'hr', 'br', 'br/', 'li', 'dt', 'dd', 'p', 'title', '/title', 'ul', '/ul', 'h1', 'h2', 'h3', 'h4', 'h5', '/h1', '/h2', '/h3', '/h4', '/h5']); + const newPara2 = new Set(['h1', 'h2', 'h3', 'h4', 'h5']); const onTextNode = (text, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars text = this.escapeEntities(text); if (!cutCounter && !(cutTitle && inTitle)) { - let tOpen = (bold ? '' : ''); + let tOpen = ''; + tOpen += (inSubTitle ? '' : ''); + tOpen += (bold ? '' : ''); tOpen += (italic ? '' : ''); - let tClose = (italic ? '' : ''); + let tClose = '' + tClose += (italic ? '' : ''); tClose += (bold ? '' : ''); + tClose += (inSubTitle ? '' : ''); growParagraph(`${tOpen}${text}${tClose}`); } @@ -106,6 +116,8 @@ class ConvertHtml extends ConvertBase { const onStartNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars if (!cutCounter) { + if (newPara2.has(tag) && !begining) + newParagraph(); if (newPara.has(tag)) newParagraph(); @@ -130,6 +142,10 @@ class ConvertHtml extends ConvertBase { cutTitle = true; } + if (tag == 'subtitle') { + inSubTitle = true; + } + if (tag == 'fb2-image') { inImage = true; const attrs = sax.getAttrsSync(tail); @@ -141,6 +157,8 @@ class ConvertHtml extends ConvertBase { if (!cutCounter) { if (newPara.has('/' + tag)) newParagraph(); + if (newPara2.has('/' + tag)) + newParagraph(); switch (tag) { case 'i': @@ -160,6 +178,9 @@ class ConvertHtml extends ConvertBase { if (tag == 'title' || tag == 'cut-title') inTitle = false; + if (tag == 'subtitle') + inSubTitle = false; + if (tag == 'fb2-image') inImage = false; }; @@ -197,7 +218,8 @@ class ConvertHtml extends ConvertBase { while (i > 0 && (!spaceCounter[i] || spaceCounter[i] < total)) i--; } - const parIndent = (i > 0 ? i : 0); + let parIndent = (i > 0 ? i : 0); + if (parIndent > 2) parIndent--; let newPars = []; const newPar = () => { @@ -233,7 +255,7 @@ class ConvertHtml extends ConvertBase { l++; } - if (l >= parIndent) { + if (l >= parIndent || line == '') { if (j > 0) newPar(); j++; @@ -250,6 +272,7 @@ class ConvertHtml extends ConvertBase { //убираем лишнее, делаем валидный fb2, т.к. в рез-те разбиения на параграфы бьются теги bold = false; italic = false; + inSubTitle = false; pars = body.section._a[0]; for (let i = 0; i < pars.length; i++) { if (pars[i]._n != 'p') @@ -259,16 +282,24 @@ class ConvertHtml extends ConvertBase { if (pars[i]._t.indexOf('<') >= 0 || bold || italic) { const t = pars[i]._t; + let first = true; let a = []; const onTextNode = (text) => { - let tOpen = (bold ? '' : ''); + let tOpen = ''; + tOpen += (inSubTitle ? '' : ''); + tOpen += (bold ? '' : ''); tOpen += (italic ? '' : ''); - let tClose = (italic ? '' : ''); + let tClose = '' + tClose += (italic ? '' : ''); tClose += (bold ? '' : ''); + tClose += (inSubTitle ? '' : ''); + if (first) + text = text.replace(/^\s+/, ''); //trimLeft a.push(`${tOpen}${text}${tClose}`); + first = false; } const onStartNode = (tag) => { @@ -276,6 +307,8 @@ class ConvertHtml extends ConvertBase { bold = true; if (tag == 'emphasis') italic = true; + if (tag == 'subtitle') + inSubTitle = true; } const onEndNode = (tag) => { @@ -283,6 +316,8 @@ class ConvertHtml extends ConvertBase { bold = false; if (tag == 'emphasis') italic = false; + if (tag == 'subtitle') + inSubTitle = false; } sax.parseSync(t, { onStartNode, onEndNode, onTextNode }); diff --git a/server/core/Reader/BookConverter/ConvertSamlib.js b/server/core/Reader/BookConverter/ConvertSamlib.js index 5b095c07..f5023d76 100644 --- a/server/core/Reader/BookConverter/ConvertSamlib.js +++ b/server/core/Reader/BookConverter/ConvertSamlib.js @@ -102,6 +102,8 @@ class ConvertSamlib extends ConvertBase { case 'h1': case 'h2': case 'h3': + case 'h4': + case 'h5': if (inPara) closeTag('p'); openTag('p'); @@ -173,6 +175,8 @@ class ConvertSamlib extends ConvertBase { case 'h1': case 'h2': case 'h3': + case 'h4': + case 'h5': closeTag('p'); bold = false; break; diff --git a/server/core/Reader/BookConverter/ConvertSites.js b/server/core/Reader/BookConverter/ConvertSites.js index 96e756cf..5b9a608d 100644 --- a/server/core/Reader/BookConverter/ConvertSites.js +++ b/server/core/Reader/BookConverter/ConvertSites.js @@ -12,7 +12,10 @@ const sitesFilter = { converter: 'cutter', begin: ``, end: ``, - } + }, + 'flibusta.is': { + converter: 'flibusta' + }, }; class ConvertSites extends ConvertHtml { @@ -54,11 +57,11 @@ class ConvertSites extends ConvertHtml { if (m) title = m[1]; - return `${title.trim()}`; + return title.trim(); } cutter(text, opts) { - const title = this.getTitle(text); + const title = `${this.getTitle(text)}`; const l = text.indexOf(opts.begin) + opts.begin.length; const r = text.indexOf(opts.end); if (l < 0 || r < 0 || r <= l) @@ -66,6 +69,42 @@ class ConvertSites extends ConvertHtml { return text.substring(l, r) + title; } + + flibusta(text) { + let author = ''; + let m = text.match(/- ([\s\S]*?)<\/a>/); + if (m) + author = m[1]; + + let book = this.getTitle(text); + book = book.replace(' (fb2) | Флибуста', ''); + + const title = `${author}${(author ? ' - ' : '')}${book}`; + + let begin = '

'; + if (text.indexOf(begin) <= 0) + begin = '

'; + + const end = '

') + .replace(/

/g, '

') + .replace(/
/g, '

') + .replace(/

/g, '

') + .replace(/
/g, '

') + .replace(/<\/h3>/g, '
') + .replace(/<\/h5>/g, '
') + .replace(/
/g, '
') + .replace(/
/g, '
') + + title; + } } module.exports = ConvertSites;