Переглянути джерело

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

Book Pauk 6 роки тому
батько
коміт
8d40ed0bda

+ 49 - 1
client/components/Reader/share/BookParser.js

@@ -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;
 

+ 77 - 0
server/core/BookConverter/sax.js

@@ -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
 }