Pārlūkot izejas kodu

Добавлен парсинг оглавления из djvu, добавлено отображение атрибута alt изображений в ContentsPage

Book Pauk 4 gadi atpakaļ
vecāks
revīzija
f5c06ce420

+ 7 - 2
client/components/Reader/ContentsPage/ContentsPage.vue

@@ -67,6 +67,7 @@
                             <img v-show="imageLoaded[item.id]" class="image-thumb" :src="imageSrc[item.id]"/>
                         </div>
                         <div class="no-expand-button column justify-center items-center">
+                            <div class="image-num">{{ item.num }}</div>
                             <div v-show="item.type == 'image/jpeg'" class="image-type it-jpg-color row justify-center">JPG</div>
                             <div v-show="item.type == 'image/png'" class="image-type it-png-color row justify-center">PNG</div>
                             <div v-show="!item.local" class="image-type it-net-color row justify-center">INET</div>
@@ -218,13 +219,13 @@ class ContentsPage extends ContentsPageProps {
             const bin = parsed.binary[image.id];
             const type = (bin ? bin.type : '');
             
-            const label = `Изображение ${image.num}`;
+            const label = (image.alt ? image.alt : '<span style="font-size: 90%; color: #dddddd"><i>Без названия</i></span>');
             const indentStyle = getIndentStyle(1);
             const labelStyle = getLabelStyle(0);
 
             const p = parsed.para[image.paraIndex];
             newImages.push({perc: (p.offset/parsed.textLength*100).toFixed(0), label, key: i, offset: p.offset,
-                indentStyle, labelStyle, type, id: image.id, local: image.local});
+                indentStyle, labelStyle, type, num: image.num, id: image.id, local: image.local});
         }
 
         this.images = newImages;
@@ -389,6 +390,10 @@ class ContentsPage extends ContentsPageProps {
     transform: rotate(90deg);
 }
 
+.image-num {
+    font-size: 120%;
+    padding-bottom: 3px;
+}
 .image-type {
     border: 1px solid black;
     border-radius: 6px;

+ 3 - 2
client/components/Reader/share/BookParser.js

@@ -205,6 +205,7 @@ export default class BookParser {
                 let attrs = sax.getAttrsSync(tail);
                 if (attrs.href && attrs.href.value) {
                     const href = attrs.href.value;
+                    const alt = (attrs.alt && attrs.alt.value ? attrs.alt.value : '');
                     const {id, local} = this.imageHrefToId(href);
                     if (href[0] == '#') {//local
                         imageNum++;
@@ -214,7 +215,7 @@ export default class BookParser {
                         else
                             newParagraph(`<image href="${href}" num="${imageNum}">${' '.repeat(maxImageLineCount)}</image>`, maxImageLineCount);
 
-                        this.images.push({paraIndex, num: imageNum, id, local});
+                        this.images.push({paraIndex, num: imageNum, id, local, alt});
 
                         if (inPara && this.showInlineImagesInCenter)
                             newParagraph(' ', 1);
@@ -224,7 +225,7 @@ export default class BookParser {
                         dimPromises.push(getExternalImageDimensions(href));
                         newParagraph(`<image href="${href}" num="${imageNum}">${' '.repeat(maxImageLineCount)}</image>`, maxImageLineCount);
 
-                        this.images.push({paraIndex, num: imageNum, id, local});
+                        this.images.push({paraIndex, num: imageNum, id, local, alt});
                     }
                 }
             }

+ 24 - 1
server/core/Reader/BookConverter/ConvertDjvu.js

@@ -22,6 +22,10 @@ class ConvertDjvu extends ConvertJpegPng {
         if (!await fs.pathExists(ddjvuPath))
             throw new Error('Внешний конвертер ddjvu не найден');
 
+        const djvusedPath = '/usr/bin/djvused';
+        if (!await fs.pathExists(djvusedPath))
+            throw new Error('Внешний конвертер djvused не найден');
+
         const tiffsplitPath = '/usr/bin/tiffsplit';
         if (!await fs.pathExists(tiffsplitPath))
             throw new Error('Внешний конвертер tiffsplitPath не найден');
@@ -67,8 +71,27 @@ class ConvertDjvu extends ConvertJpegPng {
 
         files.sort((a, b) => a.base.localeCompare(b.base));
 
+        //схема документа (outline)
+        const djvusedResult = await this.execConverter(djvusedPath, ['-u', '-e', 'print-outline', inputFiles.sourceFile]);
+        const outline = [];
+        const lines = djvusedResult.stdout.match(/\(".*"\s*?"#\d+".*?\)/g);
+        if (lines) {
+            lines.forEach(l => {
+                const m = l.match(/"(.*)"\s*?"#(\d+)"/);
+                if (m) {
+                    outline[m[2]] = m[1];
+                }
+            });
+        }
+
         await utils.sleep(100);
-        return await super.run(data, Object.assign({}, opts, {imageFiles: files.map(f => f.name)}));
+        let i = 0;
+        const imageFiles = files.map(f => {
+            i++;
+            let alt = (outline[i] ? outline[i] : '');
+            return {src: f.name, alt};
+        });
+        return await super.run(data, Object.assign({}, opts, {imageFiles}));
     }
 }
 

+ 9 - 6
server/core/Reader/BookConverter/ConvertJpegPng.js

@@ -27,7 +27,7 @@ class ConvertJpegPng extends ConvertBase {
         } else {
             const imageFile = `${inputFiles.filesDir}/${path.basename(inputFiles.sourceFile)}.${inputFiles.sourceFileType.ext}`;
             await fs.copy(inputFiles.sourceFile, imageFile);
-            files.push(imageFile);
+            files.push({src: imageFile});
         }
 
         //читаем изображения
@@ -55,10 +55,9 @@ class ConvertJpegPng extends ConvertBase {
 
         let images = [];
         let loading = [];
-        files.forEach(f => {
-            const image = {src: f};
-            images.push(image);
-            loading.push(loadImage(image));
+        files.forEach(img => {
+            images.push(img);
+            loading.push(loadImage(img));
         });
 
         await Promise.all(loading);
@@ -82,8 +81,12 @@ class ConvertJpegPng extends ConvertBase {
                 const img = {_n: 'binary', _attrs: {id: image.name, 'content-type': image.type}, _t: image.data};
                 binary.push(img);
 
+                const attrs = {'l:href': `#${image.name}`};
+                if (image.alt)
+                    attrs.alt = image.alt;
+
                 pars.push({_n: 'p', _t: ''});
-                pars.push({_n: 'image', _attrs: {'l:href': `#${image.name}`}});
+                pars.push({_n: 'image', _attrs: attrs});
             }
         }
         pars.push({_n: 'p', _t: ''});