Добавлено распарсивание тега binary

This commit is contained in:
Book Pauk
2019-02-18 21:28:48 +07:00
parent 67bc893e22
commit 8d40ed0bda
2 changed files with 126 additions and 1 deletions

View File

@@ -37,6 +37,10 @@ export default class BookParser {
let center = false;
let bold = false;
let italic = false;
this.binary = {};
let binaryId = '';
let binaryType = '';
let dimPromises = [];
let paraIndex = -1;
let paraOffset = 0;
@@ -50,6 +54,28 @@ export default class BookParser {
addIndex: Number, //индекс добавляемого пустого параграфа (addEmptyParagraphs)
}
*/
const getImageDimensions = (binaryId, binaryType, data) => {
return new Promise (async(resolve, reject) => {
const i = new Image();
let resolved = false;
i.onload = () => {
resolved = true;
this.binary[binaryId] = {
w: i.width,
h: i.height,
type: binaryType,
data
};
resolve();
};
i.src = `data:${binaryType};base64,${data}`;
await sleep(30*1000);
if (!resolved)
reject('Не удалось получить размер изображения');
});
};
const newParagraph = (text, len, addIndex) => {
paraIndex++;
let p = {
@@ -103,13 +129,20 @@ export default class BookParser {
paraOffset += p.length;
};
const onStartNode = (elemName) => {// eslint-disable-line no-unused-vars
const onStartNode = (elemName, tail) => {// eslint-disable-line no-unused-vars
if (elemName == '?xml')
return;
tag = elemName;
path += '/' + elemName;
if (tag == 'binary') {
let attrs = sax.getAttrsSync(tail);
binaryType = (attrs['content-type'].value ? attrs['content-type'].value : '');
if (binaryType == 'image/jpeg' || binaryType == 'image/png')
binaryId = (attrs.id.value ? attrs.id.value : '');
}
if (path.indexOf('/fictionbook/body') == 0) {
if (tag == 'title') {
newParagraph(' ', 1);
@@ -146,6 +179,10 @@ export default class BookParser {
const onEndNode = (elemName) => {// eslint-disable-line no-unused-vars
if (tag == elemName) {
if (tag == 'binary') {
binaryId = '';
}
if (path.indexOf('/fictionbook/body') == 0) {
if (tag == 'title') {
bold = false;
@@ -245,6 +282,10 @@ export default class BookParser {
growParagraph(`${tOpen}${text}${tClose}`, text.length);
}
}
if (binaryId) {
dimPromises.push(getImageDimensions(binaryId, binaryType, text));
}
};
const onProgress = async(prog) => {
@@ -256,6 +297,13 @@ export default class BookParser {
onStartNode, onEndNode, onTextNode, onProgress
});
if (dimPromises.length) {
try {
await Promise.all(dimPromises);
} catch (e) {
}
}
this.fb2 = fb2;
this.para = para;

View File

@@ -276,7 +276,84 @@ async function parse(xstr, options) {
await _onProgress(100);
}
function getAttrsSync(tail) {
let result = {};
let name = '';
let value = '';
let vOpen = '';
let inName = false;
let inValue = false;
let waitValue = false;
let waitEq = false;
const pushResult = () => {
if (name != '') {
let ns = '';
if (name.indexOf(':') >= 0) {
[ns, name] = name.split(':');
}
result[name] = {value, ns};
}
name = '';
value = '';
vOpen = '';
inName = false;
inValue = false;
waitValue = false;
waitEq = false;
};
tail = tail.replace(/[\t\n\r]/g, ' ');
for (let i = 0; i < tail.length; i++) {
const c = tail.charAt(i);
if (c == ' ') {
if (inValue) {
if (vOpen == '"')
value += c;
else
pushResult();
} else if (inName) {
waitEq = true;
inName = false;
}
} else if (!inValue && c == '=') {
waitEq = false;
waitValue = true;
inName = false;
} else if (c == '"') {
if (inValue) {
pushResult();
} else if (waitValue) {
inValue = true;
vOpen = '"';
}
} else if (inValue) {
value += c;
} else if (inName) {
name += c;
} else if (waitEq) {
pushResult();
inName = true;
name = c;
} else if (waitValue) {
waitValue = false;
inValue = true;
vOpen = ' ';
value = c;
} else {
inName = true;
name = c;
}
}
if (name != '')
pushResult();
return result;
}
module.exports = {
parseSync,
getAttrsSync,
parse
}