├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ ├── config.yml │ └── feature_request.yml └── workflows │ ├── check.yml │ └── release.yml ├── .gitignore ├── .husky ├── commit-msg └── pre-commit ├── .prettierignore ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dev ├── CustomComponent.vue ├── browser.html ├── dev.vue ├── index.html ├── index.ts ├── shim.d.ts └── tsconfig.json ├── dist ├── vue-showdown.cjs.js ├── vue-showdown.d.ts ├── vue-showdown.esm.js ├── vue-showdown.esm.min.js ├── vue-showdown.js └── vue-showdown.min.js ├── docs ├── .vuepress │ ├── client.ts │ ├── config.ts │ ├── public │ │ ├── logo.png │ │ └── new.html │ └── styles │ │ └── index.scss ├── README.md ├── guide │ └── README.md ├── playground │ └── README.md └── zh │ ├── README.md │ ├── guide │ └── README.md │ └── playground │ └── README.md ├── eslint.config.js ├── logo └── logo.psd ├── package.json ├── pnpm-lock.yaml ├── rollup.config.js ├── src ├── index.ts ├── index.umd.ts ├── vue-showdown-plugin.ts └── vue-showdown.ts ├── tsconfig.base.json ├── tsconfig.json └── vite.config.ts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | *.txt text eol=crlf 3 | 4 | *.png binary 5 | *.jpg binary 6 | *.jpeg binary 7 | *.ico binary 8 | *.tff binary 9 | *.woff binary 10 | *.woff2 binary 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a report to help us improve 3 | title: '[Bug report] ' 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for taking the time to fill out this bug report! 9 | - type: textarea 10 | id: bug-description 11 | attributes: 12 | label: Description 13 | description: A clear and concise description of what the bug is. If you intend to submit a PR for this issue, tell us in the description. Thanks! 14 | placeholder: Bug description 15 | validations: 16 | required: true 17 | - type: input 18 | id: reproduction 19 | attributes: 20 | label: Reproduction 21 | description: Please provide a link via [vue-showdown.js.org/new](https://vue-showdown.js.org/new) or a link to a repo that can reproduce the problem you ran into. A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is required. 22 | placeholder: Reproduction 23 | validations: 24 | required: true 25 | - type: dropdown 26 | id: package-manager 27 | attributes: 28 | label: Used Package Manager 29 | description: Select the used package manager 30 | options: 31 | - npm 32 | - yarn 33 | - pnpm 34 | validations: 35 | required: true 36 | - type: textarea 37 | id: system-info 38 | attributes: 39 | label: System Info 40 | description: Output of `npx envinfo --system --npmPackages vue-showdown,vue,showdown --binaries --browsers` 41 | render: shell 42 | placeholder: System, Binaries, Browsers 43 | validations: 44 | required: true 45 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Question & Discussion 4 | url: https://github.com/meteorlxy/vue-showdown/discussions 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: Propose a new feature 3 | title: '[Feature request] ' 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Thanks for your interest in the project and taking the time to fill out this feature request! 9 | - type: textarea 10 | id: feature-description 11 | attributes: 12 | label: Clear and concise description of the problem 13 | description: As a developer using vue-showdown, what feature your want in details. If you intend to submit a PR for this issue, tell us in the description. Thanks! 14 | placeholder: Feature description 15 | validations: 16 | required: true 17 | - type: textarea 18 | id: suggested-solution 19 | attributes: 20 | label: Suggested solution 21 | description: We could provide following implementation... 22 | placeholder: Suggested solution 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: alternative 27 | attributes: 28 | label: Alternative 29 | description: Clear and concise description of any alternative solutions or features you've considered. 30 | placeholder: Alternative solution 31 | - type: textarea 32 | id: additional-context 33 | attributes: 34 | label: Additional context 35 | description: Any other context or screenshots about the feature request here. 36 | -------------------------------------------------------------------------------- /.github/workflows/check.yml: -------------------------------------------------------------------------------- 1 | name: check 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | check: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Install pnpm 18 | uses: pnpm/action-setup@v4 19 | 20 | - name: Setup Node.js 21 | uses: actions/setup-node@v4 22 | with: 23 | cache: pnpm 24 | node-version: lts/* 25 | 26 | - name: Install dependencies 27 | run: pnpm install --frozen-lockfile 28 | 29 | - name: Lint 30 | run: pnpm lint 31 | 32 | - name: Build 33 | run: pnpm build 34 | 35 | - name: Docs build 36 | run: pnpm docs:build 37 | 38 | check-result: 39 | if: ${{ always() }} 40 | name: check result 41 | runs-on: ubuntu-latest 42 | needs: [check] 43 | steps: 44 | - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} 45 | run: exit 1 46 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | jobs: 12 | release: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: lts/* 23 | registry-url: https://registry.npmjs.org/ 24 | 25 | - name: Create release changelog 26 | run: npx changelogithub 27 | env: 28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | node_modules 3 | .cache 4 | .DS_Store 5 | .temp 6 | docs/.vuepress/dist 7 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | pnpm commitlint --edit $1 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | pnpm-lock.yaml 2 | CHANGELOG.md 3 | dist/ 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "dbaeumer.vscode-eslint", 4 | "esbenp.prettier-vscode", 5 | "vue.volar", 6 | ], 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "editor.insertSpaces": true, 5 | "editor.tabSize": 2, 6 | "files.encoding": "utf8", 7 | "files.eol": "\n", 8 | "files.trimFinalNewlines": true, 9 | "files.trimTrailingWhitespace": true, 10 | "[markdown]": { 11 | "files.trimTrailingWhitespace": false, 12 | }, 13 | "eslint.experimental.useFlatConfig": true, 14 | "eslint.validate": [ 15 | "javascript", 16 | "javascriptreact", 17 | "markdown", 18 | "typescript", 19 | "typescriptreact", 20 | "vue", 21 | ], 22 | "typescript.tsdk": "node_modules/typescript/lib", 23 | } 24 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [4.2.0](https://github.com/meteorlxy/vue-showdown/compare/v4.1.1...v4.2.0) (2023-08-28) 2 | 3 | 4 | ### Features 5 | 6 | * add vueTemplateComponents prop ([#50](https://github.com/meteorlxy/vue-showdown/issues/50)) ([000da35](https://github.com/meteorlxy/vue-showdown/commit/000da35571d77e681f22363d870c34a4c0c207c5)) 7 | 8 | 9 | 10 | ## [4.1.1](https://github.com/meteorlxy/vue-showdown/compare/v4.1.0...v4.1.1) (2023-07-03) 11 | 12 | 13 | ### Bug Fixes 14 | 15 | * fix types definitions (close [#47](https://github.com/meteorlxy/vue-showdown/issues/47)) ([16010a8](https://github.com/meteorlxy/vue-showdown/commit/16010a8bf19ff9b57c18758ec3ffa500de084547)) 16 | 17 | 18 | 19 | # [4.1.0](https://github.com/meteorlxy/vue-showdown/compare/v4.0.0...v4.1.0) (2023-05-10) 20 | 21 | 22 | ### Features 23 | 24 | * drop node 14 ([bba3951](https://github.com/meteorlxy/vue-showdown/commit/bba395150e4466d0eb11cb23a3fc72dad6a5b7c5)) 25 | 26 | 27 | 28 | # [4.0.0](https://github.com/meteorlxy/vue-showdown/compare/v3.3.0...v4.0.0) (2022-12-14) 29 | 30 | 31 | ### Build System 32 | 33 | * set build target to es2020 ([fa2796f](https://github.com/meteorlxy/vue-showdown/commit/fa2796fa5036769e0abac7f80362b9fc7742418e)) 34 | 35 | 36 | ### BREAKING CHANGES 37 | 38 | * drop support for Node 12 and publish as an esm package 39 | 40 | 41 | 42 | # [3.3.0](https://github.com/meteorlxy/vue-showdown/compare/v3.2.0...v3.3.0) (2022-04-20) 43 | 44 | 45 | ### Features 46 | 47 | * bump showdown types to v2 ([3e92b47](https://github.com/meteorlxy/vue-showdown/commit/3e92b475d7a4071729e0317b511ffa81aa06d838)) 48 | 49 | 50 | 51 | # [3.2.0](https://github.com/meteorlxy/vue-showdown/compare/v3.1.0...v3.2.0) (2022-04-11) 52 | 53 | 54 | ### Features 55 | 56 | * bump to showdown v2 ([5e727f8](https://github.com/meteorlxy/vue-showdown/commit/5e727f8634da2f2d7bd809591bcfbfbe4a7ab7d1)) 57 | 58 | 59 | 60 | # [3.1.0](https://github.com/meteorlxy/vue-showdown/compare/v3.0.0...v3.1.0) (2021-04-26) 61 | 62 | 63 | ### Features 64 | 65 | * support vueTemplateData ([04b74e5](https://github.com/meteorlxy/vue-showdown/commit/04b74e5cf959644a35dbc50cc917c2dd2370cba4)) 66 | 67 | 68 | 69 | # [3.0.0](https://github.com/meteorlxy/vue-showdown/compare/v2.4.1...v3.0.0) (2020-12-17) 70 | 71 | 72 | ### Features 73 | 74 | * migrate to vue 3 ([c747e20](https://github.com/meteorlxy/vue-showdown/commit/c747e2080bdfe2331f1a326894a050e760edb809)) 75 | 76 | 77 | 78 | ## [2.4.1](https://github.com/meteorlxy/vue-showdown/compare/v2.4.0...v2.4.1) (2019-05-21) 79 | 80 | 81 | ### Bug Fixes 82 | 83 | * remove Object.entries to be compatible with IE11 ([#8](https://github.com/meteorlxy/vue-showdown/issues/8)) ([944ca30](https://github.com/meteorlxy/vue-showdown/commit/944ca30)) 84 | 85 | 86 | 87 | # [2.4.0](https://github.com/meteorlxy/vue-showdown/compare/v2.3.0...v2.4.0) (2019-02-17) 88 | 89 | 90 | ### Features 91 | 92 | * add vue-template prop (close [#5](https://github.com/meteorlxy/vue-showdown/issues/5)) ([daa487c](https://github.com/meteorlxy/vue-showdown/commit/daa487c)) 93 | 94 | 95 | 96 | # [2.3.0](https://github.com/meteorlxy/vue-showdown/compare/v2.2.2...v2.3.0) (2018-12-21) 97 | 98 | 99 | ### Features 100 | 101 | * add types declaration ([e2e621e](https://github.com/meteorlxy/vue-showdown/commit/e2e621e)) 102 | * do not bundle showdown ([851ce0b](https://github.com/meteorlxy/vue-showdown/commit/851ce0b)) 103 | 104 | 105 | 106 | ## [2.2.2](https://github.com/meteorlxy/vue-showdown/compare/v2.2.1...v2.2.2) (2018-12-21) 107 | 108 | 109 | ### Bug Fixes 110 | 111 | * minimize build broke due to typo in rollup config ([1f35a1b](https://github.com/meteorlxy/vue-showdown/commit/1f35a1b)) 112 | 113 | 114 | 115 | ## [2.2.1](https://github.com/meteorlxy/vue-showdown/compare/v2.2.0...v2.2.1) (2018-12-19) 116 | 117 | 118 | 119 | # [2.2.0](https://github.com/meteorlxy/vue-showdown/compare/v2.1.0...v2.2.0) (2018-12-18) 120 | 121 | 122 | 123 | # [2.1.0](https://github.com/meteorlxy/vue-showdown/compare/v2.0.2...v2.1.0) (2018-12-18) 124 | 125 | 126 | ### Features 127 | 128 | * modifications about default options ([9eb73f7](https://github.com/meteorlxy/vue-showdown/commit/9eb73f7)) 129 | 130 | 131 | 132 | ## [2.0.2](https://github.com/meteorlxy/vue-showdown/compare/v2.0.1...v2.0.2) (2018-09-09) 133 | 134 | 135 | 136 | ## [2.0.1](https://github.com/meteorlxy/vue-showdown/compare/v2.0.0...v2.0.1) (2018-07-17) 137 | 138 | 139 | 140 | # [2.0.0](https://github.com/meteorlxy/vue-showdown/compare/v1.0.0...v2.0.0) (2018-07-17) 141 | 142 | ### Breaking changes 143 | 144 | - `import VueShowdown from 'vue-showdown'` will get a Vue Plugin, which should be involved by `Vue.use(VueShowdown, options)` 145 | - `import { VueShowdown } from 'vue-showdown'` will get a Vue Component, which should be involved by `Vue.component('VueShowdown ', VueShowdown )` 146 | 147 | ### Features 148 | 149 | - Support options of `showdown.js` (see https://github.com/showdownjs/showdown) 150 | 151 | ### Others 152 | 153 | - Refactor the codebase 154 | - Use `rollup` to build dist files 155 | - Use `vuepress` to build docs 156 | 157 | 158 | # 1.0.0 (2017-10-19) 159 | 160 | ### Features 161 | 162 | - Vue component for `showdown.js` 163 | - Use `prop` or `slot` to pass the markdown text into the component 164 | 165 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-present meteorlxy & contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Vue Showdown logo 4 | 5 |

6 | 7 |

8 | Vue Showdown 9 |

10 | 11 |

12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |

36 | 37 | > Current branch is for Vue 3 only. If you are using Vue 2, please check out [v2 branch](https://github.com/meteorlxy/vue-showdown/tree/v2). 38 | 39 | ## Introduction 40 | 41 | Use [showdown](https://github.com/showdownjs/showdown) as a Vue component. 42 | 43 | ## Usage 44 | 45 | See [**Live Demo and Docs**](https://vue-showdown.js.org) 46 | 47 | ## Contributing 48 | 49 | Feel free to submit Issues and PRs if you meet any problems or have any ideas. 50 | 51 | ### Develop 52 | 53 | ```sh 54 | # Clone this repo 55 | git clone https://github.com/meteorlxy/vue-showdown 56 | cd vue-showdown 57 | 58 | # Install dependencies 59 | pnpm i 60 | 61 | # Start the dev-server 62 | pnpm dev 63 | ``` 64 | 65 | ## LICENSE 66 | 67 | [MIT](https://github.com/meteorlxy/vue-showdown/blob/master/LICENSE) © [@meteorlxy](https://github.com/meteorlxy) & [Contributors](https://github.com/meteorlxy/vue-showdown/graphs/contributors) 68 | -------------------------------------------------------------------------------- /dev/CustomComponent.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | -------------------------------------------------------------------------------- /dev/browser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vue-showdown dev 8 | 17 | 18 | 19 |
20 |

Input:

21 | 22 | 27 | 28 |

Output:

29 | 30 | 34 |
35 | 36 | 37 | 38 | 39 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /dev/dev.vue: -------------------------------------------------------------------------------- 1 | 85 | 86 | 172 | 173 | 211 | -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | vue-showdown dev 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /dev/index.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import { VueShowdownPlugin, showdown } from 'vue-showdown'; 3 | import Dev from './dev.vue'; 4 | 5 | showdown.extension('replaceMarkdownByShowdown', () => [ 6 | { 7 | type: 'lang', 8 | regex: /markdown/g, 9 | replace: 'showdown', 10 | }, 11 | ]); 12 | 13 | const app = createApp(Dev); 14 | 15 | app.use(VueShowdownPlugin); 16 | 17 | app.mount('#app'); 18 | -------------------------------------------------------------------------------- /dev/shim.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue'; 3 | 4 | const comp: DefineComponent; 5 | export default comp; 6 | } 7 | -------------------------------------------------------------------------------- /dev/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "compilerOptions": { 4 | "baseUrl": "..", 5 | "paths": { 6 | "vue-showdown": ["src/index.ts"] 7 | } 8 | }, 9 | "include": ["./**/*", "./**/*.vue"] 10 | } 11 | -------------------------------------------------------------------------------- /dist/vue-showdown.cjs.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-showdown - Use showdown as a vue component 3 | * 4 | * @version v4.2.0 5 | * @link https://vue-showdown.js.org 6 | * @license MIT 7 | * @copyright 2018-2023 meteorlxy 8 | */ 9 | 10 | 'use strict'; 11 | 12 | Object.defineProperty(exports, '__esModule', { value: true }); 13 | 14 | var showdown = require('showdown'); 15 | var vue = require('vue'); 16 | 17 | /** 18 | * The VueShowdown component 19 | * 20 | * @example 21 | * ```html 22 | * 25 | * 26 | * 36 | * ``` 37 | * 38 | * @public 39 | */ 40 | const VueShowdown = vue.defineComponent({ 41 | name: 'VueShowdown', 42 | props: { 43 | /** 44 | * Raw markdown content 45 | */ 46 | markdown: { 47 | type: String, 48 | required: false, 49 | default: null, 50 | }, 51 | /** 52 | * HTML tag of the markdown wrapper 53 | */ 54 | tag: { 55 | type: String, 56 | required: false, 57 | default: 'div', 58 | }, 59 | /** 60 | * Showdown flavor 61 | * 62 | * @see https://github.com/showdownjs/showdown#flavors 63 | */ 64 | flavor: { 65 | type: String, 66 | required: false, 67 | default: null, 68 | }, 69 | /** 70 | * Showdown options 71 | * 72 | * @see https://github.com/showdownjs/showdown#valid-options 73 | */ 74 | options: { 75 | type: Object, 76 | required: false, 77 | default: () => ({}), 78 | }, 79 | /** 80 | * Showdown extensions 81 | * 82 | * @see https://github.com/showdownjs/showdown#extensions 83 | */ 84 | extensions: { 85 | type: Array, 86 | required: false, 87 | default: null, 88 | }, 89 | /** 90 | * Treat the HTML string as Vue template. Require full build of Vue (runtime + complier) 91 | */ 92 | vueTemplate: { 93 | type: Boolean, 94 | required: false, 95 | default: false, 96 | }, 97 | /** 98 | * Define components which are available in the Vue template. Require `vueTemplate` to be enabled 99 | */ 100 | vueTemplateComponents: { 101 | type: Object, 102 | required: false, 103 | default: () => ({}), 104 | }, 105 | /** 106 | * Define data which is available in the Vue template. Require `vueTemplate` to be enabled 107 | */ 108 | vueTemplateData: { 109 | type: Object, 110 | required: false, 111 | default: () => ({}), 112 | }, 113 | }, 114 | setup(props, { slots }) { 115 | // the showdown converter instance ref 116 | const converter = vue.computed(() => { 117 | const instance = new showdown.Converter({ 118 | extensions: props.extensions ?? undefined, 119 | }); 120 | if (props.flavor !== null) { 121 | instance.setFlavor(props.flavor); 122 | } 123 | Object.entries(props.options).forEach(([key, value]) => { 124 | instance.setOption(key, value); 125 | }); 126 | return instance; 127 | }); 128 | // the raw markdown string 129 | const inputMarkdown = vue.computed(() => { 130 | // from props 131 | if (props.markdown !== null) { 132 | return props.markdown; 133 | } 134 | // from default slot 135 | const slot = slots.default?.()[0]; 136 | if (slot?.type === vue.Text) { 137 | return slot.children; 138 | } 139 | // fall back to empty string 140 | return ''; 141 | }); 142 | // the parsed HTML string 143 | const outputHtml = vue.computed(() => converter.value.makeHtml(inputMarkdown.value)); 144 | return () => props.vueTemplate 145 | ? vue.h({ 146 | components: props.vueTemplateComponents, 147 | setup: () => props.vueTemplateData, 148 | template: `<${props.tag}>${outputHtml.value}`, 149 | }) 150 | : vue.h(props.tag, { 151 | innerHTML: outputHtml.value, 152 | }); 153 | }, 154 | }); 155 | 156 | /** 157 | * The VueShowdown plugin 158 | * 159 | * @example 160 | * ```ts 161 | * import { createApp } from 'vue'; 162 | * import { VueShowdownPlugin } from 'vue-showdown'; 163 | * 164 | * const app = createApp(); 165 | * app.use(VueShowdownPlugin); 166 | * ``` 167 | * 168 | * @public 169 | */ 170 | const VueShowdownPlugin = { 171 | install(app, { flavor = null, options = {}, } = {}) { 172 | // set default flavor 173 | if (flavor !== null) { 174 | showdown.setFlavor(flavor); 175 | } 176 | // set default options (override flavor) 177 | Object.entries(options).forEach(([key, value]) => { 178 | showdown.setOption(key, value); 179 | }); 180 | // register vue-showdown component globally 181 | // eslint-disable-next-line vue/match-component-file-name 182 | app.component('VueShowdown', VueShowdown); 183 | }, 184 | }; 185 | 186 | exports.showdown = showdown; 187 | exports.VueShowdown = VueShowdown; 188 | exports.VueShowdownPlugin = VueShowdownPlugin; 189 | exports.default = VueShowdownPlugin; 190 | -------------------------------------------------------------------------------- /dist/vue-showdown.d.ts: -------------------------------------------------------------------------------- 1 | import showdown, { Flavor, ShowdownOptions } from 'showdown'; 2 | export { default as showdown } from 'showdown'; 3 | import * as vue from 'vue'; 4 | import { PropType, Plugin } from 'vue'; 5 | 6 | /** 7 | * The VueShowdown component 8 | * 9 | * @example 10 | * ```html 11 | * 14 | * 15 | * 25 | * ``` 26 | * 27 | * @public 28 | */ 29 | declare const VueShowdown: vue.DefineComponent<{ 30 | /** 31 | * Raw markdown content 32 | */ 33 | markdown: { 34 | type: PropType; 35 | required: false; 36 | default: null; 37 | }; 38 | /** 39 | * HTML tag of the markdown wrapper 40 | */ 41 | tag: { 42 | type: PropType; 43 | required: false; 44 | default: string; 45 | }; 46 | /** 47 | * Showdown flavor 48 | * 49 | * @see https://github.com/showdownjs/showdown#flavors 50 | */ 51 | flavor: { 52 | type: PropType; 53 | required: false; 54 | default: null; 55 | }; 56 | /** 57 | * Showdown options 58 | * 59 | * @see https://github.com/showdownjs/showdown#valid-options 60 | */ 61 | options: { 62 | type: PropType; 63 | required: false; 64 | default: () => {}; 65 | }; 66 | /** 67 | * Showdown extensions 68 | * 69 | * @see https://github.com/showdownjs/showdown#extensions 70 | */ 71 | extensions: { 72 | type: PropType showdown.ShowdownExtension | showdown.ShowdownExtension[]) | showdown.ShowdownExtension | showdown.ShowdownExtension[])[] | null | undefined>>; 73 | required: false; 74 | default: null; 75 | }; 76 | /** 77 | * Treat the HTML string as Vue template. Require full build of Vue (runtime + complier) 78 | */ 79 | vueTemplate: { 80 | type: BooleanConstructor; 81 | required: false; 82 | default: boolean; 83 | }; 84 | /** 85 | * Define components which are available in the Vue template. Require `vueTemplate` to be enabled 86 | */ 87 | vueTemplateComponents: { 88 | type: ObjectConstructor; 89 | required: false; 90 | default: () => {}; 91 | }; 92 | /** 93 | * Define data which is available in the Vue template. Require `vueTemplate` to be enabled 94 | */ 95 | vueTemplateData: { 96 | type: ObjectConstructor; 97 | required: false; 98 | default: () => {}; 99 | }; 100 | }, () => vue.VNode, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly; 108 | required: false; 109 | default: null; 110 | }; 111 | /** 112 | * HTML tag of the markdown wrapper 113 | */ 114 | tag: { 115 | type: PropType; 116 | required: false; 117 | default: string; 118 | }; 119 | /** 120 | * Showdown flavor 121 | * 122 | * @see https://github.com/showdownjs/showdown#flavors 123 | */ 124 | flavor: { 125 | type: PropType; 126 | required: false; 127 | default: null; 128 | }; 129 | /** 130 | * Showdown options 131 | * 132 | * @see https://github.com/showdownjs/showdown#valid-options 133 | */ 134 | options: { 135 | type: PropType; 136 | required: false; 137 | default: () => {}; 138 | }; 139 | /** 140 | * Showdown extensions 141 | * 142 | * @see https://github.com/showdownjs/showdown#extensions 143 | */ 144 | extensions: { 145 | type: PropType showdown.ShowdownExtension | showdown.ShowdownExtension[]) | showdown.ShowdownExtension | showdown.ShowdownExtension[])[] | null | undefined>>; 146 | required: false; 147 | default: null; 148 | }; 149 | /** 150 | * Treat the HTML string as Vue template. Require full build of Vue (runtime + complier) 151 | */ 152 | vueTemplate: { 153 | type: BooleanConstructor; 154 | required: false; 155 | default: boolean; 156 | }; 157 | /** 158 | * Define components which are available in the Vue template. Require `vueTemplate` to be enabled 159 | */ 160 | vueTemplateComponents: { 161 | type: ObjectConstructor; 162 | required: false; 163 | default: () => {}; 164 | }; 165 | /** 166 | * Define data which is available in the Vue template. Require `vueTemplate` to be enabled 167 | */ 168 | vueTemplateData: { 169 | type: ObjectConstructor; 170 | required: false; 171 | default: () => {}; 172 | }; 173 | }>>, { 174 | extensions: Required<(string | (() => showdown.ShowdownExtension | showdown.ShowdownExtension[]) | showdown.ShowdownExtension | showdown.ShowdownExtension[])[] | null | undefined>; 175 | markdown: string | null; 176 | tag: string; 177 | flavor: Flavor | null; 178 | options: ShowdownOptions; 179 | vueTemplate: boolean; 180 | vueTemplateComponents: Record; 181 | vueTemplateData: Record; 182 | }, {}>; 183 | 184 | /** 185 | * The VueShowdown plugin 186 | * 187 | * @example 188 | * ```ts 189 | * import { createApp } from 'vue'; 190 | * import { VueShowdownPlugin } from 'vue-showdown'; 191 | * 192 | * const app = createApp(); 193 | * app.use(VueShowdownPlugin); 194 | * ``` 195 | * 196 | * @public 197 | */ 198 | declare const VueShowdownPlugin: Plugin; 199 | 200 | export { VueShowdown, VueShowdownPlugin, VueShowdownPlugin as default }; 201 | -------------------------------------------------------------------------------- /dist/vue-showdown.esm.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-showdown - Use showdown as a vue component 3 | * 4 | * @version v4.2.0 5 | * @link https://vue-showdown.js.org 6 | * @license MIT 7 | * @copyright 2018-2023 meteorlxy 8 | */ 9 | 10 | import showdown from 'showdown'; 11 | export { default as showdown } from 'showdown'; 12 | import { defineComponent, computed, Text, h } from 'vue'; 13 | 14 | /** 15 | * The VueShowdown component 16 | * 17 | * @example 18 | * ```html 19 | * 22 | * 23 | * 33 | * ``` 34 | * 35 | * @public 36 | */ 37 | const VueShowdown = defineComponent({ 38 | name: 'VueShowdown', 39 | props: { 40 | /** 41 | * Raw markdown content 42 | */ 43 | markdown: { 44 | type: String, 45 | required: false, 46 | default: null, 47 | }, 48 | /** 49 | * HTML tag of the markdown wrapper 50 | */ 51 | tag: { 52 | type: String, 53 | required: false, 54 | default: 'div', 55 | }, 56 | /** 57 | * Showdown flavor 58 | * 59 | * @see https://github.com/showdownjs/showdown#flavors 60 | */ 61 | flavor: { 62 | type: String, 63 | required: false, 64 | default: null, 65 | }, 66 | /** 67 | * Showdown options 68 | * 69 | * @see https://github.com/showdownjs/showdown#valid-options 70 | */ 71 | options: { 72 | type: Object, 73 | required: false, 74 | default: () => ({}), 75 | }, 76 | /** 77 | * Showdown extensions 78 | * 79 | * @see https://github.com/showdownjs/showdown#extensions 80 | */ 81 | extensions: { 82 | type: Array, 83 | required: false, 84 | default: null, 85 | }, 86 | /** 87 | * Treat the HTML string as Vue template. Require full build of Vue (runtime + complier) 88 | */ 89 | vueTemplate: { 90 | type: Boolean, 91 | required: false, 92 | default: false, 93 | }, 94 | /** 95 | * Define components which are available in the Vue template. Require `vueTemplate` to be enabled 96 | */ 97 | vueTemplateComponents: { 98 | type: Object, 99 | required: false, 100 | default: () => ({}), 101 | }, 102 | /** 103 | * Define data which is available in the Vue template. Require `vueTemplate` to be enabled 104 | */ 105 | vueTemplateData: { 106 | type: Object, 107 | required: false, 108 | default: () => ({}), 109 | }, 110 | }, 111 | setup(props, { slots }) { 112 | // the showdown converter instance ref 113 | const converter = computed(() => { 114 | const instance = new showdown.Converter({ 115 | extensions: props.extensions ?? undefined, 116 | }); 117 | if (props.flavor !== null) { 118 | instance.setFlavor(props.flavor); 119 | } 120 | Object.entries(props.options).forEach(([key, value]) => { 121 | instance.setOption(key, value); 122 | }); 123 | return instance; 124 | }); 125 | // the raw markdown string 126 | const inputMarkdown = computed(() => { 127 | // from props 128 | if (props.markdown !== null) { 129 | return props.markdown; 130 | } 131 | // from default slot 132 | const slot = slots.default?.()[0]; 133 | if (slot?.type === Text) { 134 | return slot.children; 135 | } 136 | // fall back to empty string 137 | return ''; 138 | }); 139 | // the parsed HTML string 140 | const outputHtml = computed(() => converter.value.makeHtml(inputMarkdown.value)); 141 | return () => props.vueTemplate 142 | ? h({ 143 | components: props.vueTemplateComponents, 144 | setup: () => props.vueTemplateData, 145 | template: `<${props.tag}>${outputHtml.value}`, 146 | }) 147 | : h(props.tag, { 148 | innerHTML: outputHtml.value, 149 | }); 150 | }, 151 | }); 152 | 153 | /** 154 | * The VueShowdown plugin 155 | * 156 | * @example 157 | * ```ts 158 | * import { createApp } from 'vue'; 159 | * import { VueShowdownPlugin } from 'vue-showdown'; 160 | * 161 | * const app = createApp(); 162 | * app.use(VueShowdownPlugin); 163 | * ``` 164 | * 165 | * @public 166 | */ 167 | const VueShowdownPlugin = { 168 | install(app, { flavor = null, options = {}, } = {}) { 169 | // set default flavor 170 | if (flavor !== null) { 171 | showdown.setFlavor(flavor); 172 | } 173 | // set default options (override flavor) 174 | Object.entries(options).forEach(([key, value]) => { 175 | showdown.setOption(key, value); 176 | }); 177 | // register vue-showdown component globally 178 | // eslint-disable-next-line vue/match-component-file-name 179 | app.component('VueShowdown', VueShowdown); 180 | }, 181 | }; 182 | 183 | export { VueShowdown, VueShowdownPlugin, VueShowdownPlugin as default }; 184 | -------------------------------------------------------------------------------- /dist/vue-showdown.esm.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-showdown - Use showdown as a vue component 3 | * 4 | * @version v4.2.0 5 | * @link https://vue-showdown.js.org 6 | * @license MIT 7 | * @copyright 2018-2023 meteorlxy 8 | */ 9 | import e from"showdown";export{default as showdown}from"showdown";import{defineComponent as t,computed as o,Text as n,h as r}from"vue";const a=t({name:"VueShowdown",props:{markdown:{type:String,required:!1,default:null},tag:{type:String,required:!1,default:"div"},flavor:{type:String,required:!1,default:null},options:{type:Object,required:!1,default:()=>({})},extensions:{type:Array,required:!1,default:null},vueTemplate:{type:Boolean,required:!1,default:!1},vueTemplateComponents:{type:Object,required:!1,default:()=>({})},vueTemplateData:{type:Object,required:!1,default:()=>({})}},setup(t,{slots:a}){const l=o((()=>{const o=new e.Converter({extensions:t.extensions??void 0});return null!==t.flavor&&o.setFlavor(t.flavor),Object.entries(t.options).forEach((([e,t])=>{o.setOption(e,t)})),o})),u=o((()=>{if(null!==t.markdown)return t.markdown;const e=a.default?.()[0];return e?.type===n?e.children:""})),p=o((()=>l.value.makeHtml(u.value)));return()=>t.vueTemplate?r({components:t.vueTemplateComponents,setup:()=>t.vueTemplateData,template:`<${t.tag}>${p.value}`}):r(t.tag,{innerHTML:p.value})}}),l={install(t,{flavor:o=null,options:n={}}={}){null!==o&&e.setFlavor(o),Object.entries(n).forEach((([t,o])=>{e.setOption(t,o)})),t.component("VueShowdown",a)}};export{a as VueShowdown,l as VueShowdownPlugin,l as default}; 10 | -------------------------------------------------------------------------------- /dist/vue-showdown.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-showdown - Use showdown as a vue component 3 | * 4 | * @version v4.2.0 5 | * @link https://vue-showdown.js.org 6 | * @license MIT 7 | * @copyright 2018-2023 meteorlxy 8 | */ 9 | 10 | (function (global, factory) { 11 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('showdown'), require('vue')) : 12 | typeof define === 'function' && define.amd ? define(['exports', 'showdown', 'vue'], factory) : 13 | (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.VueShowdown = {}, global.showdown, global.Vue)); 14 | })(this, (function (exports, showdown, vue) { 'use strict'; 15 | 16 | /** 17 | * The VueShowdown component 18 | * 19 | * @example 20 | * ```html 21 | * 24 | * 25 | * 35 | * ``` 36 | * 37 | * @public 38 | */ 39 | const VueShowdown = vue.defineComponent({ 40 | name: 'VueShowdown', 41 | props: { 42 | /** 43 | * Raw markdown content 44 | */ 45 | markdown: { 46 | type: String, 47 | required: false, 48 | default: null, 49 | }, 50 | /** 51 | * HTML tag of the markdown wrapper 52 | */ 53 | tag: { 54 | type: String, 55 | required: false, 56 | default: 'div', 57 | }, 58 | /** 59 | * Showdown flavor 60 | * 61 | * @see https://github.com/showdownjs/showdown#flavors 62 | */ 63 | flavor: { 64 | type: String, 65 | required: false, 66 | default: null, 67 | }, 68 | /** 69 | * Showdown options 70 | * 71 | * @see https://github.com/showdownjs/showdown#valid-options 72 | */ 73 | options: { 74 | type: Object, 75 | required: false, 76 | default: () => ({}), 77 | }, 78 | /** 79 | * Showdown extensions 80 | * 81 | * @see https://github.com/showdownjs/showdown#extensions 82 | */ 83 | extensions: { 84 | type: Array, 85 | required: false, 86 | default: null, 87 | }, 88 | /** 89 | * Treat the HTML string as Vue template. Require full build of Vue (runtime + complier) 90 | */ 91 | vueTemplate: { 92 | type: Boolean, 93 | required: false, 94 | default: false, 95 | }, 96 | /** 97 | * Define components which are available in the Vue template. Require `vueTemplate` to be enabled 98 | */ 99 | vueTemplateComponents: { 100 | type: Object, 101 | required: false, 102 | default: () => ({}), 103 | }, 104 | /** 105 | * Define data which is available in the Vue template. Require `vueTemplate` to be enabled 106 | */ 107 | vueTemplateData: { 108 | type: Object, 109 | required: false, 110 | default: () => ({}), 111 | }, 112 | }, 113 | setup(props, { slots }) { 114 | // the showdown converter instance ref 115 | const converter = vue.computed(() => { 116 | const instance = new showdown.Converter({ 117 | extensions: props.extensions ?? undefined, 118 | }); 119 | if (props.flavor !== null) { 120 | instance.setFlavor(props.flavor); 121 | } 122 | Object.entries(props.options).forEach(([key, value]) => { 123 | instance.setOption(key, value); 124 | }); 125 | return instance; 126 | }); 127 | // the raw markdown string 128 | const inputMarkdown = vue.computed(() => { 129 | // from props 130 | if (props.markdown !== null) { 131 | return props.markdown; 132 | } 133 | // from default slot 134 | const slot = slots.default?.()[0]; 135 | if (slot?.type === vue.Text) { 136 | return slot.children; 137 | } 138 | // fall back to empty string 139 | return ''; 140 | }); 141 | // the parsed HTML string 142 | const outputHtml = vue.computed(() => converter.value.makeHtml(inputMarkdown.value)); 143 | return () => props.vueTemplate 144 | ? vue.h({ 145 | components: props.vueTemplateComponents, 146 | setup: () => props.vueTemplateData, 147 | template: `<${props.tag}>${outputHtml.value}`, 148 | }) 149 | : vue.h(props.tag, { 150 | innerHTML: outputHtml.value, 151 | }); 152 | }, 153 | }); 154 | 155 | /** 156 | * The VueShowdown plugin 157 | * 158 | * @example 159 | * ```ts 160 | * import { createApp } from 'vue'; 161 | * import { VueShowdownPlugin } from 'vue-showdown'; 162 | * 163 | * const app = createApp(); 164 | * app.use(VueShowdownPlugin); 165 | * ``` 166 | * 167 | * @public 168 | */ 169 | const VueShowdownPlugin = { 170 | install(app, { flavor = null, options = {}, } = {}) { 171 | // set default flavor 172 | if (flavor !== null) { 173 | showdown.setFlavor(flavor); 174 | } 175 | // set default options (override flavor) 176 | Object.entries(options).forEach(([key, value]) => { 177 | showdown.setOption(key, value); 178 | }); 179 | // register vue-showdown component globally 180 | // eslint-disable-next-line vue/match-component-file-name 181 | app.component('VueShowdown', VueShowdown); 182 | }, 183 | }; 184 | 185 | if (typeof window !== 'undefined') { 186 | window.VueShowdown = VueShowdown; 187 | window.VueShowdownPlugin = VueShowdownPlugin; 188 | } 189 | 190 | exports.showdown = showdown; 191 | exports.VueShowdown = VueShowdown; 192 | exports.VueShowdownPlugin = VueShowdownPlugin; 193 | 194 | })); 195 | -------------------------------------------------------------------------------- /dist/vue-showdown.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * vue-showdown - Use showdown as a vue component 3 | * 4 | * @version v4.2.0 5 | * @link https://vue-showdown.js.org 6 | * @license MIT 7 | * @copyright 2018-2023 meteorlxy 8 | */ 9 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("showdown"),require("vue")):"function"==typeof define&&define.amd?define(["exports","showdown","vue"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VueShowdown={},e.showdown,e.Vue)}(this,(function(e,t,o){"use strict";const n=o.defineComponent({name:"VueShowdown",props:{markdown:{type:String,required:!1,default:null},tag:{type:String,required:!1,default:"div"},flavor:{type:String,required:!1,default:null},options:{type:Object,required:!1,default:()=>({})},extensions:{type:Array,required:!1,default:null},vueTemplate:{type:Boolean,required:!1,default:!1},vueTemplateComponents:{type:Object,required:!1,default:()=>({})},vueTemplateData:{type:Object,required:!1,default:()=>({})}},setup(e,{slots:n}){const u=o.computed((()=>{const o=new t.Converter({extensions:e.extensions??void 0});return null!==e.flavor&&o.setFlavor(e.flavor),Object.entries(e.options).forEach((([e,t])=>{o.setOption(e,t)})),o})),r=o.computed((()=>{if(null!==e.markdown)return e.markdown;const t=n.default?.()[0];return t?.type===o.Text?t.children:""})),l=o.computed((()=>u.value.makeHtml(r.value)));return()=>e.vueTemplate?o.h({components:e.vueTemplateComponents,setup:()=>e.vueTemplateData,template:`<${e.tag}>${l.value}`}):o.h(e.tag,{innerHTML:l.value})}}),u={install(e,{flavor:o=null,options:u={}}={}){null!==o&&t.setFlavor(o),Object.entries(u).forEach((([e,o])=>{t.setOption(e,o)})),e.component("VueShowdown",n)}};"undefined"!=typeof window&&(window.VueShowdown=n,window.VueShowdownPlugin=u),e.showdown=t,e.VueShowdown=n,e.VueShowdownPlugin=u})); 10 | -------------------------------------------------------------------------------- /docs/.vuepress/client.ts: -------------------------------------------------------------------------------- 1 | import VueShowdownPlugin from 'vue-showdown'; 2 | import { defineClientConfig, resolvers } from 'vuepress/client'; 3 | 4 | export default defineClientConfig({ 5 | enhance({ app }) { 6 | resolvers.resolvePageHeadTitle = (page, siteLocale) => 7 | [page.title, siteLocale.title].filter((item) => !!item).join(' | '); 8 | 9 | app.use(VueShowdownPlugin, { 10 | options: { 11 | emoji: true, 12 | }, 13 | }); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /docs/.vuepress/config.ts: -------------------------------------------------------------------------------- 1 | import { viteBundler } from '@vuepress/bundler-vite'; 2 | import { defaultTheme } from '@vuepress/theme-default'; 3 | import { defineUserConfig } from 'vuepress'; 4 | import { path } from 'vuepress/utils'; 5 | import { version } from '../../package.json'; 6 | 7 | export default defineUserConfig({ 8 | head: [['link', { rel: 'icon', href: `/logo.png` }]], 9 | 10 | locales: { 11 | '/': { 12 | lang: 'en-US', 13 | title: 'Vue Showdown', 14 | description: 'Use showdown.js in Vue', 15 | }, 16 | 17 | '/zh/': { 18 | lang: 'zh-CN', 19 | title: 'Vue Showdown', 20 | description: '在 Vue 中快速使用 showdown.js', 21 | }, 22 | }, 23 | 24 | bundler: viteBundler({ 25 | viteOptions: { 26 | optimizeDeps: { 27 | include: ['showdown'], 28 | }, 29 | }, 30 | }), 31 | 32 | theme: defaultTheme({ 33 | repo: 'meteorlxy/vue-showdown', 34 | 35 | docsDir: 'docs', 36 | 37 | locales: { 38 | '/': { 39 | // navbar 40 | navbar: [ 41 | { 42 | text: 'Guide', 43 | link: '/guide/', 44 | }, 45 | { 46 | text: 'Playground', 47 | link: '/playground/', 48 | }, 49 | { 50 | text: `v${version}`, 51 | link: 'https://github.com/meteorlxy/vue-showdown/blob/main/CHANGELOG.md', 52 | }, 53 | ], 54 | selectLanguageName: 'English', 55 | 56 | // page meta 57 | editLinkText: 'Edit this page on GitHub', 58 | }, 59 | 60 | '/zh/': { 61 | // navbar 62 | navbar: [ 63 | { 64 | text: '指南', 65 | link: '/zh/guide/', 66 | }, 67 | { 68 | text: 'Playground', 69 | link: '/zh/playground/', 70 | }, 71 | { 72 | text: `v${version}`, 73 | link: 'https://github.com/meteorlxy/vue-showdown/blob/main/CHANGELOG.md', 74 | }, 75 | ], 76 | selectLanguageName: '简体中文', 77 | selectLanguageText: '选择语言', 78 | selectLanguageAriaLabel: '选择语言', 79 | 80 | // page meta 81 | editLinkText: '在 GitHub 上编辑此页', 82 | lastUpdatedText: '上次更新', 83 | contributorsText: '贡献者', 84 | 85 | // custom blocks 86 | tip: '提示', 87 | warning: '注意', 88 | danger: '警告', 89 | 90 | // 404 page 91 | notFound: [ 92 | '这里什么都没有', 93 | '我们怎么到这来了?', 94 | '这是一个 404 页面', 95 | '看起来我们进入了错误的链接', 96 | ], 97 | backToHome: '返回首页', 98 | 99 | // other 100 | openInNewWindow: '在新窗口打开', 101 | }, 102 | }, 103 | }), 104 | 105 | alias: (_, isServer) => { 106 | const aliases: Record = { 107 | 'vue-showdown': path.resolve(__dirname, '../../src/index.ts'), 108 | }; 109 | 110 | if (!isServer) { 111 | // enable template compiler 112 | aliases.vue = 'vue/dist/vue.esm-bundler.js'; 113 | } 114 | 115 | return aliases; 116 | }, 117 | }); 118 | -------------------------------------------------------------------------------- /docs/.vuepress/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/meteorlxy/vue-showdown/a3cbff9ee5f2dcf5fdcc8075e4b5dac985def6ee/docs/.vuepress/public/logo.png -------------------------------------------------------------------------------- /docs/.vuepress/public/new.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /docs/.vuepress/styles/index.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --vp-c-bg-output: #fafbfc; 3 | } 4 | 5 | [data-theme='dark'] { 6 | --vp-c-bg-output: #272b2f; 7 | } 8 | 9 | .markdown-input { 10 | resize: none; 11 | outline: none; 12 | width: 100%; 13 | margin: 15px 0; 14 | padding: 15px; 15 | font-size: 16px; 16 | color: var(--vp-c-text); 17 | background-color: var(--vp-c-bg-alt); 18 | border: 1px solid var(--vp-c-border); 19 | border-radius: 5px; 20 | box-sizing: border-box; 21 | &:focus { 22 | background-color: var(--vp-c-bg); 23 | box-shadow: 0 0 5px 2px var(--vp-c-accent-text); 24 | } 25 | } 26 | 27 | .markdown-output { 28 | padding: 10px 15px; 29 | margin: 15px 0; 30 | color: var(--vp-c-text); 31 | background-color: var(--vp-c-bg-output); 32 | border: 1px solid var(--vp-c-border); 33 | border-radius: 5px; 34 | } 35 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | heroImage: /logo.png 4 | actions: 5 | - text: Guide 6 | link: /guide/ 7 | type: secondary 8 | - text: Try it → 9 | link: /playground/ 10 | features: 11 | - title: Showdown 12 | details: Parse markdown text in client side with the power of showdown.js. 13 | - title: Vue component 14 | details: Wrapped showdown.js as a Vue component, and you can use it easily. 15 | footer: MIT Licensed | Copyright © 2018-present meteorlxy 16 | --- 17 | 18 | ## Easy to use 19 | 20 | Import and use it: 21 | 22 | ```ts 23 | import { createApp } from 'vue'; 24 | import { VueShowdownPlugin } from 'vue-showdown'; 25 | import App from './App.vue'; 26 | 27 | const app = createApp(App); 28 | 29 | app.use(VueShowdownPlugin, { 30 | options: { 31 | emoji: true, 32 | }, 33 | }); 34 | ``` 35 | 36 | Then use `` component in your vue SFC: 37 | 38 | ```vue 39 | 40 | ``` 41 | 42 | Result 43 | 44 | 45 | 46 | --- 47 | 48 | See the detailed [guide](./guide/) :point_left: 49 | -------------------------------------------------------------------------------- /docs/guide/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: auto 3 | --- 4 | 5 | # Guide :rocket: 6 | 7 | ::: warning 8 | This guide is for Vue 3 only. If you're using Vue 2, please check out the docs [here](https://github.com/meteorlxy/vue-showdown/tree/v2/docs/guide). 9 | ::: 10 | 11 | ## Getting Started 12 | 13 | ### NPM 14 | 15 | Install via npm 16 | 17 | ```bash 18 | npm install vue-showdown 19 | ``` 20 | 21 | Import vue-showdown as a vue plugin: 22 | 23 | ```ts 24 | // import as a Vue plugin 25 | import { createApp } from 'vue'; 26 | import { VueShowdownPlugin } from 'vue-showdown'; 27 | 28 | const app = createApp(); 29 | 30 | // the second parameter of app.use() is optional 31 | app.use(VueShowdownPlugin, { 32 | // set default flavor of showdown 33 | flavor: 'github', 34 | // set default options of showdown (will override the flavor options) 35 | options: { 36 | emoji: false, 37 | }, 38 | }); 39 | ``` 40 | 41 | Or import vue-showdown as a vue component: 42 | 43 | ```ts 44 | // import as a Vue component 45 | import { createApp } from 'vue'; 46 | import { VueShowdown } from 'vue-showdown'; 47 | 48 | const app = createApp(); 49 | 50 | app.component('VueShowdown', VueShowdown); 51 | ``` 52 | 53 | Then use `` in your vue SFC: 54 | 55 | ```vue 56 | 57 | 62 | ``` 63 | 64 | ::: tip 65 | vue-showdown also provides [UMD](https://github.com/umdjs/umd), [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) and [ES Module](http://exploringjs.com/es6/ch_modules.html) builds as vue does. Go to the [Vue document](https://v3.vuejs.org/guide/installation.html#explanation-of-different-builds) for more details. 66 | ::: 67 | 68 | ### Browser 69 | 70 | Direct ` 79 | 80 | 81 | 82 | 93 | 94 | ``` 95 | 96 | ## Plugin Options 97 | 98 | ```ts 99 | import { createApp } from 'vue'; 100 | import { VueShowdownPlugin } from 'vue-showdown'; 101 | 102 | const app = createApp(); 103 | 104 | app.use(VueShowdownPlugin, { 105 | // Plugin options here 106 | }); 107 | ``` 108 | 109 | ### flavor 110 | 111 | Default flavor of showdown. Docs [here](https://github.com/showdownjs/showdown#flavors). 112 | 113 | - type: `string | null` 114 | - default: `null` 115 | - possible values: `'github' | 'original' | 'ghost' | 'vanilla' | 'allOn'` 116 | 117 | ::: tip 118 | The `flavor` here will be set globally by `showdown.setFlavor()`. 119 | ::: 120 | 121 | ### options 122 | 123 | Default options of showdown. Docs [here](https://github.com/showdownjs/showdown#valid-options). 124 | 125 | - type: `Object` 126 | - default: `{}` 127 | 128 | ::: tip 129 | The `options` here will be set globally by `showdown.setOption()` after `showdown.setFlavor()`, which will override the flavor's options. 130 | ::: 131 | 132 | ## Component Props 133 | 134 | ### markdown 135 | 136 | The raw markdown content to parse. 137 | 138 | - type: `string | null` 139 | - default: `null` 140 | 141 | ```vue 142 | 143 | 144 |
145 |

Hello, world!

146 |
147 | ``` 148 | 149 | ### tag 150 | 151 | The HTML tag of the markdown wrapper. Similar to [vue-router's tag](https://router.vuejs.org/api/#tag). 152 | 153 | - type: `string` 154 | - default: `'div'` 155 | 156 | ```vue 157 | 158 | 159 | 160 |

Hello, world!

161 |
162 | ``` 163 | 164 | ### flavor 165 | 166 | Flavor of showdown. Docs [here](https://github.com/showdownjs/showdown#flavors). 167 | 168 | - type: `string | null` 169 | - default: `null` 170 | - possible values: `'github' | 'original' | 'ghost' | 'vanilla' | 'allOn'` 171 | 172 | ::: tip 173 | If you set `flavor` via props, all the options will be reset to the flavor's options, which will override the default options you set by `app.use()`. 174 | ::: 175 | 176 | ### options 177 | 178 | Options of showdown. Docs [here](https://github.com/showdownjs/showdown#valid-options). 179 | 180 | - type: `Object` 181 | - default: `{}` 182 | 183 | ::: tip 184 | The `options` prop will override the default options set by `app.use()`. 185 | 186 | If you also set `flavor` prop, the `options` prop will override the flavor's options, too. 187 | ::: 188 | 189 | ### extensions 190 | 191 | Extensions of showdown. Docs [here](https://github.com/showdownjs/showdown#extensions). 192 | 193 | - type: `Array | null` 194 | - default: `null` 195 | 196 | ::: tip 197 | Check the [Advance - Extensions](./#extensions-1) section for details. 198 | ::: 199 | 200 | ### vueTemplate 201 | 202 | Treat the parsed HTML string as vue template. This will allow you to use vue template syntax in your markdown. 203 | 204 | - type: `Boolean` 205 | - default: `false` 206 | 207 | ::: warning ATTENTION 208 | If you set it to `true`, you have to use the full (runtime + compiler) build of Vue, as we need to compile templates on the client. Consult the [vue dist file guide](https://github.com/vuejs/core/tree/main/packages/vue#which-dist-file-to-use) for more details. 209 | 210 | If you have similar request as [#5](https://github.com/meteorlxy/vue-showdown/issues/5), you can enable this feature. 211 | ::: 212 | 213 | ### vueTemplateComponents 214 | 215 | Define components which are available in the vue template. It will only take effect when [vueTemplate](#vuetemplate) is enabled. 216 | 217 | - type: `Object` 218 | - default: `{}` 219 | - example: 220 | 221 | ```vue 222 | 232 | 233 | 240 | ``` 241 | 242 | ### vueTemplateData 243 | 244 | Define data which is available in the vue template. It will only take effect when [vueTemplate](#vuetemplate) is enabled. 245 | 246 | - type: `Object` 247 | - default: `{}` 248 | - example: 249 | 250 | ```vue 251 | 261 | 262 | 269 | ``` 270 | 271 | ## Advance 272 | 273 | ### Showdown library 274 | 275 | You can also import `showdown` itself from `vue-showdown` for advance usages. 276 | 277 | ```ts 278 | import { createApp } from 'vue'; 279 | import { VueShowdownPlugin, showdown } from 'vue-showdown'; 280 | 281 | const app = createApp(); 282 | 283 | showdown.setFlavor('github'); 284 | 285 | app.use(VueShowdownPlugin); 286 | ``` 287 | 288 | ### Extensions 289 | 290 | According to the [official docs about extensions](https://github.com/showdownjs/showdown/wiki/extensions), there is no way to set default extensions globally for now. 291 | 292 | So the only way to set extensions is via the `extensions` prop of the `VueShowdown` component. 293 | 294 | ```vue 295 | 313 | 314 | 317 | ``` 318 | 319 | Alternatively, you can register extensions globally via `showdown.extension()`, and reference it in the `extension` prop directly by the name that you registered. 320 | 321 | ```ts 322 | import { createApp } from 'vue'; 323 | import { VueShowdownPlugin, showdown } from 'vue-showdown'; 324 | 325 | const app = createApp(); 326 | 327 | showdown.extension('myExt', () => [ 328 | { 329 | type: 'lang', 330 | regex: /markdown/g, 331 | replace: 'showdown', 332 | }, 333 | ]); 334 | 335 | app.use(VueShowdownPlugin); 336 | ``` 337 | 338 | ```vue 339 | 342 | ``` 343 | -------------------------------------------------------------------------------- /docs/playground/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar: auto 3 | --- 4 | 5 | # Playground :running: 6 | 7 | ## Input your markdown here 8 | 9 |