Add support for displaying images in preview.
This commit is contained in:
parent
06248c86d2
commit
9fb645a4d1
|
@ -646,6 +646,11 @@
|
|||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
|
@ -796,6 +801,14 @@
|
|||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
|
||||
"dev": true
|
||||
},
|
||||
"node-html-parser": {
|
||||
"version": "1.2.21",
|
||||
"resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-1.2.21.tgz",
|
||||
"integrity": "sha512-6vDhgen6J332syN5HUmeT4FfBG7m6bFRrPN+FXY8Am7FGuVpsIxTASVbeoO5PF2IHbX2s+WEIudb1hgxOjllNQ==",
|
||||
"requires": {
|
||||
"he": "1.2.0"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
|
|
|
@ -80,6 +80,11 @@
|
|||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "Suppress warnings."
|
||||
},
|
||||
"texinfo.preview.displayImage": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"markdownDescription": "Whether to display images in in the preview."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -124,6 +129,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"cson": "^7.20.0",
|
||||
"language-texinfo": "^1.0.0"
|
||||
"language-texinfo": "^1.0.0",
|
||||
"node-html-parser": "^1.2.21"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { Options } from './options';
|
||||
import { exec } from './utils';
|
||||
import * as utils from './utils';
|
||||
|
||||
/**
|
||||
* Texinfo to HTML converter.
|
||||
|
@ -19,9 +19,8 @@ export class Converter {
|
|||
* @param path Path to the Texinfo document.
|
||||
* @yields HTML code, or `undefined` if conversion fails.
|
||||
*/
|
||||
static async convert(path: string) {
|
||||
const converter = new Converter(path);
|
||||
return await converter.convert();
|
||||
static async convertToHtml(path: string) {
|
||||
return await new Converter().convert(path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,18 +28,17 @@ export class Converter {
|
|||
*/
|
||||
private readonly options = ['-o', '-', '--no-split', '--html'];
|
||||
|
||||
private constructor(path: string) {
|
||||
private constructor() {
|
||||
Options.noHeaders && this.options.push('--no-headers');
|
||||
Options.force && this.options.push('--force');
|
||||
Options.noValidate && this.options.push('--no-validate');
|
||||
Options.noWarn && this.options.push('--no-warn');
|
||||
this.options.push(`--error-limit=${Options.errorLimit}`);
|
||||
this.options.push(path);
|
||||
}
|
||||
|
||||
private async convert() {
|
||||
private async convert(path: string) {
|
||||
const makeinfo = Options.makeinfo;
|
||||
const maxBuffer = Options.maxSize * 1024 * 1024;
|
||||
return await exec(makeinfo, this.options, maxBuffer);
|
||||
return await utils.exec(makeinfo, this.options.concat(path), maxBuffer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Preview } from './preview';
|
||||
import { Options } from './options';
|
||||
import { Preview } from './preview';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
|
|
|
@ -55,6 +55,10 @@ export class Options {
|
|||
return Options.instance.getBoolean('preview.noWarn');
|
||||
}
|
||||
|
||||
static get displayImage() {
|
||||
return Options.instance.getBoolean('preview.displayImage');
|
||||
}
|
||||
|
||||
private readonly configuration: vscode.WorkspaceConfiguration;
|
||||
|
||||
private constructor(section: string) {
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
* @license MIT
|
||||
*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { Converter } from './converter';
|
||||
import { prompt } from './utils';
|
||||
import { Options } from './options';
|
||||
import * as utils from './utils';
|
||||
|
||||
/**
|
||||
* Texinfo document preview.
|
||||
|
@ -25,7 +26,7 @@ export class Preview {
|
|||
static async show(editor: vscode.TextEditor) {
|
||||
const document = editor.document;
|
||||
if (document.isUntitled) {
|
||||
if (!await prompt('Save this document to display preview.', 'Save')) {
|
||||
if (!await utils.prompt('Save this document to display preview.', 'Save')) {
|
||||
return;
|
||||
}
|
||||
if (!await document.save()) {
|
||||
|
@ -108,10 +109,18 @@ export class Preview {
|
|||
this.pendingUpdate = false;
|
||||
this.updateTitle();
|
||||
|
||||
const htmlCode = await Converter.convert(this.document.fileName);
|
||||
let htmlCode = await Converter.convertToHtml(this.document.fileName);
|
||||
if (htmlCode === undefined) {
|
||||
vscode.window.showErrorMessage(`Failed to show preview for ${this.document.fileName}.`);
|
||||
} else {
|
||||
if (Options.displayImage) {
|
||||
const pathName = path.dirname(this.document.fileName);
|
||||
// To display images in webviews, image URIs in HTML should be converted to VSCode-recognizable ones.
|
||||
htmlCode = utils.transformHtmlImageUri(htmlCode, (src) => {
|
||||
const srcUri = vscode.Uri.file(pathName + '/' + src);
|
||||
return this.panel.webview.asWebviewUri(srcUri).toString();
|
||||
});
|
||||
}
|
||||
this.panel.webview.html = htmlCode;
|
||||
}
|
||||
this.updating = false;
|
||||
|
|
21
src/utils.ts
21
src/utils.ts
|
@ -5,8 +5,9 @@
|
|||
* @license MIT
|
||||
*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as child_process from 'child_process';
|
||||
import * as htmlparser from 'node-html-parser';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
/**
|
||||
* Open a prompt with two buttons, "Confirm" and "Cancel", and wait for user action.
|
||||
|
@ -42,3 +43,21 @@ export function exec(path: string, args: string[], maxBuffer: number) {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform and replace the `src` attribute value of all `img` elements from given HTML code using given function.
|
||||
*
|
||||
* @param htmlCode
|
||||
* @param transformer
|
||||
* @returns The HTML code after transformation.
|
||||
*/
|
||||
export function transformHtmlImageUri(htmlCode: string, transformer: (src: string) => string) {
|
||||
const dom = htmlparser.parse(htmlCode);
|
||||
const elements = dom.querySelectorAll('img');
|
||||
elements.forEach((element) => {
|
||||
const src = element.getAttribute('src');
|
||||
src && element.setAttribute('src', transformer(src));
|
||||
})
|
||||
// If nothing is transformed, return the original HTML code, for better performance.
|
||||
return elements.length === 0 ? htmlCode : dom.outerHTML;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue