diff --git a/ext/html-preview.pm b/ext/html-preview.pm
new file mode 100644
index 0000000..324d5c6
--- /dev/null
+++ b/ext/html-preview.pm
@@ -0,0 +1,43 @@
+#
+# ext/html-preview.pm
+#
+# Copyright (C) 2021 CismonX
+#
+# This file is part of vscode-texinfo.
+#
+# vscode-texinfo is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# vscode-texinfo is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# vscode-texinfo. If not, see .
+#
+
+use strict;
+
+sub vscode_convert_texinfo_image_uri {
+ my ( $self, $cmdname, $command, $args ) = @_;
+
+ my $filename = $args->[0]->{'monospacetext'};
+ if ( defined($filename)
+ && rindex( $filename, 'http://', 0 ) == -1
+ && rindex( $filename, 'https://', 0 ) == -1 )
+ {
+ $self->set_conf( 'IMAGE_LINK_PREFIX',
+ $self->{'parser'}->{'values'}->{'__vscode_texinfo_image_uri_base'}
+ );
+ }
+ return &{ $self->default_commands_conversion($cmdname) }
+ ( $self, $cmdname, $command, $args );
+}
+
+texinfo_register_command_formatting( 'image',
+ \&vscode_convert_texinfo_image_uri );
+
+1;
diff --git a/package-lock.json b/package-lock.json
index d288a91..ebbe001 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1440,12 +1440,6 @@
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==",
"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==",
- "dev": true
- },
"hosted-git-info": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz",
@@ -1966,15 +1960,6 @@
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
- "node-html-parser": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/node-html-parser/-/node-html-parser-2.2.1.tgz",
- "integrity": "sha512-Vccqb62t6t7DkMVwqPQgb0NWO+gUMMDm+1X3LzqbtXLqjilCTtUYTlniKk08yuA1zIhEFVzu/dozpqs5KZbRFQ==",
- "dev": true,
- "requires": {
- "he": "1.2.0"
- }
- },
"node-releases": {
"version": "1.1.71",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
@@ -2749,9 +2734,9 @@
"dev": true
},
"ts-loader": {
- "version": "9.0.2",
- "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.0.2.tgz",
- "integrity": "sha512-whFcWsvFRb91lzLLwU06jKS8ZwQsXA7Rk2NNLBjWNDFoaZgfSjrh8UJvc7sMknR9Vhs6NroQlw+0+2wW3fjR9Q==",
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.1.0.tgz",
+ "integrity": "sha512-yjgM84n/NhzPbcAvvjGFihJxkXmwaUOQLcJezJqT9l/eD0CRcF6zu/dL21NTr4iyW47Rs4lJZawN/d3lSX07sw==",
"dev": true,
"requires": {
"chalk": "^4.1.0",
diff --git a/package.json b/package.json
index cecf813..55496a0 100644
--- a/package.json
+++ b/package.json
@@ -35,8 +35,7 @@
"json5": "^2.2.0",
"language-texinfo": "^1.0.0",
"minify-xml": "^2.5.0",
- "node-html-parser": "^2.2.1",
- "ts-loader": "^9.0.2",
+ "ts-loader": "^9.1.0",
"ts-node": "^9.1.1",
"typescript": "^4.2.4",
"vsce": "^1.87.0",
@@ -171,11 +170,6 @@
"minimum": 0,
"description": "Max number of errors before quit when trying to display preview."
},
- "texinfo.preview.localImage": {
- "type": "boolean",
- "default": false,
- "description": "Display local images in in preview."
- },
"texinfo.preview.maxSize": {
"type": "integer",
"default": 2,
diff --git a/scripts/package.sh b/scripts/package.sh
index c615f0c..2877fb5 100755
--- a/scripts/package.sh
+++ b/scripts/package.sh
@@ -23,7 +23,13 @@ sed -i '' -e '2d' package.json
json5 -o language-configuration.json{,}
# Remove comments from Markdown files.
sed -i '' -e '1,8d' README.md CHANGELOG.md
-cd ../..
+cd ext
+# Minify Perl scripts.
+if [ -x "$(command -v perltidy)" ]; then
+ perltidy --mangle -dac -b html-preview.pm
+ rm html-preview.pm.bak
+fi
+cd ../../..
# Re-package .vsix file.
node ./scripts/make-vsix.js $VSIX_FILE_NAME
diff --git a/src/contexts/preview.ts b/src/contexts/preview.ts
index 60c83ae..5589e26 100644
--- a/src/contexts/preview.ts
+++ b/src/contexts/preview.ts
@@ -24,7 +24,6 @@ import * as vscode from 'vscode';
import DocumentContext from './document';
import Converter from '../utils/converter';
import { getNodeHtmlRef, prompt } from '../utils/misc';
-import { Operator, Optional } from '../utils/types';
/**
* Stores information of a Texinfo document preview.
@@ -56,8 +55,9 @@ export default class PreviewContext {
this.pendingUpdate = false;
// Inform the user that the preview is updating if `makeinfo` takes too long.
setTimeout(() => this.updating && this.updateTitle(), 500);
- const { data, error } = await new Converter(this.document.fileName, this.globalContext.options, this.logger)
- .convertToHtml(this.imageTransformer, this.script);
+ const initFile = this.globalContext.extensionPath + '/ext/html-preview.pm';
+ const converter = new Converter(this.document.fileName, initFile, this.globalContext.options, this.logger);
+ const { data, error } = await converter.toHTML(path => this.panel.webview.asWebviewUri(path), this.script);
if (error) {
this.logger.log(error);
this.diagnosis.update(this.document, error);
@@ -102,18 +102,6 @@ export default class PreviewContext {
*/
private updating = false;
- private get imageTransformer(): Optional> {
- if (!this.globalContext.options.localImage) return undefined;
- const pathName = path.dirname(this.document.fileName);
- return src => {
- // Do not transform URIs of online images.
- if (src.startsWith('https://') || src.startsWith('http://')) return src;
- const srcUri = vscode.Uri.file(pathName + '/' + src);
- // To display images in webviews, image URIs in HTML should be converted to VSCode-recognizable ones.
- return this.panel.webview.asWebviewUri(srcUri).toString();
- };
- }
-
/**
* Generate script used for jumping to the corresponding location of preview with code lens.
*/
diff --git a/src/global_context.ts b/src/global_context.ts
index 18e9f93..0f03d5f 100644
--- a/src/global_context.ts
+++ b/src/global_context.ts
@@ -36,13 +36,12 @@ import FoldingRangeProvider from './providers/folding_range';
export default class GlobalContext {
readonly contextMapping = new ContextMapping(this);
-
readonly diagnosis = new Diagnosis;
-
readonly indicator = new Indicator(this);
-
readonly logger = new Logger;
+ readonly extensionPath = this.context.extensionPath;
+
/**
* Note: `Options`' no singleton. Do not wire directly, always use `globalContext.options` instead.
*/
diff --git a/src/options.ts b/src/options.ts
index 5c54c87..cf46d68 100644
--- a/src/options.ts
+++ b/src/options.ts
@@ -52,10 +52,6 @@ export default class Options {
return this.getNumber('preview.errorLimit');
}
- get localImage() {
- return this.getBoolean('preview.localImage');
- }
-
get maxSize() {
return this.getNumber('preview.maxSize') * 1024 * 1024;
}
diff --git a/src/utils/converter.ts b/src/utils/converter.ts
index 813015d..cba6d19 100644
--- a/src/utils/converter.ts
+++ b/src/utils/converter.ts
@@ -19,10 +19,10 @@
* vscode-texinfo. If not, see .
*/
+ import * as path from 'path';
import * as vscode from 'vscode';
import Logger from '../logger';
import Options from '../options';
-import DOM from './dom';
import { exec } from './misc';
import { Operator } from './types';
@@ -31,25 +31,27 @@ import { Operator } from './types';
*/
export default class Converter {
- async convertToHtml(imgTransformer?: Operator, insertScript?: string) {
- const options = ['-o-', '--no-split', '--html', `--error-limit=${this.options.errorLimit}`];
+ async toHTML(imgTransformer: Operator, insertScript?: string) {
+ const newPath = imgTransformer(vscode.Uri.file(path.dirname(this.path))).toString() + '/';
+ const options = ['-o-', '--no-split', '--html', `--error-limit=${this.options.errorLimit}`,
+ `--init-file=${this.initFile}`, '-D', `__vscode_texinfo_image_uri_base ${newPath}`];
this.options.noHeaders && options.push('--no-headers');
this.options.noValidation && options.push('--no-validate');
this.options.noWarnings && options.push('--no-warn');
+ if (insertScript !== undefined) {
+ options.push('--set-customization-variable', `EXTRA_HEAD `);
+ }
this.includeCustomCSS(this.options.customCSS, options);
this.addVars(this.options.vars, options);
- const result = await exec(this.options.makeinfo, options.concat(this.path), this.options.maxSize);
- if (result.data !== undefined) {
- // No worry about performance here, as the DOM is lazily initialized.
- const dom = new DOM(result.data);
- imgTransformer && dom.transformImageUri(imgTransformer);
- insertScript && dom.insertScript(insertScript);
- result.data = dom.outerHTML;
- }
- return result;
+ return await exec(this.options.makeinfo, options.concat(this.path), this.options.maxSize);
}
- constructor(private readonly path: string, private readonly options: Options, private readonly logger: Logger) {}
+ constructor(
+ private readonly path: string,
+ private readonly initFile: string,
+ private readonly options: Options,
+ private readonly logger: Logger,
+ ) {}
private addVars(vars: readonly string[], options: string[]) {
vars.forEach(varName => options.push('-D', varName));
diff --git a/src/utils/dom.ts b/src/utils/dom.ts
deleted file mode 100644
index 55ec77c..0000000
--- a/src/utils/dom.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * utils/dom.ts
- *
- * Copyright (C) 2020,2021 CismonX
- *
- * This file is part of vscode-texinfo.
- *
- * vscode-texinfo is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation, either version 3 of the License, or (at your option)
- * any later version.
- *
- * vscode-texinfo is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * vscode-texinfo. If not, see .
- */
-
-import * as htmlparser from 'node-html-parser';
-import { Operator } from './types';
-
-/**
- * Parse HTML into DOM and transform elements.
- */
-export default class DOM {
-
- get outerHTML() {
- if (this.changed) {
- this.html = this.value.outerHTML;
- this.changed = false;
- }
- return this.html;
- }
-
- insertScript(script: string) {
- this.value.querySelector('head').insertAdjacentHTML('beforeend', ``);
- this.changed = true;
- }
-
- /**
- * Transform and replace the `src` attribute value of all `img` elements from HTML using given function.
- *
- * @param transformer
- */
- transformImageUri(transformer: Operator) {
- const elements = this.value.querySelectorAll('img');
- if (elements.length === 0) return;
- elements.forEach(element => {
- const src = element.getAttribute('src');
- src && element.setAttribute('src', transformer(src));
- });
- this.changed = true;
- }
-
- constructor(private html: string) {}
-
- private _value?: htmlparser.HTMLElement;
-
- private changed = false;
-
- private get value() {
- return this._value ??= htmlparser.parse(this.html);
- }
-}