import * as vscode from 'vscode'; import * as child_process from 'child_process'; import documentclass_symbols from '../dictionary/documentclass_symbols'; /** ${workspaceFolder} - the path of the workspace folder that contains the tasks.json file ${workspaceFolderBasename} - the name of the workspace folder that contains the tasks.json file without any slashes (/) ${file} - the current opened file ${relativeFile} - the current opened file relative to the workspace folder containing the file ${fileBasename} - the current opened file's basename ${fileBasenameNoExtension} - the current opened file's basename without the extension ${fileDirname} - the current opened file's dirname ${fileExtname} - the current opened file's extension ${cwd} - the task runner's current working directory on startup ${lineNumber} - the current selected line number in the active file */ function commandVariableSubstitution(variable: string, fileName: string): string { switch (variable) { case "${workspaceFolder}": return vscode.workspace.rootPath; case "${workspaceFolderBasename}": return vscode.workspace.rootPath; // TODO: case "${file}": return fileName; case "${relativeFile}": throw new Error("[ commandVariableSubstitution ] Not Implemented."); case "${fileBasename}": return fileName.substring(fileName.lastIndexOf('/') + 1); case "${fileBasenameNoExtension}": return fileName.substring(fileName.lastIndexOf('/') + 1, fileName.lastIndexOf('.')); case "${fileDirname}": return fileName.substring(0, fileName.lastIndexOf('/')); case "${fileExtname}": return fileName.substring(fileName.lastIndexOf('.') + 1); case "${cwd}": return vscode.workspace.rootPath; case "${lineNumber}": throw new Error("[ commandVariableSubstitution ] Not supported."); default: throw new Error("[ commandVariableSubstitution ] variable not found."); } } var decorationOptions: vscode.DecorationRenderOptions = { borderRadius: "3px", borderWidth: "1px", borderStyle: "solid", backgroundColor: "rgba(255,0,0,0.3)", borderColor: "rgba(255,100,100,0.15)" }; var LaTeX_error_decoration_type: vscode.TextEditorDecorationType = vscode.window.createTextEditorDecorationType(decorationOptions); export default { latex_pdflatex: function latex_pdflatex(textEditor: vscode.TextEditor, textEditorEdit: vscode.TextEditorEdit): void { function getHighliteLineNumbers(output: string): number[] { var lineNumbers: number[] = []; var outputLines: string[] = output.split("\n"); for (let line = outputLines[0], i = 0; i < outputLines.length; line = outputLines[i++]) { if (line.startsWith("l.")) { var ln = Number.parseInt(line.substring(2, (line.indexOf(" ") + 1 || Infinity) - 1 )); if (lineNumbers.lastIndexOf(ln) < 0) { lineNumbers.push(ln); } } } return lineNumbers; } var document: vscode.TextDocument = textEditor.document; var fileName: string = this.settings.rootFile || document.fileName; var fileDir: string = fileName.substring(0, fileName.lastIndexOf('/')); var outputChannel: vscode.OutputChannel = this.outputChannel; outputChannel.clear(); // clear the outputChannel to only show the last output document.save(); // save the document before compile child_process.exec( // "pdflatex -synctex=1 -interaction=nonstopmode -output-directory=\"" + fileDir + "\" \"" + fileName + "\"", this.settings.pdflatex.replace(/\$\{[A-Za-z]+\}/g,(str) => commandVariableSubstitution(str, fileName)), { cwd: fileDir }, // set the working directory (error: Error, stdout: string, stderr: string) => { var decorationRanges: vscode.Range[] = []; if (error) { var output: string = stdout + "\n" + stderr; var lineNumbers = getHighliteLineNumbers(output); for (var i = 0; i < lineNumbers.length; i++) { decorationRanges.push(new vscode.Range( new vscode.Position(lineNumbers[i] - 1, 0), new vscode.Position(lineNumbers[i] - 1, 1000) )); } vscode.window.showErrorMessage("pdflatex Failed: see output."); outputChannel.show(); outputChannel.appendLine("pdflatex Failed: " + error.message); outputChannel.append(output); } else { vscode.window.setStatusBarMessage("pdflatex succeeded: see output", 5000); outputChannel.appendLine("pdflatex succeeded: created file " + fileName.replace('.tex', '.pdf')); } textEditor.setDecorations(LaTeX_error_decoration_type, decorationRanges); } ); }, latex_makeindex: function latex_makeindex(textEditor: vscode.TextEditor, textEditorEdit: vscode.TextEditorEdit): void { var document: vscode.TextDocument = textEditor.document; var fileDir: string = document.fileName.substring(0, document.fileName.lastIndexOf('/')); var outputChannel: vscode.OutputChannel = this.outputChannel; textEditor.document.save(); // save the document before makeindex child_process.exec( // "makeindex " + document.fileName.substring(document.fileName.lastIndexOf('/') + 1, document.fileName.lastIndexOf('.')), this.settings.makeindex.replace(/\$\{[A-Za-z]+\}/g, (str) => commandVariableSubstitution(str, document.fileName)), { cwd: fileDir }, // set the working directory (error: Error, stdout: string, stderr: string) => { if (error) { vscode.window.showErrorMessage("makeindex Failed: see output."); outputChannel.show(); outputChannel.appendLine("makeindex Failed: " + error.message); outputChannel.append(stdout + "\n" + stderr); } else { vscode.window.setStatusBarMessage("makeindex succeeded", 5000); outputChannel.appendLine("makeindex succeeded: created *.ind file\n" + stdout); } } ); } }