Работа над парсером, промежуточный коммит

This commit is contained in:
Book Pauk
2019-01-16 01:54:14 +07:00
parent f07f11930c
commit cd2d429012
2 changed files with 195 additions and 6 deletions

View File

@@ -1,7 +1,8 @@
<template> <template>
<div ref="main" class="main"> <div ref="main" class="main">
<pre>{{ bookPos }}</pre> <p v-for="item in items" :key="item.id">
<pre>{{ meta }}</pre> {{ item.text }}
</p>
</div> </div>
</template> </template>
@@ -23,10 +24,10 @@ export default @Component({
}) })
class TextPage extends Vue { class TextPage extends Vue {
lastBook = null; lastBook = null;
meta = null;
fb2 = null;
bookPos = 0; bookPos = 0;
items = null;
created() { created() {
this.commit = this.$store.commit; this.commit = this.$store.commit;
this.dispatch = this.$store.dispatch; this.dispatch = this.$store.dispatch;
@@ -39,6 +40,7 @@ class TextPage extends Vue {
this.book = null; this.book = null;
this.meta = null; this.meta = null;
this.fb2 = null; this.fb2 = null;
this.parsed = null;
this.drawPage();//пока не загрузили, очистим канвас this.drawPage();//пока не загрузили, очистим канвас
@@ -60,6 +62,17 @@ class TextPage extends Vue {
this.fb2.bookTitle this.fb2.bookTitle
]).join(' ')); ]).join(' '));
const parsed = this.book.parsed;
parsed.p = 30;//px, отступ параграфа
parsed.w = 300;//px, ширина страницы
parsed.measureText = (text, style) => {
if (style == 'bold')
return text.length*12;
else
return text.length*10;
};
this.parsed = parsed;
this.drawPage(); this.drawPage();
})(); })();
} }
@@ -70,11 +83,33 @@ class TextPage extends Vue {
return; return;
//пустой канвас //пустой канвас
this.items = [];
if (!this.book) if (!this.book)
return; return;
const lines = this.parsed.getLines(this.bookPos, 30);
let newItems = [];
for (const line of lines) {
/* line:
{
begin: Number,
end: Number,
parts: array of {
style: 'bold'|'italic',
text: String,
}
}*/
const item = {text: '', id: line.begin};
for (const part of line.parts) {
item.text += part.text;
}
newItems.push(item);
}
this.items = newItems;
} }
keyHook(event) { keyHook(event) {
@@ -88,4 +123,9 @@ class TextPage extends Vue {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
p {
margin: 0;
padding: 0;
}
</style> </style>

View File

@@ -4,6 +4,19 @@ import {sleep} from '../../../share/utils';
export default class BookParser { export default class BookParser {
constructor() { constructor() {
this.parser = new EasySAXParser(); this.parser = new EasySAXParser();
// defaults
this.p = 30;// px, отступ параграфа
this.w = 300;// px, ширина страницы
this.textAlignJustify = false;// выравнивание по ширине
this.wordWrap = false;// перенос по слогам, если textAlignJustify = true
// заглушка
this.measureText = (text, style) => {// eslint-disable-line no-unused-vars
return text.length*10;
};
// stuff
} }
async parse(data, callback) { async parse(data, callback) {
@@ -177,7 +190,7 @@ export default class BookParser {
await parser.parse(data); await parser.parse(data);
this.meta = fb2; this.fb2 = fb2;
this.para = para; this.para = para;
callback(100); callback(100);
@@ -185,4 +198,140 @@ export default class BookParser {
return {fb2}; return {fb2};
} }
findParaIndex(bookPos) {
let result = undefined;
//дихотомия
let first = 0;
let last = this.para.length - 1;
while (first < last) {
let mid = first + Math.floor((last - first)/2);
if (bookPos >= this.para[mid].offset)
last = mid;
else
first = mid + 1;
}
if (last >= 0) {
const ofs = this.para[last].offset;
if (bookPos >= ofs && bookPos < ofs + this.para[last].length)
result = last;
}
return result;
}
parsePara(paraIndex) {
const para = this.para[paraIndex];
if (para.parsed &&
para.parsed.w === this.w &&
para.parsed.p === this.p &&
para.parsed.textAlignJustify === this.textAlignJustify &&
para.parsed.wordWrap === this.wordWrap)
return para.parsed;
const parsed = {
w: this.w,
p: this.p,
textAlignJustify: this.textAlignJustify,
wordWrap: this.wordWrap
};
const lines = [];
/* array of
{
begin: Number,
end: Number,
parts: array of {
style: 'bold'|'italic',
text: String,
}
}*/
//
parsed.lines = lines;
para.parsed = parsed;
return parsed;
}
findLineIndex(bookPos, lines) {
let result = undefined;
//дихотомия
let first = 0;
let last = lines.length - 1;
while (first < last) {
let mid = first + Math.floor((last - first)/2);
if (bookPos >= lines[mid].begin)
last = mid;
else
first = mid + 1;
}
if (last >= 0) {
if (bookPos >= lines[last].begin && bookPos <= lines[last].end)
result = last;
}
return result;
}
getLines(bookPos, n) {
const result = [];
let paraIndex = this.findParaIndex(bookPos);
if (paraIndex === undefined)
return result;
if (n > 0) {
let parsed = this.parsePara(paraIndex);
let i = this.findLineIndex(bookPos, parsed.lines);
if (i === undefined)
return result;
while (n > 0) {
result.push(parsed.lines[i]);
i++;
if (i >= parsed.lines.length) {
paraIndex++;
if (paraIndex < this.para.length)
parsed = this.parsePara(paraIndex);
else
return result;
i = 0;
}
n--;
}
} else if (n < 0) {
n = -n;
let parsed = this.parsePara(paraIndex);
let i = this.findLineIndex(bookPos, parsed.lines);
if (i === undefined)
return result;
while (n > 0) {
result.push(parsed.lines[i]);
i--;
if (i > 0) {
paraIndex--;
if (paraIndex >= this.para.length)
parsed = this.parsePara(paraIndex);
else
return result;
i = parsed.lines.length - 1;
}
n--;
}
}
return result;
}
} }