Compare commits

...

19 Commits
0.7.7 ... 0.7.8

Author SHA1 Message Date
Book Pauk
549ef91c81 Merge branch 'release/0.7.8' 2019-11-25 15:39:23 +07:00
Book Pauk
cede65313b Версия 0.7.8 2019-11-25 15:38:52 +07:00
Book Pauk
d897a7400f Улучшение парсера fb2 2019-11-25 15:36:34 +07:00
Book Pauk
47f059213f Добавлен конвертер для flibusta 2019-11-25 15:21:33 +07:00
Book Pauk
8af51bbf08 Улучшение фильтра html 2019-11-25 15:15:06 +07:00
Book Pauk
53d9f5ddc6 Улучшение конвертирования html->fb2 2019-11-24 15:36:11 +07:00
Book Pauk
06fffdccc8 Merge tag '0.7.7d' into develop
0.7.7d
2019-11-18 20:04:03 +07:00
Book Pauk
aa13dc68fc Merge branch 'release/0.7.7d' 2019-11-18 20:03:46 +07:00
Book Pauk
813876dd90 Поправлены мета-теги 2019-11-18 20:03:09 +07:00
Book Pauk
596c7d65c5 Merge tag '0.7.7c' into develop
0.7.7c
2019-11-16 18:05:56 +07:00
Book Pauk
ce8dcb75bf Merge branch 'release/0.7.7c' 2019-11-16 18:05:40 +07:00
Book Pauk
1bd51b5565 Поправил robots.txt 2019-11-16 18:04:48 +07:00
Book Pauk
1f9ec305b4 Merge tag '0.7.7b' into develop
0.7.7b
2019-11-13 19:42:30 +07:00
Book Pauk
be0f6e57d7 Merge branch 'release/0.7.7b' 2019-11-13 19:42:21 +07:00
Book Pauk
b268e9ee74 Улучшение парсинга html 2019-11-13 19:41:20 +07:00
Book Pauk
e97774435b Merge tag '0.7.7a' into develop
0.7.7a
2019-11-08 17:21:17 +07:00
Book Pauk
93586bc5bb Merge branch 'release/0.7.7a' 2019-11-08 17:21:03 +07:00
Book Pauk
fe23089714 Небольшие поправки верстки 2019-11-08 17:20:31 +07:00
Book Pauk
e743986f38 Merge tag '0.7.7' into develop
0.7.7
2019-11-06 20:18:02 +07:00
10 changed files with 128 additions and 29 deletions

View File

@@ -1,3 +1,2 @@
User-agent: * User-agent: *
Disallow: /?*url= Disallow: /?*url=
Disallow: /#/

View File

@@ -1,6 +1,6 @@
<template> <template>
<div ref="main" class="main"> <div ref="main" class="main">
<div class="part"> <div class="part top">
<span class="greeting bold-font">{{ title }}</span> <span class="greeting bold-font">{{ title }}</span>
<div class="space"></div> <div class="space"></div>
<span class="greeting">Добро пожаловать!</span> <span class="greeting">Добро пожаловать!</span>
@@ -14,6 +14,7 @@
</el-input> </el-input>
<div class="space"></div> <div class="space"></div>
<input type="file" id="file" ref="file" @change="loadFile" style='display: none;'/> <input type="file" id="file" ref="file" @change="loadFile" style='display: none;'/>
<el-button size="mini" @click="loadFileClick"> <el-button size="mini" @click="loadFileClick">
Загрузить файл с диска Загрузить файл с диска
</el-button> </el-button>
@@ -21,14 +22,17 @@
<el-button size="mini" @click="loadBufferClick"> <el-button size="mini" @click="loadBufferClick">
Из буфера обмена Из буфера обмена
</el-button> </el-button>
<div class="space"></div> <div class="space"></div>
<div class="space"></div> <div class="space"></div>
<div v-if="mode == 'omnireader'" ref="yaShare2" class="ya-share2" <div v-if="mode == 'omnireader'">
<div ref="yaShare2" class="ya-share2"
data-services="collections,vkontakte,facebook,odnoklassniki,twitter,telegram" data-services="collections,vkontakte,facebook,odnoklassniki,twitter,telegram"
data-description="Чтение fb2-книг онлайн. Загрузка любой страницы интернета одним кликом, синхронизация между устройствами, удобное управление, регистрация не требуется." data-description="Чтение fb2-книг онлайн. Загрузка любой страницы интернета одним кликом, синхронизация между устройствами, удобное управление, регистрация не требуется."
data-title="Omni Reader - браузерная онлайн-читалка" data-title="Omni Reader - браузерная онлайн-читалка"
data-url="https://omnireader.ru"> data-url="https://omnireader.ru">
</div> </div>
</div>
<div class="space"></div> <div class="space"></div>
<span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openComments">Отзывы о читалке</span> <span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openComments">Отзывы о читалке</span>
<span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openOldVersion">Старая версия</span> <span v-if="mode == 'omnireader'" class="bottom-span clickable" @click="openOldVersion">Старая версия</span>
@@ -184,7 +188,7 @@ class LoaderPage extends Vue {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 400px; min-height: 480px;
} }
.part { .part {
@@ -210,9 +214,14 @@ class LoaderPage extends Vue {
cursor: pointer; cursor: pointer;
} }
.top {
min-height: 120px;
}
.center { .center {
justify-content: flex-start; justify-content: flex-start;
padding: 0 10px 0 10px; padding: 0 10px 0 10px;
min-height: 250px;
} }
.bottom { .bottom {

View File

@@ -240,6 +240,7 @@ export default class BookParser {
newParagraph(' ', 1); newParagraph(' ', 1);
isFirstTitlePara = true; isFirstTitlePara = true;
bold = true; bold = true;
center = true;
} }
if (tag == 'epigraph') { if (tag == 'epigraph') {
@@ -282,6 +283,7 @@ export default class BookParser {
if (tag == 'subtitle') { if (tag == 'subtitle') {
isFirstTitlePara = false; isFirstTitlePara = false;
bold = false; bold = false;
center = false;
} }
if (tag == 'epigraph') { if (tag == 'epigraph') {
@@ -367,11 +369,10 @@ export default class BookParser {
tClose += (bold ? '</strong>' : ''); tClose += (bold ? '</strong>' : '');
tClose += (center ? '</center>' : ''); tClose += (center ? '</center>' : '');
if (path.indexOf('/fictionbook/body/title') == 0) { if (path.indexOf('/fictionbook/body/title') == 0 ||
growParagraph(`${tOpen}${text}${tClose}`, text.length); path.indexOf('/fictionbook/body/section') == 0 ||
} path.indexOf('/fictionbook/body/epigraph') == 0
) {
if (path.indexOf('/fictionbook/body/section') == 0) {
growParagraph(`${tOpen}${text}${tClose}`, text.length); growParagraph(`${tOpen}${text}${tClose}`, text.length);
} }

View File

@@ -1,4 +1,15 @@
export const versionHistory = [ export const versionHistory = [
{
showUntil: '2019-11-24',
header: '0.7.8 (2019-11-25)',
content:
`
<ul>
<li>улучшение html-фильтров для сайтов</li>
</ul>
`
},
{ {
showUntil: '2019-11-10', showUntil: '2019-11-10',
header: '0.7.7 (2019-11-06)', header: '0.7.7 (2019-11-06)',

View File

@@ -3,8 +3,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="description" content="браузерная онлайн-читалка книг из интернета и библиотека"> <meta name="description" content="Браузерная онлайн-читалка книг. Поддерживаются форматы: fb2, html, txt, rtf, doc, docx, pdf, epub, mobi.">
<meta name="keywords" content="библиотека,онлайн,читалка,книги,читать,браузер,интернет"> <meta name="keywords" content="онлайн,читалка,fb2,книги,читать,браузер,интернет">
<title></title> <title></title>
</head> </head>
<body> <body>

View File

@@ -1,6 +1,6 @@
{ {
"name": "Liberama", "name": "Liberama",
"version": "0.7.7", "version": "0.7.8",
"engines": { "engines": {
"node": ">=10.0.0" "node": ">=10.0.0"
}, },

View File

@@ -82,7 +82,7 @@ class ConvertBase {
} }
escapeEntities(text) { escapeEntities(text) {
return he.escape(he.decode(text)); return he.escape(he.decode(text.replace(/&nbsp;/g, ' ')));
} }
formatFb2(fb2) { formatFb2(fb2) {

View File

@@ -39,16 +39,19 @@ class ConvertHtml extends ConvertBase {
let title = ''; let title = '';
let inTitle = false; let inTitle = false;
let inSubTitle = false;
let inImage = false; let inImage = false;
let image = {}; let image = {};
let bold = false; let bold = false;
let italic = false; let italic = false;
let begining = true;
let spaceCounter = []; let spaceCounter = [];
const repCrLfTab = (text) => text.replace(/[\n\r]/g, '').replace(/\t/g, ' '); const repCrLfTab = (text) => text.replace(/[\n\r]/g, '').replace(/\t/g, ' ');
const newParagraph = () => { const newParagraph = () => {
begining = false;
pars.push({_n: 'p', _t: ''}); pars.push({_n: 'p', _t: ''});
}; };
@@ -58,12 +61,15 @@ class ConvertHtml extends ConvertBase {
const l = pars.length; const l = pars.length;
pars[l - 1]._t += text; pars[l - 1]._t += text;
if (inSubTitle)
pars[l - 1]._n = '';
//посчитаем отступы у текста, чтобы выделить потом параграфы //посчитаем отступы у текста, чтобы выделить потом параграфы
const lines = text.split('\n'); const lines = text.split('\n');
for (let line of lines) { for (let line of lines) {
if (line.trim() == '') if (line.trim() == '')
continue; continue;
line = repCrLfTab(line); line = repCrLfTab(line);
let l = 0; let l = 0;
@@ -76,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 const onTextNode = (text, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
text = this.escapeEntities(text); text = this.escapeEntities(text);
if (!cutCounter && !(cutTitle && inTitle)) { if (!cutCounter && !(cutTitle && inTitle)) {
let tOpen = (bold ? '<strong>' : ''); let tOpen = '';
tOpen += (inSubTitle ? '<subtitle>' : '');
tOpen += (bold ? '<strong>' : '');
tOpen += (italic ? '<emphasis>' : ''); tOpen += (italic ? '<emphasis>' : '');
let tClose = (italic ? '</emphasis>' : ''); let tClose = ''
tClose += (italic ? '</emphasis>' : '');
tClose += (bold ? '</strong>' : ''); tClose += (bold ? '</strong>' : '');
tClose += (inSubTitle ? '</subtitle>' : '');
growParagraph(`${tOpen}${text}${tClose}`); growParagraph(`${tOpen}${text}${tClose}`);
} }
@@ -105,6 +116,8 @@ class ConvertHtml extends ConvertBase {
const onStartNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars const onStartNode = (tag, tail, singleTag, cutCounter, cutTag) => {// eslint-disable-line no-unused-vars
if (!cutCounter) { if (!cutCounter) {
if (newPara2.has(tag) && !begining)
newParagraph();
if (newPara.has(tag)) if (newPara.has(tag))
newParagraph(); newParagraph();
@@ -129,6 +142,10 @@ class ConvertHtml extends ConvertBase {
cutTitle = true; cutTitle = true;
} }
if (tag == 'subtitle') {
inSubTitle = true;
}
if (tag == 'fb2-image') { if (tag == 'fb2-image') {
inImage = true; inImage = true;
const attrs = sax.getAttrsSync(tail); const attrs = sax.getAttrsSync(tail);
@@ -140,6 +157,8 @@ class ConvertHtml extends ConvertBase {
if (!cutCounter) { if (!cutCounter) {
if (newPara.has('/' + tag)) if (newPara.has('/' + tag))
newParagraph(); newParagraph();
if (newPara2.has('/' + tag))
newParagraph();
switch (tag) { switch (tag) {
case 'i': case 'i':
@@ -159,6 +178,9 @@ class ConvertHtml extends ConvertBase {
if (tag == 'title' || tag == 'cut-title') if (tag == 'title' || tag == 'cut-title')
inTitle = false; inTitle = false;
if (tag == 'subtitle')
inSubTitle = false;
if (tag == 'fb2-image') if (tag == 'fb2-image')
inImage = false; inImage = false;
}; };
@@ -171,7 +193,6 @@ class ConvertHtml extends ConvertBase {
}); });
titleInfo['book-title'] = title; titleInfo['book-title'] = title;
//подозрение на чистый текст, надо разбить на параграфы //подозрение на чистый текст, надо разбить на параграфы
if (isText || pars.length < buf.length/2000) { if (isText || pars.length < buf.length/2000) {
let total = 0; let total = 0;
@@ -197,7 +218,8 @@ class ConvertHtml extends ConvertBase {
while (i > 0 && (!spaceCounter[i] || spaceCounter[i] < total)) i--; 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 = []; let newPars = [];
const newPar = () => { const newPar = () => {
@@ -233,7 +255,7 @@ class ConvertHtml extends ConvertBase {
l++; l++;
} }
if (l >= parIndent) { if (l >= parIndent || line == '') {
if (j > 0) if (j > 0)
newPar(); newPar();
j++; j++;
@@ -250,6 +272,7 @@ class ConvertHtml extends ConvertBase {
//убираем лишнее, делаем валидный fb2, т.к. в рез-те разбиения на параграфы бьются теги //убираем лишнее, делаем валидный fb2, т.к. в рез-те разбиения на параграфы бьются теги
bold = false; bold = false;
italic = false; italic = false;
inSubTitle = false;
pars = body.section._a[0]; pars = body.section._a[0];
for (let i = 0; i < pars.length; i++) { for (let i = 0; i < pars.length; i++) {
if (pars[i]._n != 'p') if (pars[i]._n != 'p')
@@ -257,17 +280,26 @@ class ConvertHtml extends ConvertBase {
pars[i]._t = this.repSpaces(pars[i]._t).trim(); pars[i]._t = this.repSpaces(pars[i]._t).trim();
if (pars[i]._t.indexOf('<') >= 0) { if (pars[i]._t.indexOf('<') >= 0 || bold || italic) {
const t = pars[i]._t; const t = pars[i]._t;
let first = true;
let a = []; let a = [];
const onTextNode = (text) => { const onTextNode = (text) => {
let tOpen = (bold ? '<strong>' : ''); let tOpen = '';
tOpen += (inSubTitle ? '<subtitle>' : '');
tOpen += (bold ? '<strong>' : '');
tOpen += (italic ? '<emphasis>' : ''); tOpen += (italic ? '<emphasis>' : '');
let tClose = (italic ? '</emphasis>' : ''); let tClose = ''
tClose += (italic ? '</emphasis>' : '');
tClose += (bold ? '</strong>' : ''); tClose += (bold ? '</strong>' : '');
tClose += (inSubTitle ? '</subtitle>' : '');
if (first)
text = text.replace(/^\s+/, ''); //trimLeft
a.push(`${tOpen}${text}${tClose}`); a.push(`${tOpen}${text}${tClose}`);
first = false;
} }
const onStartNode = (tag) => { const onStartNode = (tag) => {
@@ -275,6 +307,8 @@ class ConvertHtml extends ConvertBase {
bold = true; bold = true;
if (tag == 'emphasis') if (tag == 'emphasis')
italic = true; italic = true;
if (tag == 'subtitle')
inSubTitle = true;
} }
const onEndNode = (tag) => { const onEndNode = (tag) => {
@@ -282,6 +316,8 @@ class ConvertHtml extends ConvertBase {
bold = false; bold = false;
if (tag == 'emphasis') if (tag == 'emphasis')
italic = false; italic = false;
if (tag == 'subtitle')
inSubTitle = false;
} }
sax.parseSync(t, { onStartNode, onEndNode, onTextNode }); sax.parseSync(t, { onStartNode, onEndNode, onTextNode });

View File

@@ -102,6 +102,8 @@ class ConvertSamlib extends ConvertBase {
case 'h1': case 'h1':
case 'h2': case 'h2':
case 'h3': case 'h3':
case 'h4':
case 'h5':
if (inPara) if (inPara)
closeTag('p'); closeTag('p');
openTag('p'); openTag('p');
@@ -173,6 +175,8 @@ class ConvertSamlib extends ConvertBase {
case 'h1': case 'h1':
case 'h2': case 'h2':
case 'h3': case 'h3':
case 'h4':
case 'h5':
closeTag('p'); closeTag('p');
bold = false; bold = false;
break; break;

View File

@@ -12,7 +12,10 @@ const sitesFilter = {
converter: 'cutter', converter: 'cutter',
begin: `<!-- BEGIN section where work skin applies -->`, begin: `<!-- BEGIN section where work skin applies -->`,
end: `<!-- END work skin -->`, end: `<!-- END work skin -->`,
} },
'flibusta.is': {
converter: 'flibusta'
},
}; };
class ConvertSites extends ConvertHtml { class ConvertSites extends ConvertHtml {
@@ -54,11 +57,11 @@ class ConvertSites extends ConvertHtml {
if (m) if (m)
title = m[1]; title = m[1];
return `<title>${title.trim()}</title>`; return title.trim();
} }
cutter(text, opts) { cutter(text, opts) {
const title = this.getTitle(text); const title = `<title>${this.getTitle(text)}</title>`;
const l = text.indexOf(opts.begin) + opts.begin.length; const l = text.indexOf(opts.begin) + opts.begin.length;
const r = text.indexOf(opts.end); const r = text.indexOf(opts.end);
if (l < 0 || r < 0 || r <= l) if (l < 0 || r < 0 || r <= l)
@@ -66,6 +69,42 @@ class ConvertSites extends ConvertHtml {
return text.substring(l, r) + title; return text.substring(l, r) + title;
} }
flibusta(text) {
let author = '';
let m = text.match(/- <a href=".+">([\s\S]*?)<\/a><br\/?>/);
if (m)
author = m[1];
let book = this.getTitle(text);
book = book.replace(' (fb2) | Флибуста', '');
const title = `<title>${author}${(author ? ' - ' : '')}${book}</title>`;
let begin = '<h3 class="book">';
if (text.indexOf(begin) <= 0)
begin = '<h3 class=book>';
const end = '<div id="footer">';
const l = text.indexOf(begin);
const r = text.indexOf(end);
if (l < 0 || r < 0 || r <= l)
return false;
return text.substring(l, r)
.replace(/blockquote class="?book"?/g, 'p')
.replace(/<br\/?>\s*<\/h3>/g, '</h3>')
.replace(/<h3 class="?book"?>/g, '<br><br><subtitle>')
.replace(/<h5 class="?book"?>/g, '<br><br><subtitle>')
.replace(/<h3>/g, '<br><br><subtitle>')
.replace(/<h5>/g, '<br><br><subtitle>')
.replace(/<\/h3>/g, '</subtitle><br>')
.replace(/<\/h5>/g, '</subtitle><br>')
.replace(/<div class="?stanza"?>/g, '<br>')
.replace(/<div>/g, '<br>')
+ title;
}
} }
module.exports = ConvertSites; module.exports = ConvertSites;