From c111ec89a0311f3287b6366cb40fb158f5fb16f4 Mon Sep 17 00:00:00 2001 From: CismonX Date: Sat, 23 Oct 2021 02:35:49 +0800 Subject: [PATCH] Normalize paths. --- src/diagnosis.ts | 18 ++++++++++++++---- src/utils/converter.ts | 36 +++++++++++++----------------------- src/utils/misc.ts | 30 ++++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/diagnosis.ts b/src/diagnosis.ts index 7172adf..78c1a77 100644 --- a/src/diagnosis.ts +++ b/src/diagnosis.ts @@ -19,8 +19,9 @@ * vscode-texinfo. If not, see . */ +import * as path from 'path'; import * as vscode from 'vscode'; -import { lineNumToRange } from './utils/misc'; +import { escapeStringForRegExp, lineNumToRange } from './utils/misc'; import { isDefined } from './utils/types'; /** @@ -44,10 +45,19 @@ export default class Diagnosis implements vscode.Disposable * @param logText */ update(document: vscode.TextDocument, logText: string) { - const fileName = document.uri.path; + const fileName = path.basename(document.uri.path); + const regex = new RegExp(`${escapeStringForRegExp(fileName)}:\\d+:`); const diagnostics = logText.split('\n') - .filter(line => line.startsWith(fileName)) - .map(line => logToDiagnostic(line.substring(fileName.length + 1))) + .map(line => line.length > 0 ? line.match(regex) : null) + .map(result => { + const index = result?.index; + const line = result?.input; + if (index === undefined || line === undefined) { + return undefined; + } + const logText = line.substring(index + fileName.length + 1); + return logToDiagnostic(logText); + }) .filter(isDefined); this._diagnostics.set(document.uri, diagnostics); } diff --git a/src/utils/converter.ts b/src/utils/converter.ts index e21711f..66904d4 100644 --- a/src/utils/converter.ts +++ b/src/utils/converter.ts @@ -23,7 +23,7 @@ import * as path from 'path'; import * as vscode from 'vscode'; import Logger from '../logger'; import Options from '../options'; -import { exec } from './misc'; +import { exec, normalizePath } from './misc'; import { Operator } from './types'; /** @@ -32,8 +32,8 @@ import { Operator } from './types'; export default class Converter { async toHTML(imgTransformer: Operator, insertScript?: string) { - const pathUri = vscode.Uri.file(path.dirname(this._path)); - const newPath = imgTransformer(pathUri).toString() + '/'; + const pathUri = vscode.Uri.file(path.dirname(this._pathName) + '/'); + const newPath = normalizePath(imgTransformer(pathUri).toString()); const options = ['-o-', '--no-split', '--html', `--error-limit=${this._options.errorLimit}`, `--init-file=${this._initFile}`, @@ -51,34 +51,22 @@ export default class Converter this._includeCustomCSS(this._options.customCSS, options); return await exec( this._options.makeinfo, - options.concat(this._path), + options.concat(normalizePath(this._pathName)), this._options.maxSize, ); } constructor( - path: string, + private readonly _pathName: string, private readonly _initFile: string, private readonly _options: Options, private readonly _logger: Logger, - ) { - if (process.platform === 'win32') { - // TODO: - // On Windows, when passing the path of input file to makeinfo, - // using backslashes in path name breaks some other command line - // options (notably, -I). - // Not sure if this is a bug of makeinfo, or perl, or neither. - // We should look into this issue sometime later. - this._path = path.replace(/\\/g, '/'); - } else { - this._path = path; - } - } - - private readonly _path: string; + ) {} private _addIncludePaths(paths: readonly string[], options: string[]) { - if (paths.length === 0) return; + if (paths.length === 0) { + return; + } const separator = process.platform === 'win32' ? ';' : ':'; options.push('-I', paths.join(separator)); } @@ -88,12 +76,14 @@ export default class Converter } private _includeCustomCSS(cssFileURI: string, options: string[]) { - if (!cssFileURI) return; + if (!cssFileURI) { + return; + } try { const uri = vscode.Uri.parse(cssFileURI, true); switch (uri.scheme) { case 'file': - options.push(`--css-include=${uri.path}`); + options.push(`--css-include=${normalizePath(uri.fsPath)}`); break; case 'http': case 'https': diff --git a/src/utils/misc.ts b/src/utils/misc.ts index f7fa82f..3b6db4b 100644 --- a/src/utils/misc.ts +++ b/src/utils/misc.ts @@ -20,9 +20,20 @@ */ import * as child_process from 'child_process'; +import * as path from 'path'; import * as vscode from 'vscode'; import { ExecResult } from './types'; +/** + * Escape string to match verbatim in regular expression. + * + * @param str The string to be escaped. + * @returns The escaped string. + */ +export function escapeStringForRegExp(str: string) { + return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + /** * Execute command and fetch output. * @@ -94,8 +105,8 @@ export function isAlnum(charCode: number) { /** * Get corresponding HTML cross-reference name by node name. * - * See section *HTML Cross-reference Node Name Expansion* in - * the Texinfo manual. + * See section *HTML Cross-reference Node Name Expansion* in the + * GNU Texinfo manual. * * TODO: Node name is not displayed verbatim, leading to wrong HTML xref when * containing commands. Fix this when migrating to LSP. @@ -116,3 +127,18 @@ export function getNodeHtmlRef(nodeName: string) { ? result : 'g_t_00' + firstCharCode.toString(16) + result.substring(1); } + +export function normalizePath(pathName: string) { + pathName = path.normalize(pathName); + if (process.platform === 'win32') { + // On Windows, when passing the path of input file to makeinfo, + // using backslashes in path name breaks some other command line + // options (notably, -I). + // Not sure if this is a bug of makeinfo, or perl, or neither. + // + // TODO: We should look into this issue sometime later. + return pathName.replace(/\\/g, '/'); + } else { + return pathName; + } +}