diff --git a/client/components/Reader/ContentsPage/ContentsPage.vue b/client/components/Reader/ContentsPage/ContentsPage.vue index bb0a0bea..317a2980 100644 --- a/client/components/Reader/ContentsPage/ContentsPage.vue +++ b/client/components/Reader/ContentsPage/ContentsPage.vue @@ -67,6 +67,7 @@
+
{{ item.num }}
JPG
PNG
INET
@@ -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 : 'Без названия'); 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; diff --git a/client/components/Reader/share/BookParser.js b/client/components/Reader/share/BookParser.js index b1f60615..500a64bc 100644 --- a/client/components/Reader/share/BookParser.js +++ b/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(`${' '.repeat(maxImageLineCount)}`, 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(`${' '.repeat(maxImageLineCount)}`, maxImageLineCount); - this.images.push({paraIndex, num: imageNum, id, local}); + this.images.push({paraIndex, num: imageNum, id, local, alt}); } } } diff --git a/server/core/Reader/BookConverter/ConvertDjvu.js b/server/core/Reader/BookConverter/ConvertDjvu.js index 22f899f2..35a87e8e 100644 --- a/server/core/Reader/BookConverter/ConvertDjvu.js +++ b/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})); } } diff --git a/server/core/Reader/BookConverter/ConvertJpegPng.js b/server/core/Reader/BookConverter/ConvertJpegPng.js index 8a8debeb..dda3a943 100644 --- a/server/core/Reader/BookConverter/ConvertJpegPng.js +++ b/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: ''});