├── icon.png ├── .gitignore ├── promotions └── preview.png ├── CHANGELOG.md ├── src └── index.ts ├── .vscodeignore ├── tsconfig.json ├── .eslintrc.json ├── .vscode ├── settings.json ├── tasks.json └── launch.json ├── style.css ├── notebook └── index.ts ├── esbuild-notebook.js ├── LICENSE ├── web.webpack.config.js ├── webpack.config.js ├── README.md └── package.json /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByPikod/vscode-markdown-alert/HEAD/icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | dist 3 | node_modules 4 | .vscode-test/ 5 | *.vsix 6 | dist-notebook/ 7 | -------------------------------------------------------------------------------- /promotions/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ByPikod/vscode-markdown-alert/HEAD/promotions/preview.png -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "vscode-markdown-alert" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import MarkdownIt from 'markdown-it'; 3 | import { alertPlugin } from 'markdown-it-github-alert'; 4 | 5 | export function activate() { 6 | return { 7 | extendMarkdownIt(md: MarkdownIt) { 8 | return md.use(alertPlugin); 9 | } 10 | }; 11 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/** 4 | node_modules/** 5 | src/** 6 | notebook/** 7 | dist-notebook/** 8 | .gitignore 9 | .yarnrc 10 | webpack.config.js 11 | web.webpack.config.js 12 | vsc-extension-quickstart.md 13 | **/tsconfig.json 14 | **/.eslintrc.json 15 | **/*.map 16 | **/*.ts 17 | esbuild-notebook.js 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "lib": [ 6 | "ES2020" 7 | ], 8 | "sourceMap": true, 9 | "rootDir": "src", 10 | "strict": true, /* enable all strict type-checking options */ 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "moduleResolution": "node" 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | ".vscode-test" 18 | ], 19 | "files": [ 20 | "./src/index.ts" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": [ 9 | "@typescript-eslint" 10 | ], 11 | "rules": { 12 | "@typescript-eslint/naming-convention": "warn", 13 | "@typescript-eslint/semi": "warn", 14 | "curly": "warn", 15 | "eqeqeq": "warn", 16 | "no-throw-literal": "warn", 17 | "semi": "off" 18 | }, 19 | "ignorePatterns": [ 20 | "out", 21 | "dist", 22 | "**/*.d.ts" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 5 | "dist": false // set this to true to hide the "dist" folder with the compiled JS files 6 | }, 7 | "search.exclude": { 8 | "out": true, // set this to false to include "out" folder in search results 9 | "dist": true // set this to false to include "dist" folder in search results 10 | }, 11 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 12 | "typescript.tsc.autoDetect": "off" 13 | } -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | .markdown-alert { 2 | padding: 1em; 3 | border-left: 0.25rem solid; 4 | padding-bottom: 0px; 5 | padding-top: 0px; 6 | border-color: var(--border-color); 7 | } 8 | 9 | .markdown-alert > span { 10 | display: flex; 11 | flex-direction: row; 12 | align-items: center; 13 | color: var(--border-color); 14 | font-weight: 500; 15 | } 16 | 17 | .markdown-alert .markdown-alert-icon { 18 | margin-right: 0.5em; 19 | fill: var(--border-color); 20 | } 21 | 22 | .markdown-alert.note { 23 | --border-color: #539BF5; 24 | } 25 | 26 | .markdown-alert.warning { 27 | --border-color: #C69026; 28 | } 29 | 30 | .markdown-alert.important { 31 | --border-color: #986EE2; 32 | } 33 | 34 | .markdown-alert.caution { 35 | --border-color: #E5534B; 36 | } 37 | 38 | .markdown-alert.tip { 39 | --border-color: #57AB5A; 40 | } 41 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$ts-webpack-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never", 13 | "group": "watchers" 14 | }, 15 | "group": { 16 | "kind": "build", 17 | "isDefault": true 18 | } 19 | }, 20 | { 21 | "type": "npm", 22 | "script": "watch-tests", 23 | "problemMatcher": "$tsc-watch", 24 | "isBackground": true, 25 | "presentation": { 26 | "reveal": "never", 27 | "group": "watchers" 28 | }, 29 | "group": "build" 30 | }, 31 | { 32 | "label": "tasks: watch-tests", 33 | "dependsOn": [ 34 | "npm: watch", 35 | "npm: watch-tests" 36 | ], 37 | "problemMatcher": [] 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /notebook/index.ts: -------------------------------------------------------------------------------- 1 | /*--------------------------------------------------------------------------------------------- 2 | * Copyright (c) Microsoft Corporation. All rights reserved. 3 | * Licensed under the MIT License. See License.txt in the project root for license information. 4 | *--------------------------------------------------------------------------------------------*/ 5 | import type MarkdownIt from 'markdown-it'; 6 | import type { RendererContext } from 'vscode-notebook-renderer'; 7 | import { alertPlugin } from 'markdown-it-github-alert'; 8 | 9 | export async function activate(ctx: RendererContext) { 10 | const markdownItRenderer = (await ctx.getRenderer('vscode.markdown-it-renderer')) as undefined | any; 11 | if (!markdownItRenderer) { 12 | throw new Error(`Could not load 'vscode.markdown-it-renderer'`); 13 | } 14 | 15 | markdownItRenderer.extendMarkdownIt((md: MarkdownIt) => { 16 | return md.use(alertPlugin); 17 | }); 18 | } -------------------------------------------------------------------------------- /esbuild-notebook.js: -------------------------------------------------------------------------------- 1 | const esbuild = require('esbuild'); 2 | const path = require('path'); 3 | 4 | const args = process.argv.slice(2); 5 | 6 | const isWatch = args.indexOf('--watch') >= 0; 7 | 8 | let outputRoot = __dirname; 9 | const outputRootIndex = args.indexOf('--outputRoot'); 10 | if (outputRootIndex >= 0) { 11 | outputRoot = args[outputRootIndex + 1]; 12 | } 13 | 14 | const srcDir = path.join(__dirname, 'notebook'); 15 | const outDir = path.join(outputRoot, 'dist-notebook'); 16 | 17 | async function build() { 18 | await esbuild.build({ 19 | entryPoints: [ 20 | path.join(srcDir, 'index.ts'), 21 | ], 22 | bundle: true, 23 | minify: true, 24 | sourcemap: false, 25 | format: 'esm', 26 | outdir: outDir, 27 | platform: 'browser', 28 | target: ['es2020'], 29 | }); 30 | } 31 | 32 | 33 | build().catch(() => process.exit(1)); 34 | 35 | if (isWatch) { 36 | const watcher = require('@parcel/watcher'); 37 | watcher.subscribe(srcDir, () => { 38 | return build(); 39 | }); 40 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Yahya Batulu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/dist/**/*.js" 17 | ], 18 | "preLaunchTask": "${defaultBuildTask}", 19 | "sourceMaps": true 20 | }, 21 | { 22 | "name": "Run Web Extension in VS Code", 23 | "type": "pwa-extensionHost", 24 | "debugWebWorkerHost": true, 25 | "request": "launch", 26 | "args": [ 27 | "--extensionDevelopmentPath=${workspaceFolder}", 28 | "--extensionDevelopmentKind=web" 29 | ], 30 | "outFiles": [ 31 | "${workspaceFolder}/dist/web/**/*.js" 32 | ] 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /web.webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | //@ts-check 5 | /** @typedef {import('webpack').Configuration} WebpackConfig **/ 6 | 7 | module.exports = /** @type WebpackConfig */ { 8 | mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') 9 | target: 'webworker', // extensions run in a webworker context 10 | entry: { 11 | 'index': './src/index.ts', // source of the web extension main file 12 | }, 13 | output: { 14 | filename: '[name].js', 15 | path: path.join(__dirname, 'dist', 'web'), 16 | libraryTarget: 'commonjs' 17 | }, 18 | resolve: { 19 | mainFields: ['browser', 'module', 'main'], // look for `browser` entry point in imported node modules 20 | extensions: ['.ts', '.js'], // support ts-files and js-files 21 | }, 22 | module: { 23 | rules: [{ 24 | test: /\.ts$/, 25 | exclude: /node_modules/, 26 | use: [{ 27 | loader: 'ts-loader' 28 | }] 29 | }] 30 | }, 31 | externals: { 32 | 'vscode': 'commonjs vscode', // ignored because it doesn't exist 33 | }, 34 | performance: { 35 | hints: false 36 | }, 37 | devtool: 'nosources-source-map' // create a source map that points to the original source file 38 | }; -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | 'use strict'; 4 | 5 | const path = require('path'); 6 | 7 | //@ts-check 8 | /** @typedef {import('webpack').Configuration} WebpackConfig **/ 9 | 10 | /** @type WebpackConfig */ 11 | const extensionConfig = { 12 | target: 'node', // VS Code extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ 13 | mode: 'none', // this leaves the source code as close as possible to the original (when packaging we set this to 'production') 14 | 15 | entry: './src/index.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ 16 | output: { 17 | // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ 18 | path: path.resolve(__dirname, 'dist'), 19 | filename: 'index.js', 20 | libraryTarget: 'commonjs2' 21 | }, 22 | externals: { 23 | vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/ 24 | // modules added here also need to be added in the .vscodeignore file 25 | }, 26 | resolve: { 27 | // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader 28 | extensions: ['.ts', '.js'] 29 | }, 30 | module: { 31 | rules: [ 32 | { 33 | test: /\.ts$/, 34 | exclude: /node_modules/, 35 | use: [ 36 | { 37 | loader: 'ts-loader' 38 | } 39 | ] 40 | } 41 | ] 42 | }, 43 | devtool: 'nosources-source-map', 44 | infrastructureLogging: { 45 | level: "log", // enables logging required for problem matchers 46 | }, 47 | }; 48 | module.exports = [ extensionConfig ]; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VS Code Markdown Alert 2 | 3 | This is a VS Code extension that allows you to preview GitHub's alert syntax for markdown files. This feature first introduced in [this discussion post](https://github.com/orgs/community/discussions/16925). And this extension is the first implementation of this feature in VS Code. 4 | 5 | You can install the extension from [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=yahyabatulu.vscode-markdown-alert). 6 | 7 | Syntax below, 8 | 9 | ```MD 10 | > [!NOTE] 11 | > Hello, world! 12 | ``` 13 | 14 | should look like this, 15 | 16 | > [!NOTE] 17 | > Hello, world! 18 | 19 | And this it looks like in VS Code via this extension, 20 | 21 | ![Example](promotions/preview.png) 22 | 23 | ## How does it work? 24 | 25 | For those who are interested in how this extension works, here is a brief explanation. 26 | 27 | VS Code uses a javascript library named [markdown-it](https://github.com/markdown-it/markdown-it) to render markdown files. This library allows you to add custom rules to the markdown parser. This extension adds a custom rule to the parser to render GitHub's alert syntax using [markdown-it-github-alert](https://github.com/ByPikod/markdown-it-github-alert) plugin of Markdown-it which is also written by me. 28 | 29 | For further information, you can check out the source code of this extension and the plugin. 30 | 31 | ## Contribute 32 | 33 | Contribution 34 | 35 | We welcome and appreciate contributions from the community! To contribute to this project, follow these steps: 36 | 37 | * Fork the repository. 38 | * Create a new branch for your feature or bug fix. 39 | * Make your changes and ensure they pass any existing tests. 40 | * Open a pull request with a clear title and description. 41 | * Participate in the code review process. 42 | 43 | Thank you for helping make this project better! 44 | 45 | ## Copyright 46 | 47 | This project is licensed under the terms of the MIT License. 48 | 49 | You are free to use this project in compliance with the MIT License. If you decide to use, modify, or redistribute this software, you must include a copy of the original license and copyright notice in all copies or substantial portions of the software. 50 | 51 | For more information about the MIT License, visit: [MIT License](LICENSE). 52 | 53 | **Enjoy!** 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.0.4", 3 | "name": "vscode-markdown-alert", 4 | "displayName": "Markdown Preview for Github Alerts", 5 | "description": "VS Code Github Alert Syntax for Markdown Previews", 6 | "publisher": "yahyabatulu", 7 | "license": "MIT", 8 | "icon": "icon.png", 9 | "main": "./dist/index.js", 10 | "browser": "./dist/web/index.js", 11 | "author": { 12 | "name": "Yahya Batulu", 13 | "email": "admin@yahyabatulu.com", 14 | "url": "https://www.yahyabatulu.com" 15 | }, 16 | "engines": { 17 | "vscode": "^1.83.0" 18 | }, 19 | "categories": [ 20 | "Other" 21 | ], 22 | "keywords": [ 23 | "markdown", 24 | "alert", 25 | "github", 26 | "syntax", 27 | "preview", 28 | "vscode", 29 | "extension", 30 | "plugin", 31 | "markdown-it" 32 | ], 33 | "homepage": "https://github.com/ByPikod/vscode-markdown-alert", 34 | "bugs": { 35 | "url": "https://github.com/ByPikod/vscode-markdown-alert/issues" 36 | }, 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/ByPikod/vscode-markdown-alert" 40 | }, 41 | "activationEvents": [], 42 | "contributes": { 43 | "markdown.markdownItPlugins": true, 44 | "markdown.previewStyles": [ 45 | "style.css" 46 | ], 47 | "notebookRenderer": [ 48 | { 49 | "id": "bypikod.markdown-it-alert-extension", 50 | "displayName": "Markdown IT Alert Renderer", 51 | "entrypoint": { 52 | "extends": "vscode.markdown-it-renderer", 53 | "path": "./dist-notebook/notebook.js" 54 | } 55 | } 56 | ] 57 | }, 58 | "scripts": { 59 | "clean": "rimraf ./dist ./dist-notebook ./out ./out-test", 60 | "vscode:prepublish": "npm run clean && npm run package && npm run package-web && npm run package-notebook", 61 | "compile": "webpack", 62 | "watch": "webpack --watch", 63 | "watch-web": "webpack --watch --config ./web.webpack.config.js", 64 | "package": "webpack --mode production --devtool hidden-source-map", 65 | "package-web": "webpack --mode production --devtool hidden-source-map --config ./web.webpack.config.js", 66 | "package-notebook": "node ./esbuild-notebook", 67 | "pretest": "npm run compile-tests && npm run compile && npm run lint", 68 | "lint": "eslint src --ext ts" 69 | }, 70 | "devDependencies": { 71 | "@types/markdown-it": "^13.0.5", 72 | "@types/node": "18.x", 73 | "@types/vscode": "^1.83.0", 74 | "@types/vscode-notebook-renderer": "^1.72.2", 75 | "@typescript-eslint/eslint-plugin": "^6.7.3", 76 | "@typescript-eslint/parser": "^6.7.3", 77 | "@vscode/test-electron": "^2.3.4", 78 | "esbuild": "^0.19.5", 79 | "eslint": "^8.50.0", 80 | "glob": "^10.3.3", 81 | "rimraf": "^5.0.5", 82 | "ts-loader": "^9.4.4", 83 | "typescript": "^5.2.2", 84 | "webpack": "^5.89.0", 85 | "webpack-cli": "^5.1.4" 86 | }, 87 | "dependencies": { 88 | "markdown-it": "^13.0.2", 89 | "markdown-it-github-alert": "^1.0.6" 90 | } 91 | } --------------------------------------------------------------------------------