├── docs
├── index.md
├── .vitepress
│ ├── theme
│ │ ├── custom.css
│ │ └── index.js
│ └── config.js
└── package.json
├── packages
├── bytemd
│ ├── .gitignore
│ ├── src
│ │ ├── locales
│ │ ├── env.d.ts
│ │ ├── index.ts
│ │ ├── status.svelte
│ │ ├── utils.ts
│ │ ├── help.svelte
│ │ ├── toc.svelte
│ │ ├── viewer.svelte
│ │ └── types.ts
│ ├── README.md
│ ├── tsconfig.json
│ ├── locales
│ │ ├── zgh.json
│ │ ├── zh_Hant.json
│ │ ├── zh_Hans.json
│ │ ├── ja.json
│ │ ├── ko.json
│ │ ├── ar.json
│ │ ├── en.json
│ │ ├── id.json
│ │ ├── tr.json
│ │ ├── fr.json
│ │ ├── pl.json
│ │ ├── nb_NO.json
│ │ ├── de.json
│ │ ├── pt.json
│ │ ├── pt_BR.json
│ │ ├── es.json
│ │ ├── ru.json
│ │ └── ca.json
│ ├── tsconfig.svelte.json
│ ├── test
│ │ ├── setup.ts
│ │ ├── viewer.test.ts
│ │ └── editor.test.ts
│ └── package.json
├── plugin-gfm
│ ├── src
│ │ ├── locales
│ │ ├── icons.ts
│ │ └── index.ts
│ ├── locales
│ │ ├── zh_Hans.json
│ │ ├── zh_Hant.json
│ │ ├── ar.json
│ │ ├── en.json
│ │ ├── es.json
│ │ ├── fr.json
│ │ ├── id.json
│ │ ├── pl.json
│ │ ├── ru.json
│ │ ├── tr.json
│ │ ├── ca.json
│ │ ├── nb_NO.json
│ │ ├── de.json
│ │ └── pt_BR.json
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
├── plugin-math
│ ├── src
│ │ ├── locales
│ │ ├── utils
│ │ │ ├── icons.ts
│ │ │ └── index.ts
│ │ └── index.ts
│ ├── locales
│ │ ├── ja.json
│ │ ├── zh_Hans.json
│ │ ├── zh_Hant.json
│ │ ├── ar.json
│ │ ├── id.json
│ │ ├── en.json
│ │ ├── fr.json
│ │ ├── tr.json
│ │ ├── ca.json
│ │ ├── es.json
│ │ ├── nb_NO.json
│ │ ├── pt_BR.json
│ │ ├── ru.json
│ │ └── pl.json
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
├── plugin-math-ssr
│ ├── src
│ │ ├── locales
│ │ ├── utils
│ │ └── index.ts
│ ├── locales
│ ├── tsconfig.json
│ ├── README.md
│ └── package.json
├── plugin-mermaid
│ ├── src
│ │ ├── locales
│ │ ├── icons.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── locales
│ │ ├── zh_Hans.json
│ │ ├── ar.json
│ │ ├── nb_NO.json
│ │ ├── id.json
│ │ ├── pl.json
│ │ ├── de.json
│ │ ├── tr.json
│ │ ├── pt_BR.json
│ │ ├── ca.json
│ │ ├── es.json
│ │ ├── ru.json
│ │ ├── fr.json
│ │ └── en.json
│ ├── README.md
│ └── package.json
├── vue
│ ├── src
│ │ ├── editor.vue.ts
│ │ ├── viewer.vue.ts
│ │ ├── index.ts
│ │ ├── editor.vue
│ │ └── viewer.vue
│ ├── plugin.mjs
│ ├── README.md
│ ├── tsconfig.json
│ └── package.json
├── react
│ ├── README.md
│ ├── src
│ │ ├── index.ts
│ │ ├── editor.tsx
│ │ └── viewer.tsx
│ ├── tsconfig.json
│ └── package.json
├── vue-next
│ ├── README.md
│ ├── src
│ │ ├── editor.vue.ts
│ │ ├── viewer.vue.ts
│ │ ├── index.ts
│ │ ├── editor.vue
│ │ └── viewer.vue
│ ├── plugin.mjs
│ ├── tsconfig.json
│ └── package.json
├── plugin-breaks
│ ├── tsconfig.json
│ ├── src
│ │ └── index.ts
│ ├── README.md
│ └── package.json
├── plugin-gemoji
│ ├── tsconfig.json
│ ├── src
│ │ └── index.ts
│ ├── README.md
│ └── package.json
├── plugin-frontmatter
│ ├── tsconfig.json
│ ├── README.md
│ ├── src
│ │ └── index.ts
│ └── package.json
├── plugin-highlight
│ ├── tsconfig.json
│ ├── README.md
│ ├── src
│ │ └── index.ts
│ └── package.json
├── plugin-medium-zoom
│ ├── tsconfig.json
│ ├── README.md
│ ├── src
│ │ └── index.ts
│ └── package.json
└── plugin-highlight-ssr
│ ├── tsconfig.json
│ ├── src
│ └── index.ts
│ ├── README.md
│ └── package.json
├── examples
├── svelte
│ ├── .npmrc
│ ├── static
│ │ └── favicon.png
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── src
│ │ ├── app.html
│ │ ├── app.d.ts
│ │ └── routes
│ │ │ └── index.svelte
│ ├── svelte.config.js
│ ├── package.json
│ └── README.md
├── vue3
│ ├── env.d.ts
│ ├── public
│ │ └── favicon.ico
│ ├── src
│ │ ├── main.ts
│ │ └── App.vue
│ ├── tsconfig.vite-config.json
│ ├── tsconfig.json
│ ├── vite.config.ts
│ ├── index.html
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── vue
│ ├── .browserslistrc
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ ├── src
│ │ ├── shims-vue.d.ts
│ │ ├── main.ts
│ │ ├── shims-tsx.d.ts
│ │ └── App.vue
│ ├── .gitignore
│ ├── README.md
│ ├── package.json
│ └── tsconfig.json
├── react
│ ├── src
│ │ ├── react-app-env.d.ts
│ │ ├── App.css
│ │ ├── setupTests.ts
│ │ ├── App.test.tsx
│ │ ├── index.css
│ │ ├── reportWebVitals.ts
│ │ ├── index.tsx
│ │ └── App.tsx
│ ├── public
│ │ ├── robots.txt
│ │ ├── favicon.ico
│ │ ├── logo192.png
│ │ ├── logo512.png
│ │ ├── manifest.json
│ │ └── index.html
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── react-nextjs
│ ├── .eslintrc.json
│ ├── public
│ │ ├── favicon.ico
│ │ └── vercel.svg
│ ├── next.config.js
│ ├── next-env.d.ts
│ ├── pages
│ │ ├── _app.tsx
│ │ ├── api
│ │ │ └── hello.ts
│ │ └── index.tsx
│ ├── styles
│ │ ├── globals.css
│ │ └── Home.module.css
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── package.json
│ └── README.md
├── nuxt3
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── nuxt.config.ts
│ ├── app.vue
│ ├── package.json
│ └── README.md
├── vue-nuxtjs
│ ├── static
│ │ └── favicon.ico
│ ├── .editorconfig
│ ├── store
│ │ └── README.md
│ ├── tsconfig.json
│ ├── pages
│ │ └── index.vue
│ ├── package.json
│ ├── nuxt.config.js
│ ├── .gitignore
│ └── README.md
├── vanilla-js
│ └── index.html
└── legacy-browser
│ └── index.html
├── playground
├── src
│ ├── env.d.ts
│ ├── index.ts
│ ├── text.md
│ └── app.svelte
├── vite.config.mjs
├── tsconfig.json
├── index.html
└── package.json
├── .prettierignore
├── pnpm-workspace.yaml
├── .gitignore
├── lerna.json
├── .github
└── workflows
│ ├── test.yml
│ ├── style.yml
│ ├── release.yml
│ └── bundlewatch.yml
├── netlify.toml
├── scripts
├── deploy.sh
├── plugin-template.md
├── utils.mjs
├── icon.mjs
├── postinstall.mjs
└── build.mjs
├── tsconfig-base.json
├── vitest.config.mjs
├── tsconfig.json
├── LICENSE
└── package.json
/docs/index.md:
--------------------------------------------------------------------------------
1 | ../README.md
--------------------------------------------------------------------------------
/packages/bytemd/.gitignore:
--------------------------------------------------------------------------------
1 | /svelte
2 |
--------------------------------------------------------------------------------
/packages/bytemd/src/locales:
--------------------------------------------------------------------------------
1 | ../locales
--------------------------------------------------------------------------------
/packages/plugin-gfm/src/locales:
--------------------------------------------------------------------------------
1 | ../locales
--------------------------------------------------------------------------------
/packages/plugin-math/src/locales:
--------------------------------------------------------------------------------
1 | ../locales
--------------------------------------------------------------------------------
/examples/svelte/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 |
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/src/locales:
--------------------------------------------------------------------------------
1 | ../locales
--------------------------------------------------------------------------------
/packages/plugin-mermaid/src/locales:
--------------------------------------------------------------------------------
1 | ../locales
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/locales:
--------------------------------------------------------------------------------
1 | ../plugin-math/locales
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/src/utils:
--------------------------------------------------------------------------------
1 | ../../plugin-math/src/utils
--------------------------------------------------------------------------------
/examples/vue3/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/vue/src/editor.vue.ts:
--------------------------------------------------------------------------------
1 | export { default } from 'vue'
2 |
--------------------------------------------------------------------------------
/packages/vue/src/viewer.vue.ts:
--------------------------------------------------------------------------------
1 | export { default } from 'vue'
2 |
--------------------------------------------------------------------------------
/playground/src/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | scripts/*.md
2 | CHANGELOG.md
3 | svelte
4 | dist
5 |
--------------------------------------------------------------------------------
/examples/vue/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
3 | not dead
4 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - packages/**
3 | - playground
4 |
--------------------------------------------------------------------------------
/packages/vue/plugin.mjs:
--------------------------------------------------------------------------------
1 | export { createVuePlugin } from 'vite-plugin-vue2'
2 |
--------------------------------------------------------------------------------
/examples/react/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/packages/bytemd/README.md:
--------------------------------------------------------------------------------
1 | # ByteMD
2 |
3 | https://github.com/bytedance/bytemd
4 |
--------------------------------------------------------------------------------
/packages/bytemd/src/env.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.svelte' // to fix `tsc --build`
2 |
--------------------------------------------------------------------------------
/packages/react/README.md:
--------------------------------------------------------------------------------
1 | # ByteMD
2 |
3 | https://github.com/bytedance/bytemd
4 |
--------------------------------------------------------------------------------
/packages/vue/README.md:
--------------------------------------------------------------------------------
1 | # ByteMD
2 |
3 | https://github.com/bytedance/bytemd
4 |
--------------------------------------------------------------------------------
/examples/react-nextjs/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/vue-next/README.md:
--------------------------------------------------------------------------------
1 | # ByteMD
2 |
3 | https://github.com/bytedance/bytemd
4 |
--------------------------------------------------------------------------------
/packages/vue-next/src/editor.vue.ts:
--------------------------------------------------------------------------------
1 | export { DefineComponent as default } from 'vue'
2 |
--------------------------------------------------------------------------------
/packages/vue-next/src/viewer.vue.ts:
--------------------------------------------------------------------------------
1 | export { DefineComponent as default } from 'vue'
2 |
--------------------------------------------------------------------------------
/examples/react/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | max-width: 1200px;
3 | margin: 0 auto;
4 | }
5 |
--------------------------------------------------------------------------------
/packages/vue-next/plugin.mjs:
--------------------------------------------------------------------------------
1 | export { default as createVue3Plugin } from '@vitejs/plugin-vue'
2 |
--------------------------------------------------------------------------------
/examples/react/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/examples/nuxt3/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log*
3 | .nuxt
4 | .nitro
5 | .cache
6 | .output
7 | .env
8 | dist
9 |
--------------------------------------------------------------------------------
/examples/vue/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/vue/public/favicon.ico
--------------------------------------------------------------------------------
/examples/vue3/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/vue3/public/favicon.ico
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | .DS_Store
3 | node_modules
4 | dist
5 | tsconfig.tsbuildinfo
6 | coverage
7 | packages/*/LICENSE
8 |
--------------------------------------------------------------------------------
/examples/react/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/react/public/favicon.ico
--------------------------------------------------------------------------------
/examples/react/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/react/public/logo192.png
--------------------------------------------------------------------------------
/examples/react/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/react/public/logo512.png
--------------------------------------------------------------------------------
/examples/svelte/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/svelte/static/favicon.png
--------------------------------------------------------------------------------
/examples/vue/src/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue'
3 | export default Vue
4 | }
5 |
--------------------------------------------------------------------------------
/examples/nuxt3/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | // https://v3.nuxtjs.org/concepts/typescript
3 | "extends": "./.nuxt/tsconfig.json"
4 | }
5 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/static/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/vue-nuxtjs/static/favicon.ico
--------------------------------------------------------------------------------
/examples/vue3/src/main.ts:
--------------------------------------------------------------------------------
1 | import App from './App.vue'
2 | import { createApp } from 'vue'
3 |
4 | createApp(App).mount('#app')
5 |
--------------------------------------------------------------------------------
/packages/vue/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Editor } from './editor.vue'
2 | export { default as Viewer } from './viewer.vue'
3 |
--------------------------------------------------------------------------------
/examples/react-nextjs/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/natanfelles/bytemd/main/examples/react-nextjs/public/favicon.ico
--------------------------------------------------------------------------------
/examples/svelte/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 |
--------------------------------------------------------------------------------
/packages/vue-next/src/index.ts:
--------------------------------------------------------------------------------
1 | export { default as Editor } from './editor.vue'
2 | export { default as Viewer } from './viewer.vue'
3 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/ja.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "ブロック 公式",
3 | "blockText": "公式",
4 | "inline": "インライン公式",
5 | "inlineText": "公式"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/zh_Hans.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "块级公式",
3 | "blockText": "公式",
4 | "inline": "行内公式",
5 | "inlineText": "公式"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/zh_Hant.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "塊級公式",
3 | "blockText": "公式",
4 | "inline": "內聯公式",
5 | "inlineText": "公式"
6 | }
7 |
--------------------------------------------------------------------------------
/playground/src/index.ts:
--------------------------------------------------------------------------------
1 | import App from './app.svelte'
2 |
3 | const app = new App({
4 | target: document.body,
5 | })
6 |
7 | export default app
8 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/ar.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "صيغة الكتلة",
3 | "blockText": "صيغة",
4 | "inline": "صيغة مضمنة",
5 | "inlineText": "صيغة"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/id.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Blok rumus",
3 | "blockText": "rumus",
4 | "inline": "Rumus sebaris",
5 | "inlineText": "rumus"
6 | }
7 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/custom.css:
--------------------------------------------------------------------------------
1 | /* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css */
2 | :root {
3 | --c-brand: #0969da;
4 | }
5 |
--------------------------------------------------------------------------------
/examples/react-nextjs/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | reactStrictMode: true,
4 | }
5 |
6 | module.exports = nextConfig
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Block formula",
3 | "blockText": "formula",
4 | "inline": "Inline formula",
5 | "inlineText": "formula"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Formule en bloc",
3 | "blockText": "formule",
4 | "inline": "Formule en ligne",
5 | "inlineText": "formule"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Blok formülü",
3 | "blockText": "formül",
4 | "inline": "Satır içi formülü",
5 | "inlineText": "formül"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Fórmula en bloc",
3 | "blockText": "fórmula",
4 | "inline": "Fórmula en el cos",
5 | "inlineText": "fórmula"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Fórmula en bloque",
3 | "blockText": "fórmula",
4 | "inline": "Fórmula en renglón",
5 | "inlineText": "fórmula"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/nb_NO.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Blokkformel",
3 | "blockText": "formel",
4 | "inline": "Formel på samme linje",
5 | "inlineText": "formel"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/pt_BR.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Bloco de Fórmula",
3 | "blockText": "fórmula",
4 | "inline": "Fórmula em linha",
5 | "inlineText": "fórmula"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Блочная формула",
3 | "blockText": "формула",
4 | "inline": "Встроенная формула",
5 | "inlineText": "формула"
6 | }
7 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json",
3 | "useWorkspaces": true,
4 | "version": "1.22.0",
5 | "registry": "https://registry.npmjs.org"
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/locales/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "block": "Wzór eksponowany",
3 | "blockText": "wzór eksponowany",
4 | "inline": "Wzór w tekście",
5 | "inlineText": "wzór w tekście"
6 | }
7 |
--------------------------------------------------------------------------------
/examples/vue/src/main.ts:
--------------------------------------------------------------------------------
1 | import App from './App.vue'
2 | import Vue from 'vue'
3 |
4 | Vue.config.productionTip = false
5 |
6 | new Vue({
7 | render: (h) => h(App),
8 | }).$mount('#app')
9 |
--------------------------------------------------------------------------------
/packages/bytemd/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" }
5 | }
6 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/zh_Hans.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "删除线",
3 | "strikeText": "文本",
4 | "table": "表格",
5 | "tableHeading": "标题",
6 | "task": "任务列表",
7 | "taskText": "待办事项"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/zh_Hant.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "刪除線",
3 | "strikeText": "文本",
4 | "table": "表格",
5 | "tableHeading": "標題",
6 | "task": "任務列表",
7 | "taskText": "待辦事項"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/react/src/index.ts:
--------------------------------------------------------------------------------
1 | export { Editor } from './editor'
2 | export type { EditorProps } from './editor'
3 | export { Viewer } from './viewer'
4 | export type { ViewerProps } from './viewer'
5 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/ar.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "توسيط خط",
3 | "strikeText": "نص",
4 | "table": "جدول",
5 | "tableHeading": "عنوان",
6 | "task": "قائمة المهام",
7 | "taskText": "مهام"
8 | }
9 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/index.js:
--------------------------------------------------------------------------------
1 | // https://vitepress.vuejs.org/guide/theming.html#customizing-css
2 |
3 | import DefaultTheme from 'vitepress/theme'
4 | import './custom.css'
5 |
6 | export default DefaultTheme
7 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Strikethrough",
3 | "strikeText": "text",
4 | "table": "Table",
5 | "tableHeading": "Heading",
6 | "task": "Task list",
7 | "taskText": "todo"
8 | }
9 |
--------------------------------------------------------------------------------
/examples/nuxt3/nuxt.config.ts:
--------------------------------------------------------------------------------
1 | import { defineNuxtConfig } from 'nuxt'
2 |
3 | // https://v3.nuxtjs.org/api/configuration/nuxt.config
4 | export default defineNuxtConfig({
5 | css: ['bytemd/dist/index.css'],
6 | })
7 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Tachado",
3 | "strikeText": "texto",
4 | "table": "Tabla",
5 | "tableHeading": "Título",
6 | "task": "Lista de tareas",
7 | "taskText": "pendientes"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Barré",
3 | "strikeText": "texte",
4 | "table": "Tableau",
5 | "tableHeading": "Titre",
6 | "task": "Liste de tâches",
7 | "taskText": "à-faire"
8 | }
9 |
--------------------------------------------------------------------------------
/examples/vue3/tsconfig.vite-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.node.json",
3 | "include": ["vite.config.*"],
4 | "compilerOptions": {
5 | "composite": true,
6 | "types": ["node"]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/id.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Coret Kata",
3 | "strikeText": "teks",
4 | "table": "Tabel",
5 | "tableHeading": "Tajuk",
6 | "task": "Daftar tugas",
7 | "taskText": "untuk-dilakukan"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "przekreślenie",
3 | "strikeText": "tekst",
4 | "table": "tabela",
5 | "tableHeading": "nagłówek",
6 | "task": "lista zadań",
7 | "taskText": "zadanie"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Зачеркнутый",
3 | "strikeText": "текст",
4 | "table": "Таблица",
5 | "tableHeading": "Заголовок",
6 | "task": "Список задач",
7 | "taskText": "задача"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Üstü çizili",
3 | "strikeText": "metin",
4 | "table": "Tablo",
5 | "tableHeading": "Başlık",
6 | "task": "Görev listesi",
7 | "taskText": "yapılacak"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Ratllat",
3 | "strikeText": "text",
4 | "table": "Taula",
5 | "tableHeading": "Encapçalament",
6 | "task": "Llista de tasques",
7 | "taskText": "pendents"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/nb_NO.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Gjennomstrek",
3 | "strikeText": "tekst",
4 | "table": "Tabell",
5 | "tableHeading": "Overskrift",
6 | "task": "Gjøremålsliste",
7 | "taskText": "gjøremål"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Durchstreichen",
3 | "strikeText": "Text",
4 | "table": "Tabelle",
5 | "tableHeading": "Überschrift",
6 | "task": "Aufgabenliste",
7 | "taskText": "Noch zu tun"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/bytemd/src/index.ts:
--------------------------------------------------------------------------------
1 | import './index.scss'
2 |
3 | export * from './types'
4 | export { default as Editor } from './editor.svelte'
5 | export { default as Viewer } from './viewer.svelte'
6 | export { getProcessor } from './utils'
7 |
--------------------------------------------------------------------------------
/packages/vue/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/locales/pt_BR.json:
--------------------------------------------------------------------------------
1 | {
2 | "strike": "Riscado",
3 | "strikeText": "texto riscado",
4 | "table": "Tabela",
5 | "tableHeading": "Cabeçalho da tabela",
6 | "task": "Tarefa",
7 | "taskText": "texto da tarefa"
8 | }
9 |
--------------------------------------------------------------------------------
/packages/react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/vue-next/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-breaks/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-gemoji/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/examples/react-nextjs/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/packages/plugin-frontmatter/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-highlight/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-medium-zoom/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-highlight-ssr/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [{ "path": "../bytemd" }]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/plugin-breaks/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { BytemdPlugin } from 'bytemd'
2 | import remarkBreaks from 'remark-breaks'
3 |
4 | export default function breaks(): BytemdPlugin {
5 | return {
6 | remark: (processor) => processor.use(remarkBreaks),
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/plugin-gemoji/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { BytemdPlugin } from 'bytemd'
2 | import remarkGemoji from 'remark-gemoji'
3 |
4 | export default function gemoji(): BytemdPlugin {
5 | return {
6 | remark: (processor) => processor.use(remarkGemoji),
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/react/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom'
6 |
--------------------------------------------------------------------------------
/examples/react-nextjs/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import '../styles/globals.css'
2 | import 'bytemd/dist/index.css'
3 | import type { AppProps } from 'next/app'
4 |
5 | function MyApp({ Component, pageProps }: AppProps) {
6 | return
7 | }
8 |
9 | export default MyApp
10 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/zgh.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "ⴰⵎⵉⵔⵉⵡ",
3 | "boldText": "ⴰⴹⵕⵉⵚ ⵉⵔⵉⵡⵏ",
4 | "closeHelp": "ⵇⵇⵏ ⵜⵉⵡⵉⵙⵉ",
5 | "closeToc": "ⵇⵇⵏ ⵜⴰⵍⴳⴰⵎⵜ ⵏ ⵓⴽⵜⵜⵓⵔ",
6 | "code": "ⵉⵏⵉⴳⵍ",
7 | "codeBlock": "ⴰⴱⵍⵓⴽ ⵏ ⵉⵏⵉⴳⵍ",
8 | "codeLang": "ⵜⵓⵜⵍⴰⵢⵜ",
9 | "codeText": "ⵉⵏⵉⴳⵍ"
10 | }
11 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/examples/vue/src/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from 'vue'
2 |
3 | declare global {
4 | namespace JSX {
5 | interface Element extends VNode {}
6 | interface ElementClass extends Vue {}
7 | interface IntrinsicElements {
8 | [elem: string]: any
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/bytemd/tsconfig.svelte.json:
--------------------------------------------------------------------------------
1 | // for svelte entry
2 | {
3 | "extends": "../../tsconfig-base.json",
4 | "include": ["src"],
5 | "compilerOptions": {
6 | "rootDir": "src",
7 | "outDir": "svelte",
8 | "composite": false,
9 | "emitDeclarationOnly": false
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "private": true,
4 | "scripts": {
5 | "build": "vitepress build .",
6 | "dev": "vitepress dev .",
7 | "serve": "vitepress serve ."
8 | },
9 | "dependencies": {
10 | "vitepress": "1.0.0-alpha.1",
11 | "vue": "^3.2.37"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/zh_Hans.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "类图",
3 | "er": "关系图",
4 | "flowchart": "流程图",
5 | "gantt": "甘特图",
6 | "mermaid": "Mermaid图表",
7 | "mindmap": "思维导图",
8 | "pie": "饼状图",
9 | "sequence": "时序图",
10 | "state": "状态图",
11 | "timeline": "时间轴",
12 | "uj": "旅程图"
13 | }
14 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: test
2 | on:
3 | push:
4 | pull_request:
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 | - uses: actions/setup-node@v3
11 | - run: corepack enable
12 | - run: pnpm install
13 | - run: pnpm test
14 |
--------------------------------------------------------------------------------
/.github/workflows/style.yml:
--------------------------------------------------------------------------------
1 | name: style
2 | on:
3 | push:
4 | pull_request:
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 | - uses: actions/setup-node@v3
11 | - run: corepack enable
12 | - run: pnpm install
13 | - run: pnpm style
14 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | # https://docs.netlify.com/configure-builds/file-based-configuration/#configuration-details
2 | # https://answers.netlify.com/t/using-pnpm-and-pnpm-workspaces/2759
3 | [build.environment]
4 | NPM_FLAGS="--prefix=/dev/null"
5 |
6 | [build]
7 | publish = "docs/.vitepress/dist"
8 | command = "bash scripts/deploy.sh"
9 |
--------------------------------------------------------------------------------
/examples/react/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import App from './App'
2 | import { render, screen } from '@testing-library/react'
3 | import React from 'react'
4 |
5 | test('renders learn react link', () => {
6 | render( )
7 | const linkElement = screen.getByText(/learn react/i)
8 | expect(linkElement).toBeInTheDocument()
9 | })
10 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/ar.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "مخططات الفئات",
3 | "er": "مخطط علاقات العناصر",
4 | "flowchart": "خارطة سير المعلومات",
5 | "gantt": "خارطة جانت",
6 | "mermaid": "مخطط ميرميد",
7 | "pie": "مخطط دائري",
8 | "sequence": "مخطط متسلسل",
9 | "state": "مخطط حالة الآلة",
10 | "uj": "مخطط رحلة المستخدم"
11 | }
12 |
--------------------------------------------------------------------------------
/examples/svelte/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "allowJs": true,
5 | "checkJs": true,
6 | "esModuleInterop": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "resolveJsonModule": true,
9 | "skipLibCheck": true,
10 | "sourceMap": true,
11 | "strict": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/examples/svelte/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
10 | %sveltekit.body%
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/vue/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/nb_NO.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Klassediagram",
3 | "er": "Enhetsrelaskonsdiagram",
4 | "flowchart": "Flytskjema",
5 | "gantt": "Gantt-skjema",
6 | "mermaid": "Mermaid-diagrammer",
7 | "pie": "Kakediagram",
8 | "sequence": "Sekvensdiagram",
9 | "state": "Tilstandsdiagram",
10 | "uj": "Brukerreisediagram"
11 | }
12 |
--------------------------------------------------------------------------------
/examples/svelte/src/app.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | // See https://kit.svelte.dev/docs/types#app
4 | // for information about these interfaces
5 | // and what to do when importing types
6 | declare namespace App {
7 | // interface Locals {}
8 | // interface Platform {}
9 | // interface Session {}
10 | // interface Stuff {}
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/id.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Diagram kelas",
3 | "er": "Diagram hubungan entitas",
4 | "flowchart": "Bagan alur",
5 | "gantt": "Bagan Gantt",
6 | "mermaid": "Diagram Mermaid",
7 | "pie": "Bagan pai",
8 | "sequence": "Diagram urutan",
9 | "state": "Diagram kondisi",
10 | "uj": "Diagram penjelajahan pengguna"
11 | }
12 |
--------------------------------------------------------------------------------
/scripts/deploy.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | npm i -g pnpm
4 | pnpm install
5 |
6 | # packages
7 | pnpm build
8 |
9 | # docs
10 | cd docs
11 | npm install # not in workspace because of Vue 2/3 version
12 | pnpm build
13 |
14 | # playground
15 | cd ..
16 | pnpm --filter playground build
17 |
18 | # move assets
19 | mv playground/dist docs/.vitepress/dist/playground
20 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Diagram klas",
3 | "er": "Diagram relacji encji",
4 | "flowchart": "Schemat blokowy",
5 | "gantt": "Wykres Gantta",
6 | "mermaid": "Diagramy syren",
7 | "pie": "Wykres kołowy",
8 | "sequence": "Diagram interakcji",
9 | "state": "Diagram stanu",
10 | "uj": "Diagram podróży użytkownika"
11 | }
12 |
--------------------------------------------------------------------------------
/examples/vue3/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@vue/tsconfig/tsconfig.web.json",
3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
4 | "compilerOptions": {
5 | "baseUrl": ".",
6 | "paths": {
7 | "@/*": ["./src/*"]
8 | }
9 | },
10 |
11 | "references": [
12 | {
13 | "path": "./tsconfig.vite-config.json"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Klassendiagramm",
3 | "er": "Entity-Relationship-Diagramm",
4 | "flowchart": "Flussdiagramm",
5 | "gantt": "Gantt-Diagramm",
6 | "mermaid": "Mermaid-Diagramme",
7 | "pie": "Kreisdiagramm",
8 | "sequence": "Sequenzdiagramm",
9 | "state": "Zustandsdiagramm",
10 | "uj": "User Journey-Diagramm"
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Sınıf diyagramı",
3 | "er": "Varlık ilişki diyagramı",
4 | "flowchart": "Akış diyagramı",
5 | "gantt": "Gantt şeması",
6 | "mermaid": "Mermaid diyagramları",
7 | "pie": "Pasta grafiği",
8 | "sequence": "Sıra diyagramı",
9 | "state": "Durum diyagramı",
10 | "uj": "Kullanıcı yolculuk diyagramı"
11 | }
12 |
--------------------------------------------------------------------------------
/examples/vue3/vite.config.ts:
--------------------------------------------------------------------------------
1 | import vue from '@vitejs/plugin-vue'
2 | import { fileURLToPath, URL } from 'url'
3 | import { defineConfig } from 'vite'
4 |
5 | // https://vitejs.dev/config/
6 | export default defineConfig({
7 | plugins: [vue()],
8 | resolve: {
9 | alias: {
10 | '@': fileURLToPath(new URL('./src', import.meta.url)),
11 | },
12 | },
13 | })
14 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/pt_BR.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Diagrama de classes",
3 | "er": "Entidade Relacionada",
4 | "flowchart": "Fluxograma",
5 | "gantt": "Gráfico Gantt",
6 | "mermaid": "Diagrama Mermaid",
7 | "pie": "Gráfico de Pizza",
8 | "sequence": "Diagrama de sequência",
9 | "state": "Gráfico de fluxo de estado",
10 | "uj": "Diagrama de casos de uso"
11 | }
12 |
--------------------------------------------------------------------------------
/playground/vite.config.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { svelte } from '@sveltejs/vite-plugin-svelte'
3 | import sveltePreprocess from 'svelte-preprocess'
4 | import { defineConfig } from 'vite'
5 |
6 | export default defineConfig({
7 | base: '/playground/',
8 | plugins: [
9 | svelte({
10 | preprocess: [sveltePreprocess({ typescript: true })],
11 | }),
12 | ],
13 | })
14 |
--------------------------------------------------------------------------------
/examples/react-nextjs/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 | import type { NextApiRequest, NextApiResponse } from 'next'
3 |
4 | type Data = {
5 | name: string
6 | }
7 |
8 | export default function handler(
9 | req: NextApiRequest,
10 | res: NextApiResponse
11 | ) {
12 | res.status(200).json({ name: 'John Doe' })
13 | }
14 |
--------------------------------------------------------------------------------
/examples/vue/README.md:
--------------------------------------------------------------------------------
1 | # example-vue
2 |
3 | ## Project setup
4 |
5 | ```
6 | yarn install
7 | ```
8 |
9 | ### Compiles and hot-reloads for development
10 |
11 | ```
12 | yarn serve
13 | ```
14 |
15 | ### Compiles and minifies for production
16 |
17 | ```
18 | yarn build
19 | ```
20 |
21 | ### Customize configuration
22 |
23 | See [Configuration Reference](https://cli.vuejs.org/config/).
24 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: release
2 | on:
3 | push:
4 | tags:
5 | - v*
6 | jobs:
7 | release:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v3
11 | with:
12 | fetch-depth: 0
13 | - uses: actions/setup-node@v3
14 | - run: npx changelogithub
15 | env:
16 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
17 |
--------------------------------------------------------------------------------
/tsconfig-base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "skipLibCheck": true,
4 | "target": "ESNext",
5 | "module": "ESNext",
6 | "jsx": "react",
7 | "strict": true,
8 | "moduleResolution": "node",
9 | "esModuleInterop": true,
10 | "resolveJsonModule": true,
11 | "composite": true,
12 | "emitDeclarationOnly": true
13 | },
14 | "exclude": ["**/__tests__"]
15 | }
16 |
--------------------------------------------------------------------------------
/packages/plugin-highlight-ssr/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { BytemdPlugin } from 'bytemd'
2 | import rehypeHighlight, { Options } from 'rehype-highlight'
3 |
4 | export default function highlightSsr({
5 | ignoreMissing = true,
6 | ...rest
7 | }: Options = {}): BytemdPlugin {
8 | return {
9 | rehype: (processor) =>
10 | processor.use(rehypeHighlight, { ignoreMissing, ...rest }),
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Diagrama de classes",
3 | "er": "Diagrama entitat-relació",
4 | "flowchart": "Diagrama de flux",
5 | "gantt": "Diagrama de Gantt",
6 | "mermaid": "Diagrames del Mermaid",
7 | "pie": "Diagrama sectorial",
8 | "sequence": "Diagrama de seqüències",
9 | "state": "Diagrama d’estats",
10 | "uj": "Diagrama de recorregut d’usuari"
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Diagrama de clases",
3 | "er": "Diagrama de entidad-relación",
4 | "flowchart": "Diagrama de flujo",
5 | "gantt": "Diagrama de Gantt",
6 | "mermaid": "Diagramas de Mermaid",
7 | "pie": "Gráfico sectorial",
8 | "sequence": "Diagrama de secuencia",
9 | "state": "Diagrama de estado",
10 | "uj": "Diagrama de trayecto de usuario"
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Диаграмма классов",
3 | "er": "Диаграмма отношений сущностей",
4 | "flowchart": "Блок-схема",
5 | "gantt": "Диаграмма Ганта",
6 | "mermaid": "Диаграммы Mermaid",
7 | "pie": "Круговая диаграмма",
8 | "sequence": "Диаграмма последовательностей",
9 | "state": "Диаграмма состояния",
10 | "uj": "Диаграмма пользовательского опыта"
11 | }
12 |
--------------------------------------------------------------------------------
/examples/vue3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Diagramme de classes",
3 | "er": "Diagramme de relation entre entités",
4 | "flowchart": "Organigramme",
5 | "gantt": "Diagramme de Gantt",
6 | "mermaid": "Diagrammes Mermaid",
7 | "pie": "Graphique circulaire",
8 | "sequence": "Diagramme de séquences",
9 | "state": "Diagramme d'état",
10 | "uj": "Diagramme de parcours utilisateur"
11 | }
12 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "class": "Class diagram",
3 | "er": "Entity relationship diagram",
4 | "flowchart": "Flow chart",
5 | "gantt": "Gantt chart",
6 | "mermaid": "Mermaid diagrams",
7 | "mindmap": "Mindmaps",
8 | "pie": "Pie chart",
9 | "sequence": "Sequence diagram",
10 | "state": "State diagram",
11 | "timeline": "Timeline",
12 | "uj": "User journey diagram"
13 | }
14 |
--------------------------------------------------------------------------------
/examples/react-nextjs/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | max-width: 1200px;
8 | margin: 0 auto;
9 | }
10 |
11 | a {
12 | color: inherit;
13 | text-decoration: none;
14 | }
15 |
16 | * {
17 | box-sizing: border-box;
18 | }
19 |
--------------------------------------------------------------------------------
/examples/react/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/examples/svelte/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from '@sveltejs/adapter-auto';
2 | import preprocess from 'svelte-preprocess';
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | // Consult https://github.com/sveltejs/svelte-preprocess
7 | // for more information about preprocessors
8 | preprocess: preprocess(),
9 |
10 | kit: {
11 | adapter: adapter()
12 | }
13 | };
14 |
15 | export default config;
16 |
--------------------------------------------------------------------------------
/examples/nuxt3/app.vue:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/nuxt3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-nuxt3",
3 | "scripts": {
4 | "build": "nuxt build",
5 | "dev": "nuxt dev",
6 | "generate": "nuxt generate",
7 | "preview": "nuxt preview"
8 | },
9 | "devDependencies": {
10 | "nuxt": "3.0.0-rc.4"
11 | },
12 | "dependencies": {
13 | "@bytemd/plugin-gfm": "latest",
14 | "@bytemd/vue-next": "latest",
15 | "bytemd": "latest"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/react/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/vue3/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | .DS_Store
12 | dist
13 | dist-ssr
14 | coverage
15 | *.local
16 |
17 | /cypress/videos/
18 | /cypress/screenshots/
19 |
20 | # Editor directories and files
21 | .vscode/*
22 | !.vscode/extensions.json
23 | .idea
24 | *.suo
25 | *.ntvs*
26 | *.njsproj
27 | *.sln
28 | *.sw?
29 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/store/README.md:
--------------------------------------------------------------------------------
1 | # STORE
2 |
3 | **This directory is not required, you can delete it if you don't want to use it.**
4 |
5 | This directory contains your Vuex Store files. Vuex Store option is implemented in the Nuxt.js framework.
6 |
7 | Creating a file in this directory automatically activates the option in the framework.
8 |
9 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).
10 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/src/icons.ts:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT, generated by scripts/icon.ts
2 | export const icons = {
3 | ChartGraph:
4 | ' ',
5 | }
6 |
--------------------------------------------------------------------------------
/.github/workflows/bundlewatch.yml:
--------------------------------------------------------------------------------
1 | name: bundlewatch
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v3
12 | - uses: actions/setup-node@v3
13 | - run: corepack enable
14 | - run: pnpm install
15 | - run: pnpm build
16 | - run: npx bundlewatch
17 | env:
18 | BUNDLEWATCH_GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
19 |
--------------------------------------------------------------------------------
/docs/.vitepress/config.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { defineConfig } from 'vitepress'
3 |
4 | export default defineConfig({
5 | title: 'ByteMD',
6 | description: 'Hackable Markdown Editor and Viewer',
7 | themeConfig: {
8 | nav: [
9 | {
10 | text: 'Playground',
11 | link: 'https://bytemd.js.org/playground/',
12 | },
13 | {
14 | text: 'GitHub',
15 | link: 'https://github.com/bytedance/bytemd',
16 | },
17 | ],
18 | },
19 | })
20 |
--------------------------------------------------------------------------------
/examples/react/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals'
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry)
7 | getFID(onPerfEntry)
8 | getFCP(onPerfEntry)
9 | getLCP(onPerfEntry)
10 | getTTFB(onPerfEntry)
11 | })
12 | }
13 | }
14 |
15 | export default reportWebVitals
16 |
--------------------------------------------------------------------------------
/examples/svelte/src/routes/index.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | {
14 | value = e.detail.value
15 | }}
16 | {plugins}
17 | />
18 |
19 |
20 |
26 |
--------------------------------------------------------------------------------
/vitest.config.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { sveltePreprocessor } from './scripts/utils.mjs'
3 | import { svelte } from '@sveltejs/vite-plugin-svelte'
4 | import { defineConfig } from 'vitest/config'
5 |
6 | export default defineConfig({
7 | test: {
8 | include: ['packages/bytemd/**/*.test.ts'],
9 | globals: true,
10 | environment: 'jsdom',
11 | setupFiles: 'packages/bytemd/test/setup.ts',
12 | },
13 | plugins: [
14 | svelte({
15 | preprocess: [sveltePreprocessor],
16 | }),
17 | ],
18 | })
19 |
--------------------------------------------------------------------------------
/packages/plugin-breaks/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-breaks
2 |
3 | [](https://npm.im/@bytemd/plugin-breaks)
4 |
5 | ByteMD plugin to support breaks
6 |
7 | ## Usage
8 |
9 | ```js
10 | import breaks from '@bytemd/plugin-breaks'
11 | import { Editor } from 'bytemd'
12 |
13 | new Editor({
14 | target: document.body,
15 | props: {
16 | plugins: [
17 | breaks(),
18 | // ... other plugins
19 | ],
20 | },
21 | })
22 | ```
23 |
24 | ## License
25 |
26 | MIT
27 |
--------------------------------------------------------------------------------
/packages/plugin-gemoji/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-gemoji
2 |
3 | [](https://npm.im/@bytemd/plugin-gemoji)
4 |
5 | ByteMD plugin to support Gemoji shortcodes
6 |
7 | ## Usage
8 |
9 | ```js
10 | import gemoji from '@bytemd/plugin-gemoji'
11 | import { Editor } from 'bytemd'
12 |
13 | new Editor({
14 | target: document.body,
15 | props: {
16 | plugins: [
17 | gemoji(),
18 | // ... other plugins
19 | ],
20 | },
21 | })
22 | ```
23 |
24 | ## License
25 |
26 | MIT
27 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-mermaid
2 |
3 | [](https://npm.im/@bytemd/plugin-mermaid)
4 |
5 | ByteMD plugin to support Mermaid diagram
6 |
7 | ## Usage
8 |
9 | ```js
10 | import mermaid from '@bytemd/plugin-mermaid'
11 | import { Editor } from 'bytemd'
12 |
13 | new Editor({
14 | target: document.body,
15 | props: {
16 | plugins: [
17 | mermaid(),
18 | // ... other plugins
19 | ],
20 | },
21 | })
22 | ```
23 |
24 | ## License
25 |
26 | MIT
27 |
--------------------------------------------------------------------------------
/examples/react-nextjs/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 |
--------------------------------------------------------------------------------
/packages/plugin-math/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-math
2 |
3 | [](https://npm.im/@bytemd/plugin-math)
4 |
5 | ByteMD plugin to support math formula
6 |
7 | ## Usage
8 |
9 | ```js
10 | import math from '@bytemd/plugin-math'
11 | import { Editor } from 'bytemd'
12 | import 'katex/dist/katex.css'
13 |
14 | new Editor({
15 | target: document.body,
16 | props: {
17 | plugins: [
18 | math(),
19 | // ... other plugins
20 | ],
21 | },
22 | })
23 | ```
24 |
25 | ## License
26 |
27 | MIT
28 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-gfm
2 |
3 | [](https://npm.im/@bytemd/plugin-gfm)
4 |
5 | ByteMD plugin to support GFM (autolink literals, strikethrough, tables, tasklists)
6 |
7 | ## Usage
8 |
9 | ```js
10 | import gfm from '@bytemd/plugin-gfm'
11 | import { Editor } from 'bytemd'
12 |
13 | new Editor({
14 | target: document.body,
15 | props: {
16 | plugins: [
17 | gfm(),
18 | // ... other plugins
19 | ],
20 | },
21 | })
22 | ```
23 |
24 | ## License
25 |
26 | MIT
27 |
--------------------------------------------------------------------------------
/packages/plugin-frontmatter/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-frontmatter
2 |
3 | [](https://npm.im/@bytemd/plugin-frontmatter)
4 |
5 | ByteMD plugin to parse frontmatter
6 |
7 | ## Usage
8 |
9 | ```js
10 | import frontmatter from '@bytemd/plugin-frontmatter'
11 | import { Editor } from 'bytemd'
12 |
13 | new Editor({
14 | target: document.body,
15 | props: {
16 | plugins: [
17 | frontmatter(),
18 | // ... other plugins
19 | ],
20 | },
21 | })
22 | ```
23 |
24 | ## License
25 |
26 | MIT
27 |
--------------------------------------------------------------------------------
/packages/plugin-medium-zoom/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-medium-zoom
2 |
3 | [](https://npm.im/@bytemd/plugin-medium-zoom)
4 |
5 | ByteMD plugin to zoom images like Medium
6 |
7 | ## Usage
8 |
9 | ```js
10 | import mediumZoom from '@bytemd/plugin-medium-zoom'
11 | import { Editor } from 'bytemd'
12 |
13 | new Editor({
14 | target: document.body,
15 | props: {
16 | plugins: [
17 | mediumZoom(),
18 | // ... other plugins
19 | ],
20 | },
21 | })
22 | ```
23 |
24 | ## License
25 |
26 | MIT
27 |
--------------------------------------------------------------------------------
/examples/react/src/index.tsx:
--------------------------------------------------------------------------------
1 | import App from './App'
2 | import './index.css'
3 | import reportWebVitals from './reportWebVitals'
4 | import React from 'react'
5 | import ReactDOM from 'react-dom'
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | )
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals()
18 |
--------------------------------------------------------------------------------
/examples/vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-vue",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "vue-cli-service build",
7 | "serve": "vue-cli-service serve"
8 | },
9 | "dependencies": {
10 | "@bytemd/plugin-gfm": "latest",
11 | "@bytemd/vue": "latest",
12 | "bytemd": "latest",
13 | "vue": "^2.6.14"
14 | },
15 | "devDependencies": {
16 | "@vue/cli-plugin-typescript": "~5.0.0",
17 | "@vue/cli-service": "~5.0.0",
18 | "typescript": "~4.5.5",
19 | "vue-template-compiler": "^2.6.14"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-math-ssr
2 |
3 | [](https://npm.im/@bytemd/plugin-math-ssr)
4 |
5 | ByteMD plugin to support math formula (SSR compatible)
6 |
7 | ## Usage
8 |
9 | ```js
10 | import math from '@bytemd/plugin-math-ssr'
11 | import { Editor } from 'bytemd'
12 | import 'katex/dist/katex.css'
13 |
14 | new Editor({
15 | target: document.body,
16 | props: {
17 | plugins: [
18 | math(),
19 | // ... other plugins
20 | ],
21 | },
22 | })
23 | ```
24 |
25 | ## License
26 |
27 | MIT
28 |
--------------------------------------------------------------------------------
/examples/react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src"]
20 | }
21 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": ["ESNext", "ESNext.AsyncIterable", "DOM"],
7 | "esModuleInterop": true,
8 | "allowJs": true,
9 | "sourceMap": true,
10 | "strict": true,
11 | "noEmit": true,
12 | "experimentalDecorators": true,
13 | "baseUrl": ".",
14 | "paths": {
15 | "~/*": ["./*"],
16 | "@/*": ["./*"]
17 | },
18 | "types": ["@nuxt/types", "@types/node"]
19 | },
20 | "exclude": ["node_modules", ".nuxt", "dist"]
21 | }
22 |
--------------------------------------------------------------------------------
/packages/plugin-highlight/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-highlight
2 |
3 | [](https://npm.im/@bytemd/plugin-highlight)
4 |
5 | ByteMD plugin to highlight code blocks
6 |
7 | ## Usage
8 |
9 | ```js
10 | import highlight from '@bytemd/plugin-highlight'
11 | import { Editor } from 'bytemd'
12 | import 'highlight.js/styles/default.css'
13 |
14 | new Editor({
15 | target: document.body,
16 | props: {
17 | plugins: [
18 | highlight(),
19 | // ... other plugins
20 | ],
21 | },
22 | })
23 | ```
24 |
25 | ## License
26 |
27 | MIT
28 |
--------------------------------------------------------------------------------
/examples/react-nextjs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true
17 | },
18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
19 | "exclude": ["node_modules"]
20 | }
21 |
--------------------------------------------------------------------------------
/examples/react/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
25 |
26 |
32 |
--------------------------------------------------------------------------------
/packages/plugin-highlight-ssr/README.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-highlight-ssr
2 |
3 | [](https://npm.im/@bytemd/plugin-highlight-ssr)
4 |
5 | ByteMD plugin to highlight code blocks (SSR compatible)
6 |
7 | ## Usage
8 |
9 | ```js
10 | import highlight from '@bytemd/plugin-highlight-ssr'
11 | import { Editor } from 'bytemd'
12 | import 'highlight.js/styles/default.css'
13 |
14 | new Editor({
15 | target: document.body,
16 | props: {
17 | plugins: [
18 | highlight(),
19 | // ... other plugins
20 | ],
21 | },
22 | })
23 | ```
24 |
25 | ## License
26 |
27 | MIT
28 |
--------------------------------------------------------------------------------
/examples/vue3/src/App.vue:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
30 |
--------------------------------------------------------------------------------
/examples/vue3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-vue3",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "build": "vue-tsc --noEmit && vite build",
6 | "dev": "vite",
7 | "preview": "vite preview --port 5050",
8 | "typecheck": "vue-tsc --noEmit"
9 | },
10 | "dependencies": {
11 | "@bytemd/plugin-gfm": "latest",
12 | "@bytemd/vue-next": "latest",
13 | "bytemd": "latest",
14 | "vue": "^3.2.31"
15 | },
16 | "devDependencies": {
17 | "@types/node": "^16.11.25",
18 | "@vitejs/plugin-vue": "^2.2.2",
19 | "@vue/tsconfig": "^0.1.3",
20 | "typescript": "~4.5.5",
21 | "vite": "^2.8.4",
22 | "vue-tsc": "^0.31.4"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/scripts/plugin-template.md:
--------------------------------------------------------------------------------
1 | # @bytemd/plugin-{{name}}
2 |
3 | [](https://npm.im/@bytemd/plugin-{{name}})
4 |
5 | {{{desc}}}
6 |
7 | ## Usage
8 |
9 | ```js
10 | {{{header}}}
11 | import { Editor } from 'bytemd'
12 | import {{importedName}} from '@bytemd/plugin-{{name}}'
13 |
14 | new Editor({
15 | target: document.body,
16 | props: {
17 | plugins: [
18 | {{importedName}}(),
19 | // ... other plugins
20 | ],
21 | },
22 | })
23 | ```
24 |
25 | {{#options}}### Options
26 |
27 | {{{options}}}
28 | {{/options}}
29 | {{#example}}## Example
30 |
31 | {{{example}}}
32 | {{/example}}
33 | ## License
34 |
35 | MIT
36 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "files": [],
3 | "references": [
4 | { "path": "packages/bytemd" },
5 | { "path": "packages/plugin-breaks" },
6 | { "path": "packages/plugin-frontmatter" },
7 | { "path": "packages/plugin-gemoji" },
8 | { "path": "packages/plugin-gfm" },
9 | { "path": "packages/plugin-highlight" },
10 | { "path": "packages/plugin-highlight-ssr" },
11 | { "path": "packages/plugin-math" },
12 | { "path": "packages/plugin-math-ssr" },
13 | { "path": "packages/plugin-medium-zoom" },
14 | { "path": "packages/plugin-mermaid" },
15 | { "path": "packages/react" },
16 | { "path": "packages/vue" },
17 | { "path": "packages/vue-next" }
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-vue-nuxtjs",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "nuxt build",
7 | "dev": "nuxt",
8 | "generate": "nuxt generate",
9 | "start": "nuxt start"
10 | },
11 | "dependencies": {
12 | "@bytemd/plugin-gfm": "latest",
13 | "@bytemd/vue": "latest",
14 | "bytemd": "latest",
15 | "core-js": "^3.19.3",
16 | "nuxt": "^2.15.8",
17 | "vue": "^2.6.14",
18 | "vue-server-renderer": "^2.6.14",
19 | "vue-template-compiler": "^2.6.14",
20 | "webpack": "^4.46.0"
21 | },
22 | "devDependencies": {
23 | "@nuxt/types": "^2.15.8",
24 | "@nuxt/typescript-build": "^2.1.0"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/react-nextjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-react-nextjs",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "next build",
7 | "dev": "next dev",
8 | "lint": "next lint",
9 | "start": "next start"
10 | },
11 | "dependencies": {
12 | "@bytemd/plugin-gfm": "latest",
13 | "@bytemd/react": "latest",
14 | "bytemd": "latest",
15 | "next": "12.1.1",
16 | "react": "17.0.2",
17 | "react-dom": "17.0.2"
18 | },
19 | "devDependencies": {
20 | "@types/node": "17.0.23",
21 | "@types/react": "17.0.43",
22 | "@types/react-dom": "17.0.14",
23 | "eslint": "8.12.0",
24 | "eslint-config-next": "12.1.1",
25 | "typescript": "4.6.3"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/vue/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
14 | properly without JavaScript enabled. Please enable it to
15 | continue.
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/playground/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig-base.json",
3 | "include": ["src", "src/locales/*.json"],
4 | "compilerOptions": { "rootDir": "src", "outDir": "dist" },
5 | "references": [
6 | { "path": "../packages/bytemd" },
7 | { "path": "../packages/plugin-breaks" },
8 | { "path": "../packages/plugin-frontmatter" },
9 | { "path": "../packages/plugin-gemoji" },
10 | { "path": "../packages/plugin-gfm" },
11 | { "path": "../packages/plugin-highlight" },
12 | { "path": "../packages/plugin-highlight-ssr" },
13 | { "path": "../packages/plugin-math" },
14 | { "path": "../packages/plugin-math-ssr" },
15 | { "path": "../packages/plugin-medium-zoom" },
16 | { "path": "../packages/plugin-mermaid" }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/playground/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | ByteMD Playground
8 |
12 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/svelte/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-svelte",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "dev": "svelte-kit dev",
6 | "build": "svelte-kit build",
7 | "package": "svelte-kit package",
8 | "preview": "svelte-kit preview",
9 | "prepare": "svelte-kit sync",
10 | "check": "svelte-check --tsconfig ./tsconfig.json",
11 | "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch"
12 | },
13 | "devDependencies": {
14 | "@bytemd/plugin-gfm": "latest",
15 | "@sveltejs/adapter-auto": "next",
16 | "@sveltejs/kit": "next",
17 | "bytemd": "latest",
18 | "svelte": "^3.44.0",
19 | "svelte-check": "^2.7.1",
20 | "svelte-preprocess": "^4.10.6",
21 | "tslib": "^2.3.1",
22 | "typescript": "^4.7.2"
23 | },
24 | "type": "module"
25 | }
26 |
--------------------------------------------------------------------------------
/examples/nuxt3/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt 3 Minimal Starter
2 |
3 | Look at the [nuxt 3 documentation](https://v3.nuxtjs.org) to learn more.
4 |
5 | ## Setup
6 |
7 | Make sure to install the dependencies:
8 |
9 | ```bash
10 | # yarn
11 | yarn install
12 |
13 | # npm
14 | npm install
15 |
16 | # pnpm
17 | pnpm install --shamefully-hoist
18 | ```
19 |
20 | ## Development Server
21 |
22 | Start the development server on http://localhost:3000
23 |
24 | ```bash
25 | npm run dev
26 | ```
27 |
28 | ## Production
29 |
30 | Build the application for production:
31 |
32 | ```bash
33 | npm run build
34 | ```
35 |
36 | Locally preview production build:
37 |
38 | ```bash
39 | npm run preview
40 | ```
41 |
42 | Checkout the [deployment documentation](https://v3.nuxtjs.org/guide/deploy/presets) for more information.
43 |
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/src/index.ts:
--------------------------------------------------------------------------------
1 | import en from './locales/en.json'
2 | import { MathLocale, getMathActions } from './utils'
3 | import type { BytemdPlugin } from 'bytemd'
4 | import rehypeKatex, { Options } from 'rehype-katex'
5 | import remarkMath from 'remark-math'
6 |
7 | export interface BytemdPluginMathSsrOptions {
8 | locale?: Partial
9 | katexOptions?: Omit
10 | }
11 |
12 | export default function mathSsr({
13 | locale: _locale,
14 | katexOptions,
15 | }: BytemdPluginMathSsrOptions = {}): BytemdPlugin {
16 | const locale = { ...en, ..._locale }
17 | return {
18 | remark: (processor) => processor.use(remarkMath),
19 | rehype: (processor) => processor.use(rehypeKatex, katexOptions),
20 | actions: getMathActions(locale),
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
27 |
28 |
38 |
--------------------------------------------------------------------------------
/examples/vue/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "strict": true,
6 | "jsx": "preserve",
7 | "importHelpers": true,
8 | "moduleResolution": "node",
9 | "skipLibCheck": true,
10 | "esModuleInterop": true,
11 | "allowSyntheticDefaultImports": true,
12 | "forceConsistentCasingInFileNames": true,
13 | "useDefineForClassFields": true,
14 | "sourceMap": true,
15 | "baseUrl": ".",
16 | "types": ["webpack-env"],
17 | "paths": {
18 | "@/*": ["src/*"]
19 | },
20 | "lib": ["esnext", "dom", "dom.iterable", "scripthost"]
21 | },
22 | "include": [
23 | "src/**/*.ts",
24 | "src/**/*.tsx",
25 | "src/**/*.vue",
26 | "tests/**/*.ts",
27 | "tests/**/*.tsx"
28 | ],
29 | "exclude": ["node_modules"]
30 | }
31 |
--------------------------------------------------------------------------------
/packages/plugin-medium-zoom/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { BytemdPlugin } from 'bytemd'
2 | import type * as M from 'medium-zoom'
3 |
4 | export interface BytemdPluginMediumZoomOptions extends M.ZoomOptions {
5 | filter?: (img: HTMLDivElement) => boolean
6 | }
7 |
8 | export default function mediumZoom(
9 | options?: BytemdPluginMediumZoomOptions
10 | ): BytemdPlugin {
11 | let m: typeof M
12 |
13 | return {
14 | viewerEffect({ markdownBody }) {
15 | const imgs = [...markdownBody.querySelectorAll('img')].filter((e) => {
16 | return (options?.filter?.(e) ?? true) && !e.closest('a')
17 | })
18 | if (imgs.length === 0) return
19 | ;(async () => {
20 | if (!m) {
21 | m = await import('medium-zoom')
22 | }
23 | m.default(imgs, options)
24 | })()
25 | },
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/react/src/App.tsx:
--------------------------------------------------------------------------------
1 | import './App.css'
2 | import pluginGfm from '@bytemd/plugin-gfm'
3 | import { Editor } from '@bytemd/react'
4 | import 'bytemd/dist/index.css'
5 | import React, { useMemo, useState } from 'react'
6 |
7 | function App() {
8 | const [value, setValue] = useState('')
9 | const plugins = useMemo(() => [pluginGfm()], [])
10 |
11 | return (
12 |
13 | {
17 | // upload images here
18 | return [
19 | {
20 | url: 'https://picsum.photos/200/300',
21 | },
22 | ]
23 | }}
24 | onChange={(v) => {
25 | setValue(v)
26 | }}
27 | />
28 |
29 | )
30 | }
31 |
32 | export default App
33 |
--------------------------------------------------------------------------------
/packages/bytemd/test/setup.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | // https://github.com/jsdom/jsdom/issues/3002#issuecomment-655752934
4 | document.createRange = () => {
5 | const range = new Range()
6 |
7 | range.getBoundingClientRect = vi.fn()
8 |
9 | range.getClientRects = () => {
10 | return {
11 | item: () => null,
12 | length: 0,
13 | [Symbol.iterator]: vi.fn(),
14 | }
15 | }
16 |
17 | return range
18 | }
19 |
20 | // https://github.com/facebook/jest/issues/9983#issuecomment-626489847
21 | if (typeof TextEncoder === 'undefined') {
22 | global.TextEncoder = require('util').TextEncoder
23 | }
24 |
25 | // https://stackoverflow.com/a/65095454
26 | ;(global as any).ResizeObserver = class ResizeObserver {
27 | observe() {
28 | // do nothing
29 | }
30 | unobserve() {
31 | // do nothing
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/plugin-highlight/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { BytemdPlugin } from 'bytemd'
2 | import type H from 'highlight.js'
3 |
4 | export interface BytemdPluginHighlightOptions {
5 | init?(hljs: typeof H): void | Promise
6 | }
7 |
8 | export default function highlight({
9 | init,
10 | }: BytemdPluginHighlightOptions = {}): BytemdPlugin {
11 | let hljs: typeof H
12 | return {
13 | viewerEffect({ markdownBody }) {
14 | ;(async () => {
15 | const els = markdownBody.querySelectorAll('pre>code')
16 | if (els.length === 0) return
17 |
18 | if (!hljs) {
19 | hljs = await import('highlight.js').then((m) => m.default)
20 | if (init) await init(hljs)
21 | }
22 |
23 | els.forEach((el) => {
24 | hljs.highlightElement(el)
25 | })
26 | })()
27 | },
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/scripts/utils.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import fs from 'fs-extra'
3 | import path from 'path'
4 | import sveltePreprocess from 'svelte-preprocess'
5 | import { fileURLToPath } from 'url'
6 |
7 | // https://stackoverflow.com/a/50052194
8 | const __dirname = path.dirname(fileURLToPath(import.meta.url))
9 |
10 | export const rootDir = path.resolve(__dirname, '..')
11 |
12 | export const packagesDir = path.join(rootDir, 'packages')
13 | export const packages = fs.readdirSync(packagesDir)
14 |
15 | export const sveltePreprocessor = sveltePreprocess({
16 | typescript: true,
17 | // https://github.com/sveltejs/svelte/issues/189#issuecomment-586142198
18 | replace: [
19 | [/(>)[\s]*([<{])/g, '$1$2'],
20 | [/({[/:][a-z]+})[\s]*([<{])/g, '$1$2'],
21 | [/({[#:][a-z]+ .+?})[\s]*([<{])/g, '$1$2'],
22 | [/([>}])[\s]+(<|{[/#:][a-z][^}]*})/g, '$1$2'],
23 | ],
24 | })
25 |
--------------------------------------------------------------------------------
/packages/plugin-math/src/utils/icons.ts:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT, generated by scripts/icon.ts
2 | export const icons = {
3 | Formula:
4 | ' ',
5 | Inline:
6 | ' ',
7 | Block:
8 | ' ',
9 | }
10 |
--------------------------------------------------------------------------------
/playground/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "playground",
3 | "private": true,
4 | "dependencies": {
5 | "@bytemd/plugin-breaks": "workspace:*",
6 | "@bytemd/plugin-frontmatter": "workspace:*",
7 | "@bytemd/plugin-gemoji": "workspace:*",
8 | "@bytemd/plugin-gfm": "workspace:*",
9 | "@bytemd/plugin-highlight": "workspace:*",
10 | "@bytemd/plugin-highlight-ssr": "workspace:*",
11 | "@bytemd/plugin-math": "workspace:*",
12 | "@bytemd/plugin-math-ssr": "workspace:*",
13 | "@bytemd/plugin-medium-zoom": "workspace:*",
14 | "@bytemd/plugin-mermaid": "workspace:*",
15 | "@sveltejs/vite-plugin-svelte": "2.0.4",
16 | "bytemd": "workspace:*",
17 | "github-markdown-css": "^5.2.0",
18 | "highlight.js": "^11.7.0",
19 | "katex": "^0.16.4",
20 | "svelte-preprocess": "^5.0.3",
21 | "vite": "^4.2.1"
22 | },
23 | "scripts": {
24 | "dev": "vite",
25 | "build": "vite build",
26 | "preview": "vite preview"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/packages/plugin-frontmatter/src/index.ts:
--------------------------------------------------------------------------------
1 | import type { BytemdPlugin } from 'bytemd'
2 | import { load } from 'js-yaml'
3 | import remarkFrontmatter from 'remark-frontmatter'
4 |
5 | export interface BytemdPluginFrontmatterOptions {
6 | onError?(err: any): void
7 | }
8 |
9 | declare module 'vfile' {
10 | interface VFile {
11 | frontmatter: ReturnType
12 | }
13 | }
14 |
15 | export default function frontmatter({
16 | onError,
17 | }: BytemdPluginFrontmatterOptions = {}): BytemdPlugin {
18 | return {
19 | remark: (processor) =>
20 | // @ts-ignore
21 | processor.use(remarkFrontmatter).use(() => (tree, file) => {
22 | // TODO: arg types
23 | // console.log(tree);
24 | const fisrtNode = tree.children[0]
25 | if (fisrtNode?.type !== 'yaml') return
26 |
27 | try {
28 | file.frontmatter = load(fisrtNode.value)
29 | } catch (err) {
30 | onError?.(err)
31 | }
32 | }),
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/plugin-breaks/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-breaks",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to support breaks",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-breaks"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "remark-breaks": "^3.0.2"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/react",
3 | "version": "1.22.0",
4 | "description": "Hackable Markdown Editor and Viewer",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/react"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "bytemd": "workspace:*"
32 | },
33 | "devDependencies": {
34 | "@types/react": "^18.0.31",
35 | "react": "^18.2.0"
36 | },
37 | "peerDependencies": {
38 | "react": "*"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-mermaid",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to support Mermaid diagram",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-mermaid"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "mermaid": "^10.0.2"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/plugin-gemoji/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-gemoji",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to support Gemoji shortcodes",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-gemoji"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "remark-gemoji": "^7.0.1"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/plugin-highlight/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-highlight",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to highlight code blocks",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-highlight"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "highlight.js": "^11.7.0"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/vue-next/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/vue-next",
3 | "version": "1.22.0",
4 | "description": "Hackable Markdown Editor and Viewer",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/vue-next"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "bytemd": "workspace:*"
32 | },
33 | "devDependencies": {
34 | "@vitejs/plugin-vue": "^4.1.0",
35 | "vue": "^3.2.47"
36 | },
37 | "peerDependencies": {
38 | "vue": "^3.0.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/svelte/README.md:
--------------------------------------------------------------------------------
1 | # create-svelte
2 |
3 | Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte).
4 |
5 | ## Creating a project
6 |
7 | If you're seeing this, you've probably already done this step. Congrats!
8 |
9 | ```bash
10 | # create a new project in the current directory
11 | npm init svelte
12 |
13 | # create a new project in my-app
14 | npm init svelte my-app
15 | ```
16 |
17 | ## Developing
18 |
19 | Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
20 |
21 | ```bash
22 | npm run dev
23 |
24 | # or start the server and open the app in a new browser tab
25 | npm run dev -- --open
26 | ```
27 |
28 | ## Building
29 |
30 | To create a production version of your app:
31 |
32 | ```bash
33 | npm run build
34 | ```
35 |
36 | You can preview the production build with `npm run preview`.
37 |
38 | > To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment.
39 |
--------------------------------------------------------------------------------
/packages/plugin-medium-zoom/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-medium-zoom",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to zoom images like Medium",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-medium-zoom"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "medium-zoom": "^1.0.8"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/react/src/editor.tsx:
--------------------------------------------------------------------------------
1 | import * as bytemd from 'bytemd'
2 | import React, { useEffect, useRef } from 'react'
3 |
4 | export interface EditorProps extends bytemd.EditorProps {
5 | onChange?(value: string): void
6 | }
7 |
8 | export const Editor: React.FC = ({ onChange, ...props }) => {
9 | const ed = useRef()
10 | const el = useRef(null)
11 | const onChangeRef = useRef()
12 |
13 | useEffect(() => {
14 | if (!el.current) return
15 |
16 | const editor = new bytemd.Editor({
17 | target: el.current,
18 | props,
19 | })
20 | editor.$on('change', (e: CustomEvent<{ value: string }>) => {
21 | onChangeRef.current?.(e.detail.value)
22 | })
23 | ed.current = editor
24 |
25 | return () => {
26 | editor.$destroy()
27 | }
28 | }, [])
29 |
30 | useEffect(() => {
31 | onChangeRef.current = onChange
32 | }, [onChange])
33 |
34 | useEffect(() => {
35 | // TODO: performance
36 | ed.current?.$set(props)
37 | }, [props])
38 |
39 | return
40 | }
41 |
--------------------------------------------------------------------------------
/examples/react-nextjs/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
3 |
4 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-gfm",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to support GFM (autolink literals, strikethrough, tables, tasklists)",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-gfm"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "remark-gfm": "^3.0.1"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/plugin-highlight-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-highlight-ssr",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to highlight code blocks (SSR compatible)",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-highlight-ssr"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "rehype-highlight": "^6.0.0"
32 | },
33 | "devDependencies": {
34 | "bytemd": "workspace:*"
35 | },
36 | "peerDependencies": {
37 | "bytemd": "^1.5.0"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/vue",
3 | "version": "1.22.0",
4 | "description": "Hackable Markdown Editor and Viewer",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/vue"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "bytemd": "workspace:*"
32 | },
33 | "devDependencies": {
34 | "vite-plugin-vue2": "^2.0.3",
35 | "vue": "^2.7.14",
36 | "vue-template-compiler": "^2.7.14"
37 | },
38 | "peerDependencies": {
39 | "vue": "^2.0.0"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/vanilla-js/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ByteMD example
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/plugin-math-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-math-ssr",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to support math formula (SSR compatible)",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-math-ssr"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "rehype-katex": "^6.0.2",
32 | "remark-math": "^5.1.1"
33 | },
34 | "devDependencies": {
35 | "bytemd": "workspace:*"
36 | },
37 | "peerDependencies": {
38 | "bytemd": "^1.5.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/plugin-math/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-math",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to support math formula",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-math"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "@types/katex": "^0.16.0",
32 | "katex": "^0.16.4",
33 | "remark-math": "^5.1.1"
34 | },
35 | "devDependencies": {
36 | "bytemd": "workspace:*"
37 | },
38 | "peerDependencies": {
39 | "bytemd": "^1.5.0"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/packages/vue/src/editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
49 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Rongjian Zhang
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 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/zh_Hant.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "粗體",
3 | "boldText": "粗體字",
4 | "cheatsheet": "Markdown 語法",
5 | "closeHelp": "關閉幫助",
6 | "closeToc": "關閉目錄",
7 | "code": "代碼",
8 | "codeBlock": "代碼塊",
9 | "codeLang": "編程語言",
10 | "codeText": "代碼",
11 | "exitFullscreen": "退出全屏",
12 | "exitPreviewOnly": "恢復默認",
13 | "exitWriteOnly": "恢復默認",
14 | "fullscreen": "全屏",
15 | "h1": "一級標題",
16 | "h2": "二級標題",
17 | "h3": "三級標題",
18 | "h4": "四級標題",
19 | "h5": "五級標題",
20 | "h6": "六級標題",
21 | "headingText": "標題",
22 | "help": "幫助",
23 | "hr": "分割線",
24 | "image": "圖像",
25 | "imageAlt": "alt",
26 | "imageTitle": "圖像描述",
27 | "italic": "斜體",
28 | "italicText": "斜體字",
29 | "limited": "已達最大字符數限制",
30 | "lines": "行數",
31 | "link": "連結",
32 | "linkText": "連結描述",
33 | "ol": "定義列表",
34 | "olItem": "項目",
35 | "preview": "預覽",
36 | "previewOnly": "僅預覽區",
37 | "quote": "引用",
38 | "quotedText": "引用文本",
39 | "shortcuts": "快捷鍵",
40 | "source": "源碼",
41 | "sync": "同步滾動",
42 | "toc": "目錄",
43 | "top": "回到頂部",
44 | "ul": "無序列表",
45 | "ulItem": "項目",
46 | "words": "字數",
47 | "write": "編輯",
48 | "writeOnly": "僅編輯區"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/zh_Hans.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "粗体",
3 | "boldText": "粗体文本",
4 | "cheatsheet": "Markdown 语法",
5 | "closeHelp": "关闭帮助",
6 | "closeToc": "关闭目录",
7 | "code": "代码",
8 | "codeBlock": "代码块",
9 | "codeLang": "编程语言",
10 | "codeText": "代码",
11 | "exitFullscreen": "退出全屏",
12 | "exitPreviewOnly": "恢复默认",
13 | "exitWriteOnly": "恢复默认",
14 | "fullscreen": "全屏",
15 | "h1": "一级标题",
16 | "h2": "二级标题",
17 | "h3": "三级标题",
18 | "h4": "四级标题",
19 | "h5": "五级标题",
20 | "h6": "六级标题",
21 | "headingText": "标题",
22 | "help": "帮助",
23 | "hr": "分割线",
24 | "image": "图片",
25 | "imageAlt": "alt",
26 | "imageTitle": "图片描述",
27 | "italic": "斜体",
28 | "italicText": "斜体文本",
29 | "limited": "已达最大字符数限制",
30 | "lines": "行数",
31 | "link": "链接",
32 | "linkText": "链接描述",
33 | "ol": "有序列表",
34 | "olItem": "项目",
35 | "preview": "预览",
36 | "previewOnly": "仅预览区",
37 | "quote": "引用",
38 | "quotedText": "引用文本",
39 | "shortcuts": "快捷键",
40 | "source": "源代码",
41 | "sync": "同步滚动",
42 | "toc": "目录",
43 | "top": "回到顶部",
44 | "ul": "无序列表",
45 | "ulItem": "项目",
46 | "words": "字数",
47 | "write": "编辑",
48 | "writeOnly": "仅编辑区"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/plugin-frontmatter/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/plugin-frontmatter",
3 | "version": "1.22.0",
4 | "description": "ByteMD plugin to parse frontmatter",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/bytedance/bytemd.git",
8 | "directory": "packages/plugin-frontmatter"
9 | },
10 | "license": "MIT",
11 | "author": "Rongjian Zhang",
12 | "exports": {
13 | ".": {
14 | "types": "./dist/index.d.ts",
15 | "import": "./dist/index.mjs",
16 | "require": "./dist/index.js"
17 | },
18 | "./locales/*": "./locales/*",
19 | "./lib/locales/*": "./locales/*"
20 | },
21 | "main": "./dist/index.js",
22 | "jsdelivr": "./dist/index.umd.js",
23 | "unpkg": "./dist/index.umd.js",
24 | "module": "./dist/index.mjs",
25 | "types": "./dist/index.d.ts",
26 | "files": [
27 | "dist",
28 | "locales"
29 | ],
30 | "dependencies": {
31 | "@types/js-yaml": "^4.0.5",
32 | "js-yaml": "^4.1.0",
33 | "remark-frontmatter": "^4.0.1",
34 | "vfile": "^5.3.7"
35 | },
36 | "devDependencies": {
37 | "bytemd": "workspace:*"
38 | },
39 | "peerDependencies": {
40 | "bytemd": "^1.5.0"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/examples/react-nextjs/pages/index.tsx:
--------------------------------------------------------------------------------
1 | import styles from '../styles/Home.module.css'
2 | import pluginGfm from '@bytemd/plugin-gfm'
3 | import { Editor } from '@bytemd/react'
4 | import type { NextPage } from 'next'
5 | import Head from 'next/head'
6 | import { useMemo, useState } from 'react'
7 |
8 | const Home: NextPage = () => {
9 | const [value, setValue] = useState('')
10 | const plugins = useMemo(() => [pluginGfm()], [])
11 |
12 | return (
13 |
14 |
15 |
Create Next App
16 |
17 |
18 |
19 | {/* */}
20 |
21 | {
25 | // upload images here
26 | return [
27 | {
28 | url: 'https://picsum.photos/200/300',
29 | },
30 | ]
31 | }}
32 | onChange={(v) => {
33 | setValue(v)
34 | }}
35 | />
36 |
37 | )
38 | }
39 |
40 | export default Home
41 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | // Global page headers: https://go.nuxtjs.dev/config-head
3 | head: {
4 | title: 'vue-nuxtjs',
5 | htmlAttrs: {
6 | lang: 'en',
7 | },
8 | meta: [
9 | { charset: 'utf-8' },
10 | { name: 'viewport', content: 'width=device-width, initial-scale=1' },
11 | { hid: 'description', name: 'description', content: '' },
12 | { name: 'format-detection', content: 'telephone=no' },
13 | ],
14 | link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
15 | },
16 |
17 | // Global CSS: https://go.nuxtjs.dev/config-css
18 | css: [],
19 |
20 | // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
21 | plugins: [],
22 |
23 | // Auto import components: https://go.nuxtjs.dev/config-components
24 | components: true,
25 |
26 | // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
27 | buildModules: [
28 | // https://go.nuxtjs.dev/typescript
29 | '@nuxt/typescript-build',
30 | ],
31 |
32 | // Modules: https://go.nuxtjs.dev/config-modules
33 | modules: [],
34 |
35 | // Build Configuration: https://go.nuxtjs.dev/config-build
36 | build: {},
37 | }
38 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/ja.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "太字",
3 | "boldText": "ボールドテキスト",
4 | "cheatsheet": "マークダウン カンニングペーパー",
5 | "closeHelp": "ヘルプビューアを閉じます",
6 | "closeToc": "目次を閉じます",
7 | "code": "コード",
8 | "codeBlock": "コードブロック",
9 | "codeLang": "lang",
10 | "codeText": "コード",
11 | "exitFullscreen": "全画面を閉じます",
12 | "exitPreviewOnly": "プレビューのみを終了",
13 | "exitWriteOnly": "Exit 書き込み専用",
14 | "fullscreen": "全画面",
15 | "h1": "見出し1",
16 | "h2": "見出し2",
17 | "h3": "見出し3",
18 | "h4": "見出し4",
19 | "h5": "見出し5",
20 | "h6": "見出し6",
21 | "headingText": "見出し",
22 | "help": "ヘルプビューア",
23 | "hr": "区切り線",
24 | "image": "イメージ",
25 | "imageAlt": "alt",
26 | "imageTitle": "タイトル",
27 | "italic": "イタリック",
28 | "italicText": "斜体のテキスト",
29 | "lines": "線",
30 | "link": "リンク",
31 | "linkText": "リンクテキスト",
32 | "ol": "番号付きリスト",
33 | "olItem": "アイテム",
34 | "preview": "プレビュー",
35 | "previewOnly": "試写専用",
36 | "quote": "見積もり",
37 | "quotedText": "引用テキスト",
38 | "shortcuts": "ショートカット",
39 | "source": "原始コード",
40 | "sync": "スクロール同期",
41 | "toc": "目次",
42 | "top": "トップにスクロールします",
43 | "ul": "順序なしリスト",
44 | "ulItem": "アイテム",
45 | "words": "言葉",
46 | "write": "書く",
47 | "writeOnly": "書き込み専用"
48 | }
49 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/ko.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "굵게",
3 | "boldText": "굵은 글자",
4 | "cheatsheet": "참고용 마크다운",
5 | "closeHelp": "도움말 닫기",
6 | "closeToc": "목차 닫기",
7 | "code": "코드",
8 | "codeBlock": "코드 블록",
9 | "codeLang": "언어",
10 | "codeText": "코드",
11 | "exitFullscreen": "꽉 찬 화면 종료",
12 | "exitPreviewOnly": "미리보기 전용 종료",
13 | "exitWriteOnly": "쓰기 전용 종료",
14 | "fullscreen": "꽉 찬 화면",
15 | "h1": "제목 1",
16 | "h2": "제목 2",
17 | "h3": "제목 3",
18 | "h4": "제목 4",
19 | "h5": "제목 5",
20 | "h6": "제목 6",
21 | "headingText": "제목",
22 | "help": "도움말",
23 | "hr": "구분선",
24 | "image": "이미지",
25 | "imageAlt": "대체 텍스트",
26 | "imageTitle": "타이틀",
27 | "italic": "이탤릭",
28 | "italicText": "이탤릭 글자",
29 | "limited": "최대 글자수 한도에 도달했습니다",
30 | "lines": "줄",
31 | "link": "링크",
32 | "linkText": "링크 글자",
33 | "ol": "순서 있는 목록",
34 | "olItem": "아이템",
35 | "preview": "미리보기",
36 | "previewOnly": "미리보기 전용",
37 | "quote": "인용",
38 | "quotedText": "인용된 텍스트",
39 | "shortcuts": "바로가기",
40 | "source": "소스 코드",
41 | "sync": "스크롤 동기화",
42 | "toc": "목차",
43 | "top": "맨 위로 스크롤",
44 | "ul": "순서 없는 목록",
45 | "ulItem": "아이템",
46 | "words": "글자",
47 | "write": "작성",
48 | "writeOnly": "쓰기 전용"
49 | }
50 |
--------------------------------------------------------------------------------
/examples/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/example-react",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "react-scripts build",
7 | "eject": "react-scripts eject",
8 | "start": "react-scripts start",
9 | "test": "react-scripts test"
10 | },
11 | "browserslist": {
12 | "production": [
13 | ">0.2%",
14 | "not dead",
15 | "not op_mini all"
16 | ],
17 | "development": [
18 | "last 1 chrome version",
19 | "last 1 firefox version",
20 | "last 1 safari version"
21 | ]
22 | },
23 | "eslintConfig": {
24 | "extends": [
25 | "react-app",
26 | "react-app/jest"
27 | ]
28 | },
29 | "dependencies": {
30 | "@bytemd/plugin-gfm": "latest",
31 | "@bytemd/react": "latest",
32 | "@testing-library/jest-dom": "^5.16.3",
33 | "@testing-library/react": "^12.1.4",
34 | "@testing-library/user-event": "^13.5.0",
35 | "@types/jest": "^27.4.1",
36 | "@types/node": "^16.11.26",
37 | "@types/react": "^17.0.43",
38 | "@types/react-dom": "^17.0.14",
39 | "bytemd": "latest",
40 | "react": "^17.0.2",
41 | "react-dom": "^17.0.2",
42 | "react-scripts": "5.0.0",
43 | "typescript": "^4.6.3",
44 | "web-vitals": "^2.1.4"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/packages/bytemd/test/viewer.test.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { Viewer } from '../src'
3 | import '@testing-library/jest-dom'
4 | import { render, act } from '@testing-library/svelte'
5 |
6 | function stripComment(str: string) {
7 | return str.replace(/<\!--.*?-->/g, '')
8 | }
9 |
10 | test('value', async () => {
11 | const $ = render(Viewer, { value: '# title' })
12 | expect(
13 | stripComment($.container.querySelector('.markdown-body')?.innerHTML)
14 | ).toEqual('title ')
15 | $.component.$destroy()
16 | })
17 |
18 | test('plugin', async () => {
19 | const $ = render(Viewer)
20 | const off = vi.fn()
21 | const viewerEffect = vi.fn(() => off)
22 |
23 | $.component.$set({ plugins: [{ viewerEffect }] })
24 | await act()
25 | expect(viewerEffect).toBeCalled()
26 | expect(viewerEffect).toBeCalledTimes(1)
27 |
28 | // FIXME:
29 | // expect(viewerEffect).toBeCalledWith(
30 | // expect.objectContaining({
31 | // markdownBody: $.container.querySelector('.markdown-body'),
32 | // file: expect.objectContaining({
33 | // contents: '',
34 | // data: {},
35 | // }),
36 | // })
37 | // )
38 |
39 | $.component.$set({ plugins: [{ viewerEffect }] })
40 | await act()
41 | expect(off).toBeCalled()
42 | expect(off).toBeCalledTimes(1)
43 | })
44 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/src/icons.ts:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT, generated by scripts/icon.ts
2 | export const icons = {
3 | Strikethrough:
4 | ' ',
5 | CheckCorrect:
6 | ' ',
7 | InsertTable:
8 | ' ',
9 | }
10 |
--------------------------------------------------------------------------------
/examples/legacy-browser/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | IE9 Example
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/packages/vue-next/src/editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
56 |
--------------------------------------------------------------------------------
/packages/bytemd/src/status.svelte:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 | {locale.words}: {words}
23 |
24 |
25 | {locale.lines}: {lines}
26 |
27 | {#if islimited}
28 | {locale.limited}
29 | {/if}
30 |
31 |
32 |
33 | {#if showSync}
34 |
35 | dispatch('sync', !syncEnabled)}
39 | />
40 | {locale.sync}
41 |
42 | {/if}
43 | dispatch('top')}
45 | on:keydown|self={(e) =>
46 | ['Enter', 'Space'].includes(e.code) && dispatch('top')}
47 | >{locale.top}
49 |
50 |
51 |
--------------------------------------------------------------------------------
/packages/plugin-math/src/index.ts:
--------------------------------------------------------------------------------
1 | import en from './locales/en.json'
2 | import { MathLocale, getMathActions } from './utils'
3 | import type { BytemdPlugin } from 'bytemd'
4 | import type { default as K, KatexOptions } from 'katex'
5 | import remarkMath from 'remark-math'
6 |
7 | export interface BytemdPluginMathOptions {
8 | locale?: Partial
9 | katexOptions?: Omit
10 | }
11 |
12 | export default function math({
13 | locale: _locale,
14 | katexOptions,
15 | }: BytemdPluginMathOptions = {}): BytemdPlugin {
16 | const locale = { ...en, ..._locale }
17 | let katex: typeof K
18 |
19 | return {
20 | remark: (processor) => processor.use(remarkMath),
21 | viewerEffect({ markdownBody }) {
22 | const renderMath = async (selector: string, displayMode: boolean) => {
23 | const els = markdownBody.querySelectorAll(selector)
24 | if (els.length === 0) return
25 |
26 | if (!katex) {
27 | katex = await import('katex').then((m) => m.default)
28 | }
29 |
30 | els.forEach((el) => {
31 | katex.render(el.innerText, el, {
32 | ...katexOptions,
33 | throwOnError: false,
34 | displayMode,
35 | })
36 | })
37 | }
38 |
39 | renderMath('.math.math-inline', false)
40 | renderMath('.math.math-display', true)
41 | },
42 | actions: getMathActions(locale),
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/ar.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "سميك",
3 | "boldText": "نص سميك",
4 | "cheatsheet": "مرجع للغة التوصيف",
5 | "closeHelp": "أغلق المساعدة",
6 | "closeToc": "أغلق قائمة المحتوى",
7 | "code": "نص برمجي",
8 | "codeBlock": "مربع برمجة",
9 | "codeLang": "اللغة",
10 | "codeText": "نص برمجي",
11 | "exitFullscreen": "الخروج من ملء الشاشة",
12 | "exitPreviewOnly": "الخروج من وضع معاينة فقط",
13 | "exitWriteOnly": "الخروج من وضع التعديل فقط",
14 | "fullscreen": "ملء الشاشة",
15 | "h1": "عنوان 1",
16 | "h2": "عنوان 2",
17 | "h3": "عنوان 3",
18 | "h4": "عنوان 4",
19 | "h5": "عنوان 5",
20 | "h6": "عنوان 6",
21 | "headingText": "عنوان",
22 | "help": "مساعدة",
23 | "hr": "فاصل عرضي",
24 | "image": "صورة",
25 | "imageAlt": "وصف الصورة",
26 | "imageTitle": "العنوان",
27 | "italic": "مائل",
28 | "italicText": "نص مائل",
29 | "limited": "تم الوصول لحد الكتابة الأقصى",
30 | "lines": "الأسطر",
31 | "link": "رابط",
32 | "linkText": "نص الرابط",
33 | "ol": "قائمة مرتبة",
34 | "olItem": "عنصر",
35 | "preview": "معاينة",
36 | "previewOnly": "معاينة فقط",
37 | "quote": "اقتباس",
38 | "quotedText": "النص المقتبس",
39 | "shortcuts": "اختصارات",
40 | "source": "المصدر البرمجي",
41 | "sync": "ربط الحركة",
42 | "toc": "الفهرس",
43 | "top": "الذهاب الى البداية",
44 | "ul": "قائمة منقطة",
45 | "ulItem": "عنصر",
46 | "words": "كلمات",
47 | "write": "أكتب",
48 | "writeOnly": "الكتابة فقط"
49 | }
50 |
--------------------------------------------------------------------------------
/scripts/icon.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import * as icons from '@icon-park/svg'
3 | import { execSync } from 'child_process'
4 | import fs from 'fs-extra'
5 | import svgo from 'svgo'
6 |
7 | /** @type {Record} */
8 | const meta = {
9 | 'bytemd/src': [
10 | 'Close',
11 |
12 | 'H',
13 | 'H1',
14 | 'H2',
15 | 'H3',
16 | 'LevelFourTitle',
17 | 'LevelFiveTitle',
18 | 'LevelSixTitle',
19 | 'TextBold',
20 | 'TextItalic',
21 | 'Quote',
22 | 'LinkOne',
23 | 'Pic',
24 | 'Code',
25 | 'CodeBrackets',
26 | 'ListTwo',
27 | 'OrderedList',
28 | 'DividingLine',
29 |
30 | 'AlignTextLeftOne',
31 | 'Helpcenter',
32 | 'LeftExpand',
33 | 'RightExpand',
34 | 'OffScreen',
35 | 'FullScreen',
36 | 'GithubOne',
37 | ],
38 | 'plugin-gfm/src': ['Strikethrough', 'CheckCorrect', 'InsertTable'],
39 | 'plugin-math/src/utils': ['Formula', 'Inline', 'Block'],
40 | 'plugin-mermaid/src': ['ChartGraph'],
41 | }
42 |
43 | for (let [p, keys] of Object.entries(meta)) {
44 | let obj = {}
45 | for (let key of keys) {
46 | const svg = svgo.optimize(icons[key]({}))
47 | obj[key] = svg.data
48 | }
49 |
50 | fs.writeFileSync(
51 | `./packages/${p}/icons.ts`,
52 | `// DO NOT EDIT, generated by scripts/icon.ts
53 | export const icons=${JSON.stringify(obj)}`
54 | )
55 | }
56 |
57 | execSync('npx prettier --write packages/**/*.ts')
58 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Bold",
3 | "boldText": "bold text",
4 | "cheatsheet": "Markdown Cheatsheet",
5 | "closeHelp": "Close help",
6 | "closeToc": "Close table of contents",
7 | "code": "Code",
8 | "codeBlock": "Code block",
9 | "codeLang": "lang",
10 | "codeText": "code",
11 | "exitFullscreen": "Exit fullscreen",
12 | "exitPreviewOnly": "Exit preview only",
13 | "exitWriteOnly": "Exit write only",
14 | "fullscreen": "Fullscreen",
15 | "h1": "Heading 1",
16 | "h2": "Heading 2",
17 | "h3": "Heading 3",
18 | "h4": "Heading 4",
19 | "h5": "Heading 5",
20 | "h6": "Heading 6",
21 | "headingText": "heading",
22 | "help": "Help",
23 | "hr": "Horizontal rule",
24 | "image": "Image",
25 | "imageAlt": "alt",
26 | "imageTitle": "title",
27 | "italic": "Italic",
28 | "italicText": "italic text",
29 | "limited": "The maximum character limit has been reached",
30 | "lines": "Lines",
31 | "link": "Link",
32 | "linkText": "link text",
33 | "ol": "Ordered list",
34 | "olItem": "item",
35 | "preview": "Preview",
36 | "previewOnly": "Preview only",
37 | "quote": "Quote",
38 | "quotedText": "quoted text",
39 | "shortcuts": "Shortcuts",
40 | "source": "Source code",
41 | "sync": "Scroll sync",
42 | "toc": "Table of contents",
43 | "top": "Scroll to top",
44 | "ul": "Unordered list",
45 | "ulItem": "item",
46 | "words": "Words",
47 | "write": "Write",
48 | "writeOnly": "Write only"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/plugin-math/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | import { icons } from './icons'
2 | import type { BytemdAction } from 'bytemd'
3 |
4 | export type MathLocale = {
5 | inline: string
6 | inlineText: string
7 | block: string
8 | blockText: string
9 | }
10 |
11 | export function getMathActions(locale: MathLocale): BytemdAction[] {
12 | return [
13 | {
14 | icon: icons.Formula,
15 | handler: {
16 | type: 'dropdown',
17 | actions: [
18 | {
19 | title: locale.inline,
20 | icon: icons.Inline,
21 | cheatsheet: `$${locale.inlineText}$`,
22 | handler: {
23 | type: 'action',
24 | click({ wrapText, editor }) {
25 | wrapText('$')
26 | editor.focus()
27 | },
28 | },
29 | },
30 | {
31 | title: locale.block,
32 | icon: icons.Block,
33 | cheatsheet: `$$↵${locale.blockText}↵$$`,
34 | handler: {
35 | type: 'action',
36 | click({ appendBlock, editor, codemirror }) {
37 | const { line } = appendBlock('$$\n\\TeX\n$$')
38 | editor.setSelection(
39 | codemirror.Pos(line + 1, 0),
40 | codemirror.Pos(line + 1, 4)
41 | )
42 | editor.focus()
43 | },
44 | },
45 | },
46 | ],
47 | },
48 | },
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/id.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Tebal",
3 | "boldText": "teks tebal",
4 | "cheatsheet": "Contekan Markdown",
5 | "closeHelp": "Tutup bantuan",
6 | "closeToc": "Tutup daftar isi",
7 | "code": "Kode",
8 | "codeBlock": "Blok kode",
9 | "codeLang": "bahasa",
10 | "codeText": "kode",
11 | "exitFullscreen": "Keluar layar penuh",
12 | "exitPreviewOnly": "Keluar hanya-pratinjau",
13 | "exitWriteOnly": "Keluar hanya menulis",
14 | "fullscreen": "Layar penuh",
15 | "h1": "Tajuk 1",
16 | "h2": "Tajuk 2",
17 | "h3": "Tajuk 3",
18 | "h4": "Tajuk 4",
19 | "h5": "Tajuk 5",
20 | "h6": "Tajuk 6",
21 | "headingText": "tajuk",
22 | "help": "Bantuan",
23 | "hr": "Kaidah horizontal",
24 | "image": "Gambar",
25 | "imageAlt": "alternatif",
26 | "imageTitle": "judul",
27 | "italic": "Miring",
28 | "italicText": "teks miring",
29 | "limited": "Batas maksimum karakter telah tercapai",
30 | "lines": "Baris",
31 | "link": "Tautan",
32 | "linkText": "teks tautan",
33 | "ol": "Daftar terurut",
34 | "olItem": "item",
35 | "preview": "Pratinjau",
36 | "previewOnly": "Hanya-pratinjau",
37 | "quote": "Kutip",
38 | "quotedText": "teks kutipan",
39 | "shortcuts": "Pintasan",
40 | "source": "Kode sumber",
41 | "sync": "Sinkronisasi pengguliran",
42 | "toc": "Daftar isi",
43 | "top": "Ke permulaan",
44 | "ul": "Daftar tak berurutan",
45 | "ulItem": "item",
46 | "words": "Kata",
47 | "write": "Tulis",
48 | "writeOnly": "Hanya menulis"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/src/utils.ts:
--------------------------------------------------------------------------------
1 | import type { ViewerProps } from './types'
2 | import { defaultSchema } from 'hast-util-sanitize'
3 | import type { Schema } from 'hast-util-sanitize'
4 | import rehypeRaw from 'rehype-raw'
5 | import rehypeSanitize from 'rehype-sanitize'
6 | import rehypeStringify from 'rehype-stringify'
7 | import remarkParse from 'remark-parse'
8 | import remarkRehype from 'remark-rehype'
9 | import { unified } from 'unified'
10 | import type { Processor } from 'unified'
11 |
12 | const schemaStr = JSON.stringify(defaultSchema)
13 |
14 | /**
15 | * Get unified processor with ByteMD plugins
16 | */
17 | export function getProcessor({
18 | sanitize,
19 | plugins,
20 | remarkRehype: remarkRehypeOptions = {},
21 | }: Omit) {
22 | let processor: Processor = unified().use(remarkParse)
23 |
24 | plugins?.forEach(({ remark }) => {
25 | if (remark) processor = remark(processor)
26 | })
27 | processor = processor
28 | .use(remarkRehype, { allowDangerousHtml: true, ...remarkRehypeOptions })
29 | .use(rehypeRaw)
30 |
31 | let schema = JSON.parse(schemaStr) as Schema
32 | schema.attributes!['*'].push('className') // Allow class names by default
33 |
34 | if (typeof sanitize === 'function') {
35 | schema = sanitize(schema)
36 | }
37 |
38 | processor = processor.use(rehypeSanitize, schema)
39 |
40 | plugins?.forEach(({ rehype }) => {
41 | if (rehype) processor = rehype(processor)
42 | })
43 |
44 | return processor.use(rehypeStringify)
45 | }
46 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/tr.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Kalın",
3 | "boldText": "kalın metin",
4 | "cheatsheet": "Markdown Kısayol Tuşları",
5 | "closeHelp": "Yardımı Kapat",
6 | "closeToc": "İçindekileri Kapat",
7 | "code": "Kod",
8 | "codeBlock": "Kod bloğu",
9 | "codeLang": "dil",
10 | "codeText": "kod",
11 | "exitFullscreen": "Tam ekrandan çık",
12 | "exitPreviewOnly": "Sadece ön izlemeyi kapat",
13 | "exitWriteOnly": "Sadece editörü kapat",
14 | "fullscreen": "Tam ekran",
15 | "h1": "Başlık 1",
16 | "h2": "Başlık 2",
17 | "h3": "Başlık 3",
18 | "h4": "Başlık 4",
19 | "h5": "Başlık 5",
20 | "h6": "Başlık 6",
21 | "headingText": "başlık",
22 | "help": "Yardım",
23 | "hr": "Yatay Çizgi",
24 | "image": "Resim",
25 | "imageAlt": "alternatif metin",
26 | "imageTitle": "başlık",
27 | "italic": "italik",
28 | "italicText": "italik metin",
29 | "limited": "Maksimum karakter sınırına ulaşıldı",
30 | "lines": "Satırlar",
31 | "link": "Bağlantı",
32 | "linkText": "bağlantı metni",
33 | "ol": "Sıralı liste",
34 | "olItem": "madde",
35 | "preview": "Ön izleme",
36 | "previewOnly": "Sadece ön izleme",
37 | "quote": "Alıntı",
38 | "quotedText": "alıntılanmış metin",
39 | "shortcuts": "Kısayollar",
40 | "source": "Kaynak kodu",
41 | "sync": "Kaydırma senkronizasyonu",
42 | "toc": "İçindekiler",
43 | "top": "En başa git",
44 | "ul": "Sırasız liste",
45 | "ulItem": "madde",
46 | "words": "Kelimeler",
47 | "write": "Yaz",
48 | "writeOnly": "Sadece yazı modu"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Gras",
3 | "boldText": "texte en gras",
4 | "cheatsheet": "Aide-mémoire Markdown",
5 | "closeHelp": "Fermer l'aide",
6 | "closeToc": "Ferme le sommaire",
7 | "code": "Code",
8 | "codeBlock": "Bloc de code",
9 | "codeLang": "langue",
10 | "codeText": "code",
11 | "exitFullscreen": "Quitter le plein écran",
12 | "exitPreviewOnly": "Quitter l'aperçu seul",
13 | "exitWriteOnly": "Quitter l'écriture seule",
14 | "fullscreen": "Plein écran",
15 | "h1": "Titre 1",
16 | "h2": "Titre 2",
17 | "h3": "Titre 3",
18 | "h4": "Titre 4",
19 | "h5": "Titre 5",
20 | "h6": "Titre 6",
21 | "headingText": "titre",
22 | "help": "Aide",
23 | "hr": "Règle horizontale",
24 | "image": "Image",
25 | "imageAlt": "alt",
26 | "imageTitle": "titre",
27 | "italic": "Italique",
28 | "italicText": "texte en italique",
29 | "limited": "La limite maximale de caractères a été atteinte",
30 | "lines": "Lignes",
31 | "link": "Lien",
32 | "linkText": "texte du texte",
33 | "ol": "Liste ordonnée",
34 | "olItem": "élément",
35 | "preview": "Aperçu",
36 | "previewOnly": "Aperçu seul",
37 | "quote": "Citation",
38 | "quotedText": "texte cité",
39 | "shortcuts": "Raccourcis",
40 | "source": "Code source",
41 | "sync": "Défilement synchro",
42 | "toc": "Sommaire",
43 | "top": "Défiler vers le haut",
44 | "ul": "Liste non ordonnée",
45 | "ulItem": "élément",
46 | "words": "Mots",
47 | "write": "Écrire",
48 | "writeOnly": "Écriture seule"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Pogrubienie",
3 | "boldText": "pogrubienie",
4 | "cheatsheet": "Ściągawka markdowna",
5 | "closeHelp": "Zamknij pomoc",
6 | "closeToc": "Zamknij spis treści",
7 | "code": "Kod",
8 | "codeBlock": "Blok kodu",
9 | "codeLang": "język",
10 | "codeText": "kod",
11 | "exitFullscreen": "Zamknij pełny ekran",
12 | "exitPreviewOnly": "Zamknij widok podglądu",
13 | "exitWriteOnly": "Zamknij widok edytora",
14 | "fullscreen": "Pełny ekran",
15 | "h1": "Nagłówek 1",
16 | "h2": "Nagłówek 2",
17 | "h3": "Nagłówek 3",
18 | "h4": "Nagłówek 4",
19 | "h5": "Nagłówek 5",
20 | "h6": "Nagłówek 6",
21 | "headingText": "nagłówek",
22 | "help": "Pomoc",
23 | "hr": "Pozioma linia",
24 | "image": "Obraz",
25 | "imageAlt": "tekst alternatywny",
26 | "imageTitle": "tytuł",
27 | "italic": "Kursywa",
28 | "italicText": "kursywa",
29 | "limited": "Osiągnięto limit liczby znaków",
30 | "lines": "Linie",
31 | "link": "Hiperłącze",
32 | "linkText": "hiperłącze",
33 | "ol": "Lista numerowana",
34 | "olItem": "element listy",
35 | "preview": "Podgląd",
36 | "previewOnly": "Tylko podgląd",
37 | "quote": "Cytat",
38 | "quotedText": "cytat",
39 | "shortcuts": "Skróty",
40 | "source": "Kod źródłowy",
41 | "sync": "Synchronizuj przewijanie",
42 | "toc": "Spis treści",
43 | "top": "Przewiń do góry",
44 | "ul": "Lista nienumerowana",
45 | "ulItem": "element listy",
46 | "words": "Słowa",
47 | "write": "Edytor",
48 | "writeOnly": "Tylko edytor"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/react/src/viewer.tsx:
--------------------------------------------------------------------------------
1 | import * as bytemd from 'bytemd'
2 | import React, { useMemo, useEffect, useRef, FC } from 'react'
3 |
4 | export interface ViewerProps extends bytemd.ViewerProps {}
5 |
6 | export const Viewer: FC = ({
7 | value,
8 | sanitize,
9 | plugins,
10 | remarkRehype,
11 | }) => {
12 | const elRef = useRef(null)
13 | const file = useMemo(() => {
14 | try {
15 | return bytemd
16 | .getProcessor({ sanitize, plugins, remarkRehype })
17 | .processSync(value)
18 | } catch (err) {
19 | console.error(err)
20 | }
21 | }, [value, sanitize, plugins, remarkRehype])
22 |
23 | useEffect(() => {
24 | const markdownBody = elRef.current
25 | if (!markdownBody || !file) return
26 |
27 | const cbs = plugins?.map(({ viewerEffect }) =>
28 | viewerEffect?.({ markdownBody, file })
29 | )
30 | return () => {
31 | cbs?.forEach((cb) => cb && cb())
32 | }
33 | }, [file, plugins])
34 |
35 | return (
36 | {
38 | const $ = e.target as HTMLElement
39 | if ($.tagName !== 'A') return
40 |
41 | const href = $.getAttribute('href')
42 | if (!href?.startsWith('#')) return
43 |
44 | elRef.current
45 | ?.querySelector('#user-content-' + href.slice(1))
46 | ?.scrollIntoView()
47 | }}
48 | ref={elRef}
49 | className="markdown-body"
50 | dangerouslySetInnerHTML={{ __html: file?.toString() ?? '' }}
51 | >
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/nb_NO.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Fet",
3 | "boldText": "fet tekst",
4 | "cheatsheet": "Markdown-jukseark",
5 | "closeHelp": "Lukk hjelp",
6 | "closeToc": "Lukk innholdsfortegnelse",
7 | "code": "Kode",
8 | "codeBlock": "Kodeblokk",
9 | "codeLang": "språk",
10 | "codeText": "kode",
11 | "exitFullscreen": "Avslutt fullskjermsvisning",
12 | "exitPreviewOnly": "Avslutt kun forhåndsvisning",
13 | "exitWriteOnly": "Avslutt kun skriving",
14 | "fullscreen": "Fullskjermsvisning",
15 | "h1": "Overskrift 1",
16 | "h2": "Overskrift 2",
17 | "h3": "Overskrift 3",
18 | "h4": "Overskrift 4",
19 | "h5": "Overskrift 5",
20 | "h6": "Overskrift 6",
21 | "headingText": "overskrift",
22 | "help": "Hjelp",
23 | "hr": "Vannrett linje",
24 | "image": "Bilde",
25 | "imageAlt": "alt. tekst",
26 | "imageTitle": "tittel",
27 | "italic": "Kursiv",
28 | "italicText": "skråskriftstekst",
29 | "limited": "Maksimalt antall tegn oppbrukt",
30 | "lines": "Linjer",
31 | "link": "Lenke",
32 | "linkText": "lenketekst",
33 | "ol": "Nummerert liste",
34 | "olItem": "element",
35 | "preview": "Forhåndsvis",
36 | "previewOnly": "Kun forhåndsvisning",
37 | "quote": "Sitat",
38 | "quotedText": "Sitert tekst",
39 | "shortcuts": "Snarveier",
40 | "source": "Kildekode",
41 | "sync": "Rullingssynkronisering",
42 | "toc": "Innholdsfortegnelse",
43 | "top": "Rull til toppen",
44 | "ul": "Liste",
45 | "ulItem": "element",
46 | "words": "Ord",
47 | "write": "Skriv",
48 | "writeOnly": "Kun skriving"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Fett",
3 | "boldText": "Fetter Text",
4 | "cheatsheet": "Markdown-Spickzettel",
5 | "closeHelp": "Hilfe schließen",
6 | "closeToc": "Inhaltsverzeichnis schließen",
7 | "code": "Code",
8 | "codeBlock": "Codeblock",
9 | "codeLang": "Sprache",
10 | "codeText": "Code",
11 | "exitFullscreen": "Vollbildmodus beenden",
12 | "exitPreviewOnly": "Nur Vorschau schließen",
13 | "exitWriteOnly": "Nur Schreiben schließen",
14 | "fullscreen": "Vollbild",
15 | "h1": "Überschrift 1",
16 | "h2": "Überschrift 2",
17 | "h3": "Überschrift 3",
18 | "h4": "Überschrift 4",
19 | "h5": "Überschrift 5",
20 | "h6": "Überschrift 6",
21 | "headingText": "Überschrift",
22 | "help": "Hilfe",
23 | "hr": "Horizontale Linie",
24 | "image": "Bild",
25 | "imageAlt": "Alternativtext",
26 | "imageTitle": "Titel",
27 | "italic": "Kursiv",
28 | "italicText": "Kursiver Text",
29 | "limited": "Die maximale Zeichengrenze ist erreicht",
30 | "lines": "Zeilen",
31 | "link": "Link",
32 | "linkText": "Linktext",
33 | "ol": "Geordnete Liste",
34 | "olItem": "Artikel",
35 | "preview": "Vorschau",
36 | "previewOnly": "Nur Vorschau",
37 | "quote": "Zitat",
38 | "quotedText": "Zitattext",
39 | "shortcuts": "Verknüpfungen",
40 | "source": "Quellcode",
41 | "sync": "Synchronisiertes Scrollen",
42 | "toc": "Inhaltsverzeichnis",
43 | "top": "Nach oben scrollen",
44 | "ul": "Ungeordnete Liste",
45 | "ulItem": "Artikel",
46 | "words": "Wörter",
47 | "write": "Schreiben",
48 | "writeOnly": "Nur Schreiben"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/pt.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Negrito",
3 | "boldText": "texto em negrito",
4 | "cheatsheet": "Referência de Markdown",
5 | "closeHelp": "Fechar ajuda",
6 | "closeToc": "Fechar índice",
7 | "code": "Código",
8 | "codeBlock": "Bloco de código",
9 | "codeLang": "linguagem",
10 | "codeText": "código",
11 | "exitFullscreen": "Sair do ecrã inteiro",
12 | "exitPreviewOnly": "Sair apenas do modo Visualizar",
13 | "exitWriteOnly": "Sair apenas do modo Escrever",
14 | "fullscreen": "Tela Cheia",
15 | "h1": "Cabeçalho 1",
16 | "h2": "Cabeçalho 2",
17 | "h3": "Cabeçalho 3",
18 | "h4": "Cabeçalho 4",
19 | "h5": "Cabeçalho 5",
20 | "h6": "Cabeçalho 6",
21 | "headingText": "cabeçalho",
22 | "help": "ajuda",
23 | "hr": "Linha horizontal",
24 | "image": "Imagem",
25 | "imageAlt": "alt",
26 | "imageTitle": "titulo",
27 | "italic": "Italico",
28 | "italicText": "texto em italico",
29 | "limited": "O máximo de caracteres foi atingido",
30 | "lines": "Linhas",
31 | "link": "Link",
32 | "linkText": "texto do link",
33 | "ol": "Lista Ordenada",
34 | "olItem": "item",
35 | "preview": "Visualizar",
36 | "previewOnly": "Somente visualização",
37 | "quote": "Citar",
38 | "quotedText": "texto citado",
39 | "shortcuts": "Atalhos",
40 | "source": "Código-fonte",
41 | "sync": "Sincronizar a barra de rolagem",
42 | "toc": "Índice",
43 | "top": "Rolar para cima",
44 | "ul": "Lista não ordenada",
45 | "ulItem": "item",
46 | "words": "Palavras",
47 | "write": "Escrever",
48 | "writeOnly": "Apenas escrever"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/pt_BR.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Negrito",
3 | "boldText": "texto em negrito",
4 | "cheatsheet": "Referência de Markdown",
5 | "closeHelp": "Fechar ajuda",
6 | "closeToc": "Fechar índice",
7 | "code": "Código",
8 | "codeBlock": "Bloco de código",
9 | "codeLang": "linguagem",
10 | "codeText": "código",
11 | "exitFullscreen": "Sair da tela cheia",
12 | "exitPreviewOnly": "Sair apenas do modo Visualizar",
13 | "exitWriteOnly": "Sair apenas do modo Escrever",
14 | "fullscreen": "Tela cheia",
15 | "h1": "Cabeçalho 1",
16 | "h2": "Cabeçalho 2",
17 | "h3": "Cabeçalho 3",
18 | "h4": "Cabeçalho 4",
19 | "h5": "Cabeçalho 5",
20 | "h6": "Cabeçalho 6",
21 | "headingText": "cabeçalho",
22 | "help": "Ajuda",
23 | "hr": "Linha horizontal",
24 | "image": "Imagem",
25 | "imageAlt": "texto",
26 | "imageTitle": "título",
27 | "italic": "Itálico",
28 | "italicText": "texto itálico",
29 | "limited": "O limite máximo de caracteres foi atingido",
30 | "lines": "Linhas",
31 | "link": "Link",
32 | "linkText": "texto do link",
33 | "ol": "Lista ordenada",
34 | "olItem": "item",
35 | "preview": "Visualizar",
36 | "previewOnly": "Visualizar apenas",
37 | "quote": "Citar",
38 | "quotedText": "texto citado",
39 | "shortcuts": "Atalhos",
40 | "source": "Código fonte",
41 | "sync": "Sincronizar a barra de rolagem",
42 | "toc": "Índice",
43 | "top": "Rolar para cima",
44 | "ul": "Lista não ordenada",
45 | "ulItem": "item",
46 | "words": "Palavras",
47 | "write": "Escrever",
48 | "writeOnly": "Escrever apenas"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Negrita",
3 | "boldText": "texto en negritas",
4 | "cheatsheet": "Referencia rápida de Markdown",
5 | "closeHelp": "Cerrar ayuda",
6 | "closeToc": "Cerrar sumario",
7 | "code": "Código",
8 | "codeBlock": "Bloque de código",
9 | "codeLang": "lenguaje",
10 | "codeText": "código",
11 | "exitFullscreen": "Salir de pantalla completa",
12 | "exitPreviewOnly": "Salir de Solo previsualización",
13 | "exitWriteOnly": "Salir de Solo escritura",
14 | "fullscreen": "Pantalla completa",
15 | "h1": "Título 1",
16 | "h2": "Título 2",
17 | "h3": "Título 3",
18 | "h4": "Título 4",
19 | "h5": "Título 5",
20 | "h6": "Título 6",
21 | "headingText": "título",
22 | "help": "Ayuda",
23 | "hr": "Línea horizontal",
24 | "image": "Imagen",
25 | "imageAlt": "texto alt.",
26 | "imageTitle": "título",
27 | "italic": "Itálica",
28 | "italicText": "texto en itálicas",
29 | "limited": "S'ha arribat al límit màxim de caràcters",
30 | "lines": "Renglones",
31 | "link": "Enlace",
32 | "linkText": "texto de enlace",
33 | "ol": "Lista numerada",
34 | "olItem": "elemento",
35 | "preview": "Previsualizar",
36 | "previewOnly": "Solo previsualización",
37 | "quote": "Cita",
38 | "quotedText": "texto citado",
39 | "shortcuts": "Atajos",
40 | "source": "Código fuente",
41 | "sync": "Desplazamiento síncrono",
42 | "toc": "Sumario",
43 | "top": "Desplazarse hasta arriba",
44 | "ul": "Lista con bolos",
45 | "ulItem": "elemento",
46 | "words": "Palabras",
47 | "write": "Escribir",
48 | "writeOnly": "Solo escritura"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/ru.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Жирный",
3 | "boldText": "жирный текст",
4 | "cheatsheet": "Шпаргалка по Markdown",
5 | "closeHelp": "Закрыть справку",
6 | "closeToc": "Закрыть оглавление",
7 | "code": "Код",
8 | "codeBlock": "Блок кода",
9 | "codeLang": "язык",
10 | "codeText": "код",
11 | "exitFullscreen": "Выйти из полноэкранного режима",
12 | "exitPreviewOnly": "Выйти из режима предпросмотра",
13 | "exitWriteOnly": "Выйти из режима редактирования",
14 | "fullscreen": "Полноэкранный режим",
15 | "h1": "Заголовок 1",
16 | "h2": "Заголовок 2",
17 | "h3": "Заголовок 3",
18 | "h4": "Заголовок 4",
19 | "h5": "Заголовок 5",
20 | "h6": "Заголовок 6",
21 | "headingText": "заголовок",
22 | "help": "Справка",
23 | "hr": "Горизонтальная линия",
24 | "image": "Изображение",
25 | "imageAlt": "alt",
26 | "imageTitle": "название",
27 | "italic": "Курсив",
28 | "italicText": "курсивный текст",
29 | "limited": "Достигнуто максимальное количество символов",
30 | "lines": "Строки",
31 | "link": "Ссылка",
32 | "linkText": "текст ссылки",
33 | "ol": "Нумерованный список",
34 | "olItem": "элемент",
35 | "preview": "Предпросмотр",
36 | "previewOnly": "Только предпросмотр",
37 | "quote": "Цитата",
38 | "quotedText": "цитируемый текст",
39 | "shortcuts": "Горячие клавиши",
40 | "source": "Исходный код",
41 | "sync": "Синхронизация прокрутки",
42 | "toc": "Оглавление",
43 | "top": "Пролистать наверх",
44 | "ul": "Маркированный список",
45 | "ulItem": "элемент",
46 | "words": "Слова",
47 | "write": "Редактор",
48 | "writeOnly": "Только редактор"
49 | }
50 |
--------------------------------------------------------------------------------
/packages/bytemd/locales/ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "bold": "Negreta",
3 | "boldText": "text en negreta",
4 | "cheatsheet": "Referència ràpida del Markdown",
5 | "closeHelp": "Tanca l’ajuda",
6 | "closeToc": "Tanca la taula de contingut",
7 | "code": "Codi",
8 | "codeBlock": "Bloc de codi",
9 | "codeLang": "llenguatge",
10 | "codeText": "codi",
11 | "exitFullscreen": "Surt de la pantalla completa",
12 | "exitPreviewOnly": "Surt de «Només previsualització»",
13 | "exitWriteOnly": "Surt de «Només escriptura»",
14 | "fullscreen": "Pantalla completa",
15 | "h1": "Encapçalament 1",
16 | "h2": "Encapçalament 2",
17 | "h3": "Encapçalament 3",
18 | "h4": "Encapçalament 4",
19 | "h5": "Encapçalament 5",
20 | "h6": "Encapçalament 6",
21 | "headingText": "encapçalament",
22 | "help": "Ajuda",
23 | "hr": "Línia horitzontal",
24 | "image": "Imatge",
25 | "imageAlt": "text alt.",
26 | "imageTitle": "títol",
27 | "italic": "Cursiva",
28 | "italicText": "text en cursiva",
29 | "limited": "S'ha arribat al límit màxim de caràcters",
30 | "lines": "Línies",
31 | "link": "Enllaç",
32 | "linkText": "text de l’enllaç",
33 | "ol": "Llista ordenada",
34 | "olItem": "element",
35 | "preview": "Previsualització",
36 | "previewOnly": "Només previsualització",
37 | "quote": "Cita",
38 | "quotedText": "text citat",
39 | "shortcuts": "Dreceres",
40 | "source": "Codi font",
41 | "sync": "Desplaçament síncron",
42 | "toc": "Taula de contingut",
43 | "top": "Desplaça’t fins al capdamunt",
44 | "ul": "Llista sense ordenar",
45 | "ulItem": "element",
46 | "words": "Mots",
47 | "write": "Escriptura",
48 | "writeOnly": "Només escriptura"
49 | }
50 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Node template
3 | # Logs
4 | /logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 | *.pid.lock
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Bower dependency directory (https://bower.io/)
29 | bower_components
30 |
31 | # node-waf configuration
32 | .lock-wscript
33 |
34 | # Compiled binary addons (https://nodejs.org/api/addons.html)
35 | build/Release
36 |
37 | # Dependency directories
38 | node_modules/
39 | jspm_packages/
40 |
41 | # TypeScript v1 declaration files
42 | typings/
43 |
44 | # Optional npm cache directory
45 | .npm
46 |
47 | # Optional eslint cache
48 | .eslintcache
49 |
50 | # Optional REPL history
51 | .node_repl_history
52 |
53 | # Output of 'npm pack'
54 | *.tgz
55 |
56 | # Yarn Integrity file
57 | .yarn-integrity
58 |
59 | # dotenv environment variables file
60 | .env
61 |
62 | # parcel-bundler cache (https://parceljs.org/)
63 | .cache
64 |
65 | # next.js build output
66 | .next
67 |
68 | # nuxt.js build output
69 | .nuxt
70 |
71 | # Nuxt generate
72 | dist
73 |
74 | # vuepress build output
75 | .vuepress/dist
76 |
77 | # Serverless directories
78 | .serverless
79 |
80 | # IDE / Editor
81 | .idea
82 |
83 | # Service worker
84 | sw.*
85 |
86 | # macOS
87 | .DS_Store
88 |
89 | # Vim swap files
90 | *.swp
91 |
--------------------------------------------------------------------------------
/packages/vue/src/viewer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
67 |
--------------------------------------------------------------------------------
/examples/react-nextjs/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | ```
12 |
13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14 |
15 | You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
16 |
17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
18 |
19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 |
--------------------------------------------------------------------------------
/packages/bytemd/src/help.svelte:
--------------------------------------------------------------------------------
1 |
26 |
27 |
28 |
{locale.cheatsheet}
29 |
42 |
{locale.shortcuts}
43 |
56 |
57 |
--------------------------------------------------------------------------------
/examples/vue3/README.md:
--------------------------------------------------------------------------------
1 | # vue-next
2 |
3 | This template should help get you started developing with Vue 3 in Vite.
4 |
5 | ## Recommended IDE Setup
6 |
7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin).
8 |
9 | ## Type Support for `.vue` Imports in TS
10 |
11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
12 |
13 | If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
14 |
15 | 1. Disable the built-in TypeScript Extension
16 | 1. Run `Extensions: Show Built-in Extensions` from VSCode's command palette
17 | 2. Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
18 | 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
19 |
20 | ## Customize configuration
21 |
22 | See [Vite Configuration Reference](https://vitejs.dev/config/).
23 |
24 | ## Project Setup
25 |
26 | ```sh
27 | npm install
28 | ```
29 |
30 | ### Compile and Hot-Reload for Development
31 |
32 | ```sh
33 | npm run dev
34 | ```
35 |
36 | ### Type-Check, Compile and Minify for Production
37 |
38 | ```sh
39 | npm run build
40 | ```
41 |
--------------------------------------------------------------------------------
/packages/bytemd/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bytemd",
3 | "version": "1.22.0",
4 | "description": "Hackable Markdown Editor and Viewer",
5 | "keywords": [
6 | "markdown",
7 | "editor",
8 | "viewer"
9 | ],
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/bytedance/bytemd.git",
13 | "directory": "packages/bytemd"
14 | },
15 | "license": "MIT",
16 | "author": "Rongjian Zhang",
17 | "exports": {
18 | ".": {
19 | "types": "./dist/index.d.ts",
20 | "svelte": "./svelte/index.js",
21 | "import": "./dist/index.mjs",
22 | "require": "./dist/index.js"
23 | },
24 | "./locales/*": "./locales/*",
25 | "./lib/locales/*": "./locales/*",
26 | "./dist/index.css": "./dist/index.css",
27 | "./dist/index.min.css": "./dist/index.min.css"
28 | },
29 | "main": "./dist/index.js",
30 | "svelte": "./svelte/index.js",
31 | "jsdelivr": "./dist/index.umd.js",
32 | "unpkg": "./dist/index.umd.js",
33 | "module": "./dist/index.mjs",
34 | "types": "./dist/index.d.ts",
35 | "files": [
36 | "dist",
37 | "locales",
38 | "svelte"
39 | ],
40 | "dependencies": {
41 | "@popperjs/core": "^2.11.7",
42 | "@types/codemirror": "^5.60.7",
43 | "@types/hast": "^2.3.4",
44 | "@types/lodash-es": "^4.17.7",
45 | "@types/mdast": "^3.0.11",
46 | "codemirror-ssr": "^0.65.0",
47 | "hast-util-sanitize": "^4.1.0",
48 | "lodash-es": "^4.17.21",
49 | "rehype-raw": "^6.1.1",
50 | "rehype-sanitize": "^5.0.1",
51 | "rehype-stringify": "^9.0.3",
52 | "remark-parse": "^10.0.1",
53 | "remark-rehype": "^10.1.0",
54 | "select-files": "^1.0.1",
55 | "tippy.js": "^6.3.7",
56 | "unified": "^10.1.2",
57 | "unist-util-visit": "^4.1.2",
58 | "vfile": "^5.3.7",
59 | "word-count": "^0.2.2"
60 | },
61 | "devDependencies": {
62 | "@primer/css": "^15.2.0"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/examples/react/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/packages/plugin-gfm/src/index.ts:
--------------------------------------------------------------------------------
1 | import { icons } from './icons'
2 | import en from './locales/en.json'
3 | import type { BytemdPlugin } from 'bytemd'
4 | import remarkGfm, { Options } from 'remark-gfm'
5 |
6 | type Locale = {
7 | strike: string
8 | strikeText: string
9 | task: string
10 | taskText: string
11 | table: string
12 | tableHeading: string
13 | }
14 |
15 | export interface BytemdPluginGfmOptions extends Options {
16 | locale?: Partial
17 | }
18 |
19 | export default function gfm({
20 | locale: _locale,
21 | ...remarkGfmOptions
22 | }: BytemdPluginGfmOptions = {}): BytemdPlugin {
23 | const locale = { ...en, ..._locale } as Locale
24 |
25 | return {
26 | remark: (processor) => processor.use(remarkGfm, remarkGfmOptions),
27 | actions: [
28 | {
29 | title: locale.strike,
30 | icon: icons.Strikethrough,
31 | cheatsheet: `~~${locale.strikeText}~~`,
32 | handler: {
33 | type: 'action',
34 | click({ wrapText, editor }) {
35 | wrapText('~~')
36 | editor.focus()
37 | },
38 | },
39 | },
40 | {
41 | title: locale.task,
42 | icon: icons.CheckCorrect,
43 | cheatsheet: `- [ ] ${locale.taskText}`,
44 | handler: {
45 | type: 'action',
46 | click({ replaceLines, editor }) {
47 | replaceLines((line) => '- [ ] ' + line)
48 | editor.focus()
49 | },
50 | },
51 | },
52 | {
53 | title: locale.table,
54 | icon: icons.InsertTable,
55 | handler: {
56 | type: 'action',
57 | click({ editor, appendBlock, codemirror }) {
58 | const { line } = appendBlock(
59 | `| ${locale.tableHeading} | |\n| --- | --- |\n| | |\n`
60 | )
61 | editor.setSelection(
62 | codemirror.Pos(line, 2),
63 | codemirror.Pos(line, 2 + locale.tableHeading.length)
64 | )
65 | editor.focus()
66 | },
67 | },
68 | },
69 | ],
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/packages/vue-next/src/viewer.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
88 |
--------------------------------------------------------------------------------
/playground/src/text.md:
--------------------------------------------------------------------------------
1 | ---
2 | # frontmatter: https://jekyllrb.com/docs/front-matter/
3 | layout: post
4 | title: Blogging Like a Hacker
5 | ---
6 |
7 | ## Markdown Basic Syntax
8 |
9 | I just love **bold text**. Italicized text is the _cat's meow_. At the command prompt, type `nano`.
10 |
11 | My favorite markdown editor is [ByteMD](https://github.com/bytedance/bytemd).
12 |
13 | 1. First item
14 | 2. Second item
15 | 3. Third item
16 |
17 | > Dorothy followed her through many of the beautiful rooms in her castle.
18 |
19 | ```js
20 | import gfm from '@bytemd/plugin-gfm'
21 | import { Editor, Viewer } from 'bytemd'
22 |
23 | const plugins = [
24 | gfm(),
25 | // Add more plugins here
26 | ]
27 |
28 | const editor = new Editor({
29 | target: document.body, // DOM to render
30 | props: {
31 | value: '',
32 | plugins,
33 | },
34 | })
35 |
36 | editor.on('change', (e) => {
37 | editor.$set({ value: e.detail.value })
38 | })
39 | ```
40 |
41 | ## GFM Extended Syntax
42 |
43 | Automatic URL Linking: https://github.com/bytedance/bytemd
44 |
45 | ~~The world is flat.~~ We now know that the world is round.
46 |
47 | - [x] Write the press release
48 | - [ ] Update the website
49 | - [ ] Contact the media
50 |
51 | | Syntax | Description |
52 | | --------- | ----------- |
53 | | Header | Title |
54 | | Paragraph | Text |
55 |
56 | ## Footnotes
57 |
58 | Here's a simple footnote,[^1] and here's a longer one.[^bignote]
59 |
60 | [^1]: This is the first footnote.
61 | [^bignote]: Here's one with multiple paragraphs and code.
62 |
63 | Indent paragraphs to include them in the footnote.
64 |
65 | `{ my code }`
66 |
67 | Add as many paragraphs as you like.
68 |
69 | ## Gemoji
70 |
71 | Thumbs up: :+1:, thumbs down: :-1:.
72 |
73 | Families: :family_man_man_boy_boy:
74 |
75 | Long flags: :wales:, :scotland:, :england:.
76 |
77 | ## Math Equation
78 |
79 | Inline math equation: $a+b$
80 |
81 | $$
82 | \displaystyle \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)
83 | $$
84 |
85 | ## Mermaid Diagrams
86 |
87 | ```mermaid
88 | graph TD;
89 | A-->B;
90 | A-->C;
91 | B-->D;
92 | C-->D;
93 | ```
94 |
--------------------------------------------------------------------------------
/examples/react/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
--------------------------------------------------------------------------------
/packages/bytemd/src/toc.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
53 |
54 |
55 |
{locale.toc}
56 |
57 | {#each items as item, index}
58 | {
64 | dispatch('click', index)
65 | }}
66 | on:keydown|self={(e) => {
67 | if (['Enter', 'Space'].includes(e.code)) {
68 | dispatch('click', index)
69 | }
70 | }}
71 | >
72 | {item.text}
73 |
74 | {/each}
75 |
76 |
77 |
--------------------------------------------------------------------------------
/examples/react-nextjs/styles/Home.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 0 2rem;
3 | }
4 |
5 | .main {
6 | min-height: 100vh;
7 | padding: 4rem 0;
8 | flex: 1;
9 | display: flex;
10 | flex-direction: column;
11 | justify-content: center;
12 | align-items: center;
13 | }
14 |
15 | .footer {
16 | display: flex;
17 | flex: 1;
18 | padding: 2rem 0;
19 | border-top: 1px solid #eaeaea;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | .footer a {
25 | display: flex;
26 | justify-content: center;
27 | align-items: center;
28 | flex-grow: 1;
29 | }
30 |
31 | .title a {
32 | color: #0070f3;
33 | text-decoration: none;
34 | }
35 |
36 | .title a:hover,
37 | .title a:focus,
38 | .title a:active {
39 | text-decoration: underline;
40 | }
41 |
42 | .title {
43 | margin: 0;
44 | line-height: 1.15;
45 | font-size: 4rem;
46 | }
47 |
48 | .title,
49 | .description {
50 | text-align: center;
51 | }
52 |
53 | .description {
54 | margin: 4rem 0;
55 | line-height: 1.5;
56 | font-size: 1.5rem;
57 | }
58 |
59 | .code {
60 | background: #fafafa;
61 | border-radius: 5px;
62 | padding: 0.75rem;
63 | font-size: 1.1rem;
64 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
65 | Bitstream Vera Sans Mono, Courier New, monospace;
66 | }
67 |
68 | .grid {
69 | display: flex;
70 | align-items: center;
71 | justify-content: center;
72 | flex-wrap: wrap;
73 | max-width: 800px;
74 | }
75 |
76 | .card {
77 | margin: 1rem;
78 | padding: 1.5rem;
79 | text-align: left;
80 | color: inherit;
81 | text-decoration: none;
82 | border: 1px solid #eaeaea;
83 | border-radius: 10px;
84 | transition: color 0.15s ease, border-color 0.15s ease;
85 | max-width: 300px;
86 | }
87 |
88 | .card:hover,
89 | .card:focus,
90 | .card:active {
91 | color: #0070f3;
92 | border-color: #0070f3;
93 | }
94 |
95 | .card h2 {
96 | margin: 0 0 1rem 0;
97 | font-size: 1.5rem;
98 | }
99 |
100 | .card p {
101 | margin: 0;
102 | font-size: 1.25rem;
103 | line-height: 1.5;
104 | }
105 |
106 | .logo {
107 | height: 1em;
108 | margin-left: 0.5rem;
109 | }
110 |
111 | @media (max-width: 600px) {
112 | .grid {
113 | width: 100%;
114 | flex-direction: column;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@bytemd/monorepo",
3 | "private": true,
4 | "workspaces": [
5 | "packages/*"
6 | ],
7 | "scripts": {
8 | "build": "pnpm clean && node scripts/build.mjs && tsc --build",
9 | "clean": "rm -rf packages/*/tsconfig.tsbuildinfo && rm -rf packages/*/dist",
10 | "dev": "pnpm --filter playground dev",
11 | "format": "prettier --write '**/*.{ts,tsx,json,md,svelte}' && sort-package-json package.json 'packages/*/package.json'",
12 | "postinstall": "node scripts/postinstall.mjs && pnpm format && sort-json packages/*/locales/*.json",
13 | "pub": "pnpm build && lerna publish",
14 | "style": "prettier --check '**/*.{ts,tsx,json,md,svelte}'",
15 | "test": "vitest"
16 | },
17 | "prettier": {
18 | "pluginSearchDirs": [
19 | "."
20 | ],
21 | "proseWrap": "never",
22 | "semi": false,
23 | "singleQuote": true
24 | },
25 | "devDependencies": {
26 | "@icon-park/svg": "^1.4.2",
27 | "@sveltejs/vite-plugin-svelte": "2.0.4",
28 | "@testing-library/jest-dom": "^5.16.5",
29 | "@testing-library/svelte": "^3.2.2",
30 | "@trivago/prettier-plugin-sort-imports": "^4.1.1",
31 | "@types/fs-extra": "^11.0.1",
32 | "@types/lodash-es": "^4.17.7",
33 | "@types/resolve": "^1.20.2",
34 | "conventional-changelog-cli": "^2.2.2",
35 | "decode-named-character-reference": "^1.0.2",
36 | "execa": "^7.1.1",
37 | "fast-glob": "^3.2.12",
38 | "fs-extra": "^11.1.1",
39 | "jsdom": "^21.1.1",
40 | "lerna": "^6.6.1",
41 | "lodash-es": "^4.17.21",
42 | "mustache": "^4.2.0",
43 | "prettier": "^2.8.7",
44 | "prettier-plugin-svelte": "^2.10.0",
45 | "resolve": "^1.22.1",
46 | "sass": "^1.60.0",
47 | "sort-json": "^2.0.1",
48 | "sort-package-json": "^2.4.1",
49 | "svelte": "^3.57.0",
50 | "svelte-preprocess": "^5.0.3",
51 | "svelte2tsx": "^0.6.10",
52 | "svgo": "^3.0.2",
53 | "typescript": "^5.0.2",
54 | "vite": "^4.2.1",
55 | "vitest": "^0.29.8"
56 | },
57 | "packageManager": "pnpm@8.15.9+sha512.499434c9d8fdd1a2794ebf4552b3b25c0a633abcee5bb15e7b5de90f32f47b513aca98cd5cfd001c31f0db454bc3804edccd578501e4ca293a6816166bbd9f81",
58 | "bundlewatch": {
59 | "files": [
60 | {
61 | "path": "packages/*/dist/index.umd.js"
62 | }
63 | ],
64 | "ci": {
65 | "repoBranchBase": "main",
66 | "trackBranches": [
67 | "main"
68 | ]
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/packages/bytemd/src/viewer.svelte:
--------------------------------------------------------------------------------
1 |
2 |
3 |
93 |
94 |
95 | {@html html}
96 |
97 |
--------------------------------------------------------------------------------
/examples/vue-nuxtjs/README.md:
--------------------------------------------------------------------------------
1 | # vue-nuxtjs
2 |
3 | ## Build Setup
4 |
5 | ```bash
6 | # install dependencies
7 | $ yarn install
8 |
9 | # serve with hot reload at localhost:3000
10 | $ yarn dev
11 |
12 | # build for production and launch server
13 | $ yarn build
14 | $ yarn start
15 |
16 | # generate static project
17 | $ yarn generate
18 | ```
19 |
20 | For detailed explanation on how things work, check out the [documentation](https://nuxtjs.org).
21 |
22 | ## Special Directories
23 |
24 | You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality.
25 |
26 | ### `assets`
27 |
28 | The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts.
29 |
30 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/assets).
31 |
32 | ### `components`
33 |
34 | The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components.
35 |
36 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/components).
37 |
38 | ### `layouts`
39 |
40 | Layouts are a great help when you want to change the look and feel of your Nuxt app, whether you want to include a sidebar or have distinct layouts for mobile and desktop.
41 |
42 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts).
43 |
44 | ### `pages`
45 |
46 | This directory contains your application views and routes. Nuxt will read all the `*.vue` files inside this directory and setup Vue Router automatically.
47 |
48 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/get-started/routing).
49 |
50 | ### `plugins`
51 |
52 | The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use `Vue.use()`, you should create a file in `plugins/` and add its path to plugins in `nuxt.config.js`.
53 |
54 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/plugins).
55 |
56 | ### `static`
57 |
58 | This directory contains your static files. Each file inside this directory is mapped to `/`.
59 |
60 | Example: `/static/robots.txt` is mapped as `/robots.txt`.
61 |
62 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/static).
63 |
64 | ### `store`
65 |
66 | This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex.
67 |
68 | More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/store).
69 |
--------------------------------------------------------------------------------
/packages/bytemd/test/editor.test.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { Editor } from '../src'
3 | import '@testing-library/jest-dom'
4 | import {
5 | render,
6 | cleanup,
7 | fireEvent,
8 | act,
9 | RenderResult,
10 | } from '@testing-library/svelte'
11 |
12 | function sleep(ms: number = 0) {
13 | return new Promise((r) => setTimeout(r, ms))
14 | }
15 |
16 | function getCodeMirror($: RenderResult) {
17 | const dom = $.container.querySelector('.CodeMirror') as any
18 | return dom.CodeMirror as CodeMirror.Editor
19 | }
20 |
21 | function stripComment(str: string) {
22 | return str.replace(/<\!--.*?-->/g, '')
23 | }
24 |
25 | const heading = '# title'
26 | const headingHtml = 'title '
27 | const paragraph = 'abc'
28 | const paragraphHtml = 'abc
'
29 |
30 | beforeEach(() => {
31 | cleanup()
32 | })
33 |
34 | test('value', async () => {
35 | const $ = render(Editor, { value: heading })
36 | const onChange = vi.fn()
37 | $.component.$on('change', onChange)
38 | await act()
39 | expect(getCodeMirror($).getValue()).toEqual(heading)
40 |
41 | // // change from UI
42 | // getCodeMirror($).setValue(paragraph);
43 | // await act();
44 | // expect(getCodeMirror($).getValue()).toEqual(paragraph);
45 | // expect(onChange).toBeCalled();
46 | // expect(onChange).toBeCalledTimes(1);
47 | // // expect(onChange).toBeCalledWith()
48 |
49 | // change from props
50 | $.component.$set({ value: heading })
51 | expect(getCodeMirror($).getValue()).toEqual(heading)
52 | expect(onChange).not.toBeCalled()
53 | })
54 |
55 | test('preview debounce', async () => {
56 | const $ = render(Editor, {})
57 | $.component.$set({ value: paragraph })
58 | expect(
59 | stripComment($.container.querySelector('.markdown-body').innerHTML)
60 | ).toEqual('')
61 | await sleep(400)
62 | expect(
63 | stripComment($.container.querySelector('.markdown-body').innerHTML)
64 | ).toEqual(paragraphHtml)
65 | })
66 |
67 | describe('mode', () => {
68 | test('split', async () => {
69 | const $ = render(Editor, { mode: 'split' })
70 | await act()
71 | expect($.container.querySelector('.bytemd-editor')).toBeVisible()
72 | expect($.container.querySelector('.bytemd-preview')).toBeVisible()
73 | })
74 |
75 | test('tab', async () => {
76 | const $ = render(Editor, { mode: 'tab' })
77 | const write = $.getByText('Write')
78 | const preview = $.getByText('Preview')
79 |
80 | expect($.container.querySelector('.bytemd-editor')).toBeVisible()
81 | expect(write).toHaveClass('bytemd-toolbar-tab-active')
82 | // expect($.container.querySelector('.bytemd-preview')).toHaveStyle('width:0');
83 | expect(preview).not.toHaveClass('bytemd-toolbar-tab-active')
84 |
85 | await fireEvent.click(preview)
86 | // expect($.container.querySelector('.bytemd-editor')).toHaveStyle('width:0');
87 | expect(write).not.toHaveClass('bytemd-toolbar-tab-active')
88 | expect($.container.querySelector('.bytemd-preview')).toBeVisible()
89 | expect(preview).toHaveClass('bytemd-toolbar-tab-active')
90 | })
91 | })
92 |
93 | describe('plugin', () => {
94 | test('editor effect', async () => {
95 | const $ = render(Editor, {})
96 | const editorOff = vi.fn()
97 | const editorEffect = vi.fn(() => editorOff)
98 |
99 | $.component.$set({ plugins: [{ editorEffect }] })
100 | await act()
101 | expect(editorEffect).toBeCalled()
102 | expect(editorEffect).toBeCalledTimes(1)
103 | expect(editorEffect).toBeCalledWith(
104 | expect.objectContaining({
105 | // $el: $.container.querySelector('.bytemd'),
106 | editor: getCodeMirror($),
107 | })
108 | )
109 |
110 | $.component.$set({ plugins: [{ editorEffect }] })
111 | await act()
112 | expect(editorOff).toBeCalled()
113 | expect(editorOff).toBeCalledTimes(1)
114 | })
115 | })
116 |
--------------------------------------------------------------------------------
/scripts/postinstall.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { packages, packagesDir, rootDir } from './utils.mjs'
3 | import fs from 'fs-extra'
4 | import _ from 'lodash-es'
5 | import mustache from 'mustache'
6 | import path from 'path'
7 |
8 | function readFileSyncSafe(p) {
9 | try {
10 | return fs.readFileSync(p, 'utf8')
11 | } catch (err) {
12 | return ''
13 | }
14 | }
15 |
16 | const plugins = packages.filter((x) => x.startsWith('plugin-'))
17 |
18 | packages.forEach((p) => {
19 | const tsconfig = path.join(packagesDir, p, 'tsconfig.json')
20 | const c = fs.readJsonSync(tsconfig)
21 | c.include = ['src', 'src/locales/*.json'] // https://github.com/microsoft/TypeScript/issues/25636#issuecomment-627111031
22 | c.compilerOptions = {
23 | rootDir: 'src',
24 | outDir: 'dist',
25 | }
26 |
27 | // tsconfig
28 | fs.writeJsonSync(tsconfig, c)
29 | })
30 |
31 | fs.writeJsonSync('tsconfig.json', {
32 | files: [],
33 | references: packages.map((p) => ({ path: path.join('packages', p) })),
34 | })
35 |
36 | packages.forEach((p) => {
37 | // license
38 | fs.copyFileSync(
39 | path.join(rootDir, 'LICENSE'),
40 | path.join(packagesDir, p, 'LICENSE')
41 | )
42 |
43 | // package.json
44 | const pkgPath = path.join(packagesDir, p, 'package.json')
45 | const pkg = fs.readJsonSync(pkgPath)
46 | pkg.repository = {
47 | type: 'git',
48 | url: 'https://github.com/bytedance/bytemd.git',
49 | directory: `packages/${p}`,
50 | }
51 |
52 | pkg.types = './dist/index.d.ts'
53 | pkg.module = './dist/index.mjs'
54 | pkg.main = './dist/index.js'
55 | pkg.unpkg = './dist/index.umd.js'
56 | pkg.jsdelivr = './dist/index.umd.js'
57 |
58 | pkg.exports = {
59 | '.': {
60 | types: './dist/index.d.ts',
61 | ...(pkg.name === 'bytemd'
62 | ? {
63 | svelte: './svelte/index.js',
64 | }
65 | : {}),
66 | import: './dist/index.mjs',
67 | require: './dist/index.js',
68 | },
69 | './locales/*': './locales/*',
70 |
71 | // for compatible with old version
72 | './lib/locales/*': './locales/*',
73 | }
74 | pkg.files = ['dist', 'locales']
75 |
76 | if (pkg.name === 'bytemd') {
77 | pkg.exports['./dist/index.css'] = './dist/index.css'
78 | pkg.exports['./dist/index.min.css'] = './dist/index.min.css'
79 | pkg.files.push('svelte')
80 | }
81 | fs.writeJsonSync(pkgPath, pkg)
82 | })
83 |
84 | // plugins readme
85 | plugins.forEach((p) => {
86 | const name = p.split('-').slice(1).join('-')
87 | const result = mustache.render(
88 | readFileSyncSafe(path.join(rootDir, 'scripts/plugin-template.md')),
89 | {
90 | name,
91 | importedName: _.camelCase(name.replace('-ssr', '')),
92 | header: p.startsWith('plugin-math')
93 | ? 'import "katex/dist/katex.css"'
94 | : p.startsWith('plugin-highlight')
95 | ? 'import "highlight.js/styles/default.css"'
96 | : '',
97 | desc: fs.readJsonSync(path.join(packagesDir, p, 'package.json'))
98 | .description,
99 | }
100 | )
101 | fs.writeFileSync(path.join(packagesDir, p, 'README.md'), result)
102 | })
103 |
104 | // bytemd readme
105 | const readme = readFileSyncSafe(path.join(rootDir, 'README.md')).replace(
106 | /### Official Plugins\s+([\w\W])*?\s+##/,
107 | (match, p1, offset, string) => {
108 | const content = plugins
109 | .map((p) => {
110 | const pkg = fs.readJsonSync(path.join(packagesDir, p, 'package.json'))
111 | if (pkg.private) return
112 |
113 | const name = p.split('-').slice(1).join('-')
114 | const badge = `[](https://npm.im/@bytemd/plugin-${name})`
115 | const desc = _.upperFirst(
116 | pkg.description.replace('ByteMD plugin to ', '')
117 | )
118 | return `| [@bytemd/plugin-${name}](https://github.com/bytedance/bytemd/tree/main/packages/plugin-${name}) | ${badge} | ${desc} |`
119 | })
120 | .filter((x) => x)
121 | .join('\n')
122 |
123 | return `### Official Plugins
124 |
125 | | Package | Status | Description |
126 | | --- | --- | --- |
127 | ${content}
128 |
129 | ##`
130 | }
131 | )
132 |
133 | fs.writeFileSync(path.join(rootDir, 'README.md'), readme)
134 |
--------------------------------------------------------------------------------
/playground/src/app.svelte:
--------------------------------------------------------------------------------
1 |
82 |
83 |
128 |
129 |
154 |
--------------------------------------------------------------------------------
/packages/plugin-mermaid/src/index.ts:
--------------------------------------------------------------------------------
1 | import { icons } from './icons'
2 | import en from './locales/en.json'
3 | import type { BytemdPlugin } from 'bytemd'
4 | import type { default as Mermaid, MermaidConfig } from 'mermaid'
5 |
6 | type Locale = {
7 | mermaid: string
8 | flowchart: string
9 | sequence: string
10 | class: string
11 | state: string
12 | er: string
13 | uj: string
14 | gantt: string
15 | pie: string
16 | mindmap: string
17 | timeline: string
18 | }
19 |
20 | export interface BytemdPluginMermaidOptions extends MermaidConfig {
21 | locale?: Partial
22 | }
23 |
24 | export default function mermaid({
25 | locale: _locale,
26 | ...mermaidConfig
27 | }: BytemdPluginMermaidOptions = {}): BytemdPlugin {
28 | const locale = { ...en, ..._locale } as Locale
29 | let m: typeof Mermaid
30 |
31 | const actionItems = [
32 | {
33 | title: locale.flowchart,
34 | code: `graph TD
35 | Start --> Stop`,
36 | },
37 | {
38 | title: locale.sequence,
39 | code: `sequenceDiagram
40 | Alice->>John: Hello John, how are you?
41 | John-->>Alice: Great!
42 | Alice-)John: See you later!`,
43 | },
44 | {
45 | title: locale.class,
46 | code: `classDiagram
47 | Animal <|-- Duck
48 | Animal <|-- Fish
49 | Animal <|-- Zebra
50 | Animal : +int age
51 | Animal : +String gender
52 | Animal: +isMammal()
53 | Animal: +mate()
54 | class Duck{
55 | +String beakColor
56 | +swim()
57 | +quack()
58 | }
59 | class Fish{
60 | -int sizeInFeet
61 | -canEat()
62 | }
63 | class Zebra{
64 | +bool is_wild
65 | +run()
66 | }`,
67 | },
68 | {
69 | title: locale.state,
70 | code: `stateDiagram-v2
71 | [*] --> Still
72 | Still --> [*]
73 |
74 | Still --> Moving
75 | Moving --> Still
76 | Moving --> Crash
77 | Crash --> [*]`,
78 | },
79 | {
80 | title: locale.er,
81 | code: `erDiagram
82 | CUSTOMER ||--o{ ORDER : places
83 | ORDER ||--|{ LINE-ITEM : contains
84 | CUSTOMER }|..|{ DELIVERY-ADDRESS : uses`,
85 | },
86 | {
87 | title: locale.uj,
88 | code: `journey
89 | title My working day
90 | section Go to work
91 | Make tea: 5: Me
92 | Go upstairs: 3: Me
93 | Do work: 1: Me, Cat
94 | section Go home
95 | Go downstairs: 5: Me
96 | Sit down: 5: Me`,
97 | },
98 | {
99 | title: locale.gantt,
100 | code: `gantt
101 | title A Gantt Diagram
102 | dateFormat YYYY-MM-DD
103 | section Section
104 | A task :a1, 2014-01-01, 30d
105 | Another task :after a1 , 20d
106 | section Another
107 | Task in sec :2014-01-12 , 12d
108 | another task : 24d`,
109 | },
110 | {
111 | title: locale.pie,
112 | code: `pie title Pets adopted by volunteers
113 | "Dogs" : 386
114 | "Cats" : 85
115 | "Rats" : 15`,
116 | },
117 | {
118 | title: locale.mindmap,
119 | code: `mindmap
120 | Root
121 | A
122 | B
123 | C
124 | `,
125 | },
126 | {
127 | title: locale.timeline,
128 | code: `timeline
129 | title History of Social Media Platform
130 | 2002 : LinkedIn
131 | 2004 : Facebook
132 | : Google
133 | 2005 : Youtube
134 | 2006 : Twitter
135 | `,
136 | },
137 | ]
138 |
139 | return {
140 | viewerEffect({ markdownBody }) {
141 | ;(async () => {
142 | const els = markdownBody.querySelectorAll(
143 | 'pre>code.language-mermaid'
144 | )
145 | if (els.length === 0) return
146 |
147 | if (!m) {
148 | m = await import('mermaid').then((c) => c.default)
149 | if (mermaidConfig) {
150 | m.initialize(mermaidConfig)
151 | }
152 | }
153 |
154 | els.forEach((el, i) => {
155 | const pre = el.parentElement!
156 | const source = el.innerText
157 |
158 | const container = document.createElement('div')
159 | container.classList.add('bytemd-mermaid')
160 | container.style.lineHeight = 'initial' // reset line-height
161 | pre.replaceWith(container)
162 |
163 | m.render(
164 | `bytemd-mermaid-${Date.now()}-${i}`,
165 | source,
166 | // @ts-ignore
167 | container
168 | )
169 | .then((svgCode) => {
170 | // @ts-ignore
171 | container.innerHTML = svgCode.svg
172 | })
173 | .catch((err) => {
174 | // console.error(err);
175 | })
176 | })
177 | })()
178 | },
179 | actions: [
180 | {
181 | title: locale.mermaid,
182 | icon: icons.ChartGraph,
183 | cheatsheet: '```mermaid',
184 | handler: {
185 | type: 'dropdown',
186 | actions: actionItems.map(({ title, code }) => ({
187 | title,
188 | handler: {
189 | type: 'action',
190 | click({ editor, appendBlock, codemirror }) {
191 | const { line } = appendBlock('```mermaid\n' + code + '\n```')
192 | editor.setSelection(
193 | codemirror.Pos(line + 1, 0),
194 | codemirror.Pos(line + code.split('\n').length)
195 | )
196 | editor.focus()
197 | },
198 | },
199 | })),
200 | ...locale,
201 | },
202 | },
203 | ],
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/scripts/build.mjs:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { createVue3Plugin } from '../packages/vue-next/plugin.mjs'
3 | import { createVuePlugin } from '../packages/vue/plugin.mjs'
4 | import { packages, packagesDir, sveltePreprocessor } from './utils.mjs'
5 | import { svelte } from '@sveltejs/vite-plugin-svelte'
6 | import { execaCommand } from 'execa'
7 | import glob from 'fast-glob'
8 | import fs from 'fs-extra'
9 | import { camelCase } from 'lodash-es'
10 | import path from 'path'
11 | import resolve from 'resolve'
12 | import { emitDts } from 'svelte2tsx'
13 | import { preprocess } from 'svelte/compiler'
14 | import { build } from 'vite'
15 |
16 | ;(async () => {
17 | for (let name of packages) {
18 | console.log('[building]', name)
19 |
20 | const root = path.resolve(packagesDir, name)
21 | process.chdir(root)
22 |
23 | if (name === 'bytemd') {
24 | // some parts are from here https://github.com/sveltejs/kit/blob/master/packages/kit/src/packaging/typescript.js
25 | await emitDts({
26 | svelteShimsPath: 'node_modules/svelte2tsx/svelte-shims.d.ts',
27 | declarationDir: './dist',
28 | })
29 | glob.sync('./dist/src/*.svelte.d.ts').forEach((file) => {
30 | // console.log(file)
31 | fs.moveSync(file, file.replace('/src', ''))
32 | })
33 | fs.removeSync('./dist/src')
34 | }
35 |
36 | // build js
37 | const pkg = await fs.readJson(path.resolve(root, 'package.json'))
38 |
39 | for (let format of ['es', 'cjs', 'umd']) {
40 | const legacy = format === 'umd' || format === 'iife'
41 | const externalDeps = []
42 |
43 | if (legacy) {
44 | externalDeps.push(...Object.keys({ ...pkg.peerDependencies }))
45 | } else if (format === 'es') {
46 | externalDeps.push(
47 | ...Object.keys({
48 | ...pkg.peerDependencies,
49 | ...pkg.dependencies,
50 | })
51 | )
52 | } else if (format === 'cjs') {
53 | const deps = Object.keys({ ...pkg.dependencies })
54 | // exclude esm packages, bundle them to make it work for cjs
55 | .filter((dep) => {
56 | const pkgPath = path.resolve(
57 | root,
58 | 'node_modules',
59 | dep,
60 | 'package.json'
61 | )
62 |
63 | if (!fs.existsSync(pkgPath)) {
64 | throw new Error(`${dep} not exists, please install it`)
65 | }
66 |
67 | const { type: pkgType } = fs.readJsonSync(pkgPath)
68 | return pkgType !== 'module'
69 | })
70 |
71 | externalDeps.push(...Object.keys({ ...pkg.peerDependencies }), ...deps)
72 | }
73 |
74 | const alias = {
75 | // https://github.com/rollup/plugins/issues/1159
76 | // for plugin-highlight-ssr
77 | lowlight: 'lowlight/lib/common',
78 | }
79 |
80 | if (format === 'cjs') {
81 | const pkgName = 'decode-named-character-reference'
82 |
83 | // do not resolve `browser` field to make CJS bundle work at SSR
84 | // https://github.com/vitejs/vite/issues/4405
85 | // for bytemd and plugin-gfm
86 | alias[pkgName] = resolve.sync(pkgName)
87 | }
88 |
89 | await build({
90 | root,
91 | build: {
92 | emptyOutDir: false,
93 | minify: legacy,
94 | target: 'es2019', // nullish coalescing in es2020
95 | lib: {
96 | entry: 'src/index.ts',
97 | name: camelCase(pkg.name),
98 | formats: [format],
99 | fileName: 'index',
100 | },
101 | rollupOptions: {
102 | external: [
103 | ...externalDeps,
104 | ...externalDeps.map((dep) => new RegExp(`^${dep}\/`)),
105 | ],
106 | },
107 | },
108 | resolve: { alias },
109 | plugins: [
110 | name === 'bytemd' &&
111 | svelte({
112 | preprocess: [sveltePreprocessor],
113 | }),
114 | name === 'vue' && createVuePlugin(),
115 | name === 'vue-next' && createVue3Plugin(),
116 | ],
117 | })
118 | }
119 |
120 | if (name === 'bytemd') {
121 | await fs.emptyDir('svelte')
122 |
123 | console.log('build svelte files...')
124 | const files = await glob('src/*.svelte')
125 | for (let file of files) {
126 | const dest = file.replace('src/', 'svelte/')
127 | await fs.ensureDir(path.dirname(dest))
128 |
129 | if (fs.statSync(file).isDirectory()) return
130 |
131 | if (file.endsWith('.svelte')) {
132 | const source = await fs.readFile(file, 'utf8')
133 | const item = await preprocess(source, sveltePreprocessor, {
134 | filename: file,
135 | })
136 | await fs.writeFile(
137 | dest,
138 | item.code.replace('