From 41463857d0c08838366177f5887c1d3d3eb7a160 Mon Sep 17 00:00:00 2001 From: Dynasty 11 Dev Date: Mon, 23 Sep 2024 16:52:24 -0400 Subject: [PATCH] updated readme and added auto-refresh support --- .github/workflows/build-extension.yml | 39 +++++ .github/workflows/publish-extension.yml | 36 ++++ CHANGELOG.md | 54 +++--- README.md | 55 +++--- package-lock.json | 4 +- package.json | 16 +- src/extension.ts | 217 ++++++++++++++---------- vsc-extension-quickstart.md | 45 +++-- 8 files changed, 291 insertions(+), 175 deletions(-) create mode 100644 .github/workflows/build-extension.yml create mode 100644 .github/workflows/publish-extension.yml diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml new file mode 100644 index 0000000..387a01c --- /dev/null +++ b/.github/workflows/build-extension.yml @@ -0,0 +1,39 @@ +name: Build extension + +on: + push: + branches: ["fix-readme"] + +jobs: + build: + runs-on: ubuntu-latest + name: Build and package + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Use Node.js 20 + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: "npm" + registry-url: https://registry.npmjs.org/ + - name: Install dependencies + run: npm ci + - name: Get NPM Version + id: package-version + uses: martinbeentjes/npm-get-version-action@v1.3.1 + - name: Build extension + run: vsce package -o postscript-preview-${{ steps.package-version.outputs.current-version }}.vsix + - name: Upload a Build Artifact + uses: actions/upload-artifact@v3 + with: + name: postscript-preview-${{ steps.package-version.outputs.current-version }}.vsix + path: postscript-preview-${{ steps.package-version.outputs.current-version }}.vsix + if-no-files-found: error + - name: Create release with artifact + if: ${{ success() && steps.package-version.outputs.current-version }} + uses: softprops/action-gh-release@v1 + with: + name: Release v${{ steps.package-version.outputs.current-version }} + draft: true + files: postscript-preview-${{ steps.package-version.outputs.current-version }}.vsix diff --git a/.github/workflows/publish-extension.yml b/.github/workflows/publish-extension.yml new file mode 100644 index 0000000..8ae928f --- /dev/null +++ b/.github/workflows/publish-extension.yml @@ -0,0 +1,36 @@ +name: Publish extension + +on: + release: + types: [published] + +jobs: + openvsx: + name: "Open VSX Registry" + if: endsWith(github.event.release.assets[0].name, '.vsix') + runs-on: ubuntu-latest + steps: + - name: Download release artifact + run: "curl -L -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' -H 'Accept: application/octet-stream' ${{ github.event.release.assets[0].url }} --output extension.vsix" + # - name: Validate extension file + # run: unzip -f extension.vsix extension/package.json + # - name: Publish to Open VSX Registry + # uses: HaaLeo/publish-vscode-extension@v1 + # with: + # pat: ${{ secrets.OPEN_VSX_TOKEN }} + # extensionFile: extension.vsix + vs: + name: "Visual Studio Marketplace" + if: endsWith(github.event.release.assets[0].name, '.vsix') + runs-on: ubuntu-latest + steps: + - name: Download release artifact + run: "curl -L -H 'Authorization: token ${{ secrets.GITHUB_TOKEN }}' -H 'Accept: application/octet-stream' ${{ github.event.release.assets[0].url }} --output extension.vsix" + # - name: Validate extension file + # run: unzip -f extension.vsix extension/package.json + # - name: Publish to Visual Studio Marketplace + # uses: HaaLeo/publish-vscode-extension@v1 + # with: + # pat: ${{ secrets.VS_MARKETPLACE_TOKEN }} + # registryUrl: https://marketplace.visualstudio.com + # extensionFile: extension.vsix diff --git a/CHANGELOG.md b/CHANGELOG.md index 1decac0..25139e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,60 +1,50 @@ # Change Log +## [0.4.3] - 2024-09-23 +- Fixed README issues +- Added doc to pin to version 0.89.0 for poppler on Windows +- Added auto-refresh capability ## [0.4.0] - 2021-11-11 -- Fixed pdf conversion error -- Updated README with new instructions - - +- Fixed pdf conversion error +- Updated README with new instructions ## [0.3.2] - 2021-11-11 -- Fixed README instructions -- Version bump - - +- Fixed README instructions +- Version bump ## [0.3.1] - 2021-10-22 -- Version bump - - +- Version bump ## [0.3.0] - 2021-10-11 -- Fixed controller scrolling -- Added instructions for Ubuntu install - - +- Fixed controller scrolling +- Added instructions for Ubuntu install ## [0.2.3] - 2021-10-09 -- Added option to hide controls -- Fixed container sizing issue -- Switched controller positioning - - +- Added option to hide controls +- Fixed container sizing issue +- Switched controller positioning ## [0.2.1] - 2021-10-08 -- Fixed requirement instructions - - +- Fixed requirement instructions ## [0.2.0] - 2021-10-08 -- Added support for SVG Pan and Zoom -- Added support for changing background color of preview window - -- Fixed issue with Windows 10 preview +- Added support for SVG Pan and Zoom +- Added support for changing background color of preview window - +- Fixed issue with Windows 10 preview ## [0.1.0] - 2020-07-19 -- Basic functionality of EPS preview. -- A command to invoke the preview. -- A preview icon in the menu bar for open EPS file. -- README and CHANGELOG files. +- Basic functionality of EPS preview. +- A command to invoke the preview. +- A preview icon in the menu bar for open EPS file. +- README and CHANGELOG files. diff --git a/README.md b/README.md index c19203a..119b659 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,6 @@ Installs

- - -

Logo

@@ -15,15 +12,10 @@ Read Requirements After Install

-

PostScript Preview

- - > PostScript Preview is an extension that helps to **preview** EPS and PS files in [Visual Studio Code](https://code.visualstudio.com/). It supercharges how your view PostScript files by also allowing to **pan** and **zoom** the image. You can also change the preview background for extra **customizations**. - - ## Features This extension enables the in-VSCode preview of EPS image files. @@ -31,8 +23,6 @@ A new command `postscript-preview.sidePreview` is added as well as a preview ico demo - - ## Requirements This extension depends on the `PostScript Language` extension to recognize EPS/PS file. @@ -40,8 +30,8 @@ You can install that [extension](https://marketplace.visualstudio.com/items?item This extension also depends on two commands: -- `ps2pdf` - to first convert the EPS/PS file to PDF (the command is part of GhostScript) -- `pdftocairo` - to convert the generated pdf to svg which is shown in the preview +- `ps2pdf` - to first convert the EPS/PS file to PDF (the command is part of GhostScript) +- `pdftocairo` - to convert the generated pdf to svg which is shown in the preview Thus you need to install these two commands first and ensure they are in the executable path. @@ -51,6 +41,7 @@ You can install them via [homebrew](https://brew.sh/): ```bash brew install ghostscript +brew install poppler ``` ### **Ubuntu** @@ -59,6 +50,7 @@ You can install them using the following commands: ```bash sudo apt-get install ghostscript -y +sudo apt-get install poppler-utils -y ``` ### **Windows** @@ -66,14 +58,19 @@ sudo apt-get install ghostscript -y You need to have GhostScript installed in your system. You can install them via [Chocolatey](https://chocolatey.org/install). Run the following commands using an **Administrative PowerShell**. Installs GhostScript for _ps2pdf_ + ```bash choco install ghostscript --version 9.55.0 --force -y ``` + Installs _pdftocairo_ + ```bash -choco install poppler -y +choco install poppler --version 0.89.0 -y --force ``` + Adds the executables to the environment path + ```bash [Environment]::SetEnvironmentVariable("Path",[Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) + ";C:\Program Files\gs\gs9.55.0\lib;C:\Program Files\gs\gs9.55.0\bin;C:\ProgramData\chocolatey\lib\poppler\tools",[EnvironmentVariableTarget]::Machine) ``` @@ -87,19 +84,39 @@ C:\Program Files\gs\gs9.55.0\lib C:\Program Files\gs\gs9.55.0\bin C:\ProgramData\chocolatey\lib\poppler\tools ``` -_Please verify that you can view files in the above folders. If the folders do not exist, you might have run into issues with your installation. It's good to close Logitech GHUB and Logitech GHUB Updater when you install these as they might interfere with the process._ +_Please verify that you can view files in the above folders. If the folders do not exist, you might have run into issues with your installation. It's good to close Logitech GHUB and Logitech GHUB Updater when you install these as they might interfere with the process._ ## Known Issues -None yet. If you run into issues, please report them here: https://github.com/ahnafnafee/PostScript-Preview/issues +None yet. If you run into issues, please report them here: You are also encouraged to open pull requests for additional features and fixes you want to add to this extension. +## Credits + +- [mkvoya/eps-preview](https://github.com/mkvoya/eps-preview) for the original base extension +- [bumbu/svg-pan-zoom](https://github.com/bumbu/svg-pan-zoom) for the SVG Pan Zoom library +- [Simonwep/pickr](https://github.com/Simonwep/pickr) for the color picker library +## Installing Locally (for Development Purposes) -## Credits +Install the VSCode Publishing Extension + +```bash +npm install -g @vscode/vsce +``` + +Package the extension: + +```bash +vsce package +``` + +Publish the extension: + +```bash +vsce publish +``` -- [mkvoya/eps-preview](https://github.com/mkvoya/eps-preview) for the original base extension -- [bumbu/svg-pan-zoom](https://github.com/bumbu/svg-pan-zoom) for the SVG Pan Zoom library -- [Simonwep/pickr](https://github.com/Simonwep/pickr) for the color picker library +See published extensions here: diff --git a/package-lock.json b/package-lock.json index b95e4fe..05cdaca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "postscript-preview", - "version": "0.4.2", + "version": "0.4.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "postscript-preview", - "version": "0.4.2", + "version": "0.4.3", "dependencies": { "@types/temp": "^0.8.34", "temp": "^0.9.1" diff --git a/package.json b/package.json index d3bbd17..584aea0 100644 --- a/package.json +++ b/package.json @@ -2,15 +2,13 @@ "name": "postscript-preview", "displayName": "PostScript Preview", "description": "PostScript Preview is an extension that helps to preview EPS and PS files in Visual Studio Code.", - "version": "0.4.2", + "version": "0.4.3", "icon": "images/logo.png", "publisher": "ahnafnafee", "engines": { "vscode": "^1.46.0" }, - "categories": [ - "Other" - ], + "categories": ["Other"], "author": { "name": "Ahnaf An Nafee", "email": "ahnafnafee@gmail.com" @@ -19,12 +17,7 @@ "color": "#4B7D78", "theme": "dark" }, - "keywords": [ - "postscript", - "ghostscript", - "ps", - "preview" - ], + "keywords": ["postscript", "ghostscript", "ps", "preview"], "activationEvents": [ "onCommand:postscript-preview.sidePreview", "onLanguage:postscript" @@ -77,5 +70,8 @@ "repository": { "type": "git", "url": "https://github.com/ahnafnafee/PostScript-Preview.git" + }, + "sponsor": { + "url": "https://github.com/sponsors/ahnafnafee" } } diff --git a/src/extension.ts b/src/extension.ts index a6b700a..7aa0485 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,99 +1,138 @@ +// biome-ignore lint/style/useNodejsImportProtocol: +import { execSync } from "child_process"; // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below -import * as vscode from 'vscode'; -import { execSync } from 'child_process'; -import temp = require('temp'); -import fs = require('fs'); -import path = require('path'); -import {window, ExtensionContext, extensions, env, Uri} from "vscode"; +import * as vscode from "vscode"; +// biome-ignore lint/style/useImportType: +import { ExtensionContext, Uri, env, extensions, window } from "vscode"; +import temp = require("temp"); +// biome-ignore lint/style/useNodejsImportProtocol: +import fs = require("fs"); +// biome-ignore lint/style/useNodejsImportProtocol: +import path = require("path"); const extensionId = "ahnafnafee.postscript-preview"; +function generatePreview(filepath: string, panel: vscode.WebviewPanel) { + temp.track(); + temp.open( + { prefix: "postscript-preview-svg_", suffix: ".pdf" }, + (pdfErr, pdfInfo) => { + if (pdfErr) { + console.log("Creating temporary file eps-preview-pdf failed."); + return; + } + temp.open( + { prefix: "postscript-preview-svg_", suffix: ".svg" }, + (svgErr, svgInfo) => { + if (svgErr) { + console.log("Creating temporary file eps-preview-svg failed."); + return; + } + // Transform EPS to SVG + // Thank https://superuser.com/a/769466/502597. + try { + execSync(`ps2pdf -dEPSCrop "${filepath}" "${pdfInfo.path}"`); + } catch (err) { + vscode.window.showInformationMessage( + "Failed to execute ps2pdf. Report bug with postscript file to dev.", + ); + console.log("Error executing ps2pdf."); + console.log(err); + // Clean up + temp.cleanupSync(); + return; + } + try { + execSync( + `pdftocairo -svg -f 1 -l 1 "${pdfInfo.path}" "${svgInfo.path}"`, + ); + } catch (err) { + vscode.window.showInformationMessage( + "Failed to execute pdftocairo. Report bug with postscript file to dev.", + ); + console.log("Error executing pdftocairo."); + console.log(err); + // Clean up + temp.cleanupSync(); + return; + } + try { + const stat = fs.fstatSync(svgInfo.fd); + const svgContent = Buffer.alloc(stat.size); + fs.readSync(svgInfo.fd, svgContent, 0, stat.size, null); + // Show SVG in the webview panel + panel.webview.html = getWebviewContent( + path.basename(filepath), + svgContent, + ); + } catch (err) { + console.log("Error reading the final file."); + console.log(err); + } + }, + ); + }, + ); + + // Clean up + temp.cleanupSync(); +} + // this method is called when your extension is activated // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { - const isWindows = process.platform === "win32"; if (isWindows) { showWhatsNew(context); // show notification in case of a minor release i.e. 1.1.0 -> 1.2.0 } + const channel = vscode.window.createOutputChannel("PostScript-Preview"); + // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json - let disposable = vscode.commands.registerCommand('postscript-preview.sidePreview', () => { - - // Create new panel - let panel = vscode.window.createWebviewPanel('', 'PostScript Preview', - vscode.ViewColumn.Beside, - { - enableScripts: true - } - ); - - // Get the EPS content - const document = vscode.window.activeTextEditor?.document; - - if (!document) { - // No active document - console.log("No active document. Do nothing."); - return; - } - - const epsContent = document.getText(); - const filename = path.basename(document.fileName); - let mainFilePath = document.fileName; - - temp.track(); - temp.open({prefix: "postscript-preview-svg_", suffix: '.pdf'}, function (pdfErr, pdfInfo) { - if (pdfErr) { - console.log("Creating temporary file eps-preview-pdf failed."); + const disposable = vscode.commands.registerCommand( + "postscript-preview.sidePreview", + () => { + // Get the EPS content + const document = vscode.window.activeTextEditor?.document; + + if (!document) { + // No active document + console.log("No active document. Do nothing."); return; } - temp.open({prefix: "postscript-preview-svg_", suffix: '.svg'}, function (svgErr, svgInfo) { - if (svgErr) { - console.log("Creating temporary file eps-preview-svg failed."); - return; - } - // Transform EPS to SVG - // Thank https://superuser.com/a/769466/502597. - try { - execSync(`ps2pdf -dEPSCrop "${mainFilePath}" "${pdfInfo.path}"`); - } catch (err) { - vscode.window.showInformationMessage('Failed to execute ps2pdf. Report bug with postscript file to dev.'); - console.log("Error executing ps2pdf."); - console.log(err); - // Clean up - temp.cleanupSync(); - return; - } - try { - execSync(`pdftocairo -svg -f 1 -l 1 "${pdfInfo.path}" "${svgInfo.path}"`); - } catch (err) { - vscode.window.showInformationMessage('Failed to execute pdftocairo. Report bug with postscript file to dev.'); - console.log("Error executing pdftocairo."); - console.log(err); - // Clean up - temp.cleanupSync(); - return; - } - try { - const stat = fs.fstatSync(svgInfo.fd); - let svgContent = Buffer.alloc(stat.size); - fs.readSync(svgInfo.fd, svgContent, 0, stat.size, null); - // Show SVG in the webview panel - panel.webview.html = getWebviewContent(filename, svgContent); - } catch (err) { - console.log("Error reading the final file."); - console.log(err); - } - }); - }); - // Clean up - temp.cleanupSync(); - }); + const filename = path.basename(document.fileName); + const filePath = document.uri.fsPath; + + // Create new panel + const panel = vscode.window.createWebviewPanel( + "", + `PostScript Preview - ${filename}`, + vscode.ViewColumn.Beside, + { + enableScripts: true, + }, + ); + + const mainFilePath = document.fileName; + + generatePreview(mainFilePath, panel); + channel.appendLine(`Watching ${filePath}`); + const watcher = vscode.workspace.createFileSystemWatcher(filePath); + watcher.onDidChange((_: vscode.Uri) => { + channel.appendLine(`File changed, regenerating : ${filePath}`); + generatePreview(mainFilePath, panel); + }); + panel.onDidDispose(() => { + watcher.dispose(); + channel.appendLine(`Stop watching ${filePath}`); + }); + }, + ); context.subscriptions.push(disposable); } @@ -105,21 +144,23 @@ function isMajorUpdate(previousVersion: string, currentVersion: string) { return true; } //returns int array [1,1,1] i.e. [major,minor,patch] - var previousVerArr = previousVersion.split(".").map(Number); - var currentVerArr = currentVersion.split(".").map(Number); + const previousVerArr = previousVersion.split(".").map(Number); + const currentVerArr = currentVersion.split(".").map(Number); // For pdftocairo bug fix - if (currentVerArr[1] > previousVerArr[1] || currentVerArr[2] > previousVerArr[2]) { + if ( + currentVerArr[1] > previousVerArr[1] || + currentVerArr[2] > previousVerArr[2] + ) { return true; - } else { - return false; } + return false; } async function showWhatsNew(context: ExtensionContext) { const previousVersion = context.globalState.get(extensionId); - const currentVersion = extensions.getExtension(extensionId)!.packageJSON - .version; + const currentVersion = + extensions.getExtension(extensionId)?.packageJSON.version; // store latest version context.globalState.update(extensionId, currentVersion); @@ -128,20 +169,18 @@ async function showWhatsNew(context: ExtensionContext) { previousVersion === undefined || isMajorUpdate(previousVersion, currentVersion) ) { - // show whats new notificatin: + // show whats new notification: const actions = [{ title: "See Requirements" }]; const result = await window.showInformationMessage( `PostScript Preview v${currentVersion} — READ NEW REQUIREMENTS!`, - ...actions + ...actions, ); if (result !== null) { if (result === actions[0]) { await env.openExternal( - Uri.parse( - "https://github.com/ahnafnafee/PostScript-Preview#windows" - ) + Uri.parse("https://github.com/ahnafnafee/PostScript-Preview#windows"), ); } } @@ -151,7 +190,7 @@ async function showWhatsNew(context: ExtensionContext) { // this method is called when your extension is deactivated export function deactivate() {} - +// biome-ignore lint/suspicious/noExplicitAny: function getWebviewContent(fileName: any, svgContent: any) { return ` diff --git a/vsc-extension-quickstart.md b/vsc-extension-quickstart.md index b510bff..f488b2e 100644 --- a/vsc-extension-quickstart.md +++ b/vsc-extension-quickstart.md @@ -2,41 +2,40 @@ ## What's in the folder -* This folder contains all of the files necessary for your extension. -* `package.json` - this is the manifest file in which you declare your extension and command. - * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. -* `src/extension.ts` - this is the main file where you will provide the implementation of your command. - * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. - * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. +- This folder contains all of the files necessary for your extension. +- `package.json` - this is the manifest file in which you declare your extension and command. + - The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. +- `src/extension.ts` - this is the main file where you will provide the implementation of your command. + - The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. + - We pass the function containing the implementation of the command as the second parameter to `registerCommand`. ## Get up and running straight away -* Press `F5` to open a new window with your extension loaded. -* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. -* Set breakpoints in your code inside `src/extension.ts` to debug your extension. -* Find output from your extension in the debug console. +- Press `F5` to open a new window with your extension loaded. +- Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. +- Set breakpoints in your code inside `src/extension.ts` to debug your extension. +- Find output from your extension in the debug console. ## Make changes -* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. -* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. - +- You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. +- You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. ## Explore the API -* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. +- You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. ## Run tests -* Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. -* Press `F5` to run the tests in a new window with your extension loaded. -* See the output of the test result in the debug console. -* Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. - * The provided test runner will only consider files matching the name pattern `**.test.ts`. - * You can create folders inside the `test` folder to structure your tests any way you want. +- Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. +- Press `F5` to run the tests in a new window with your extension loaded. +- See the output of the test result in the debug console. +- Make changes to `src/test/suite/extension.test.ts` or create new test files inside the `test/suite` folder. + - The provided test runner will only consider files matching the name pattern `**.test.ts`. + - You can create folders inside the `test` folder to structure your tests any way you want. ## Go further - * Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). - * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. - * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). +- Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). +- [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VSCode extension marketplace. +- Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration).