Введение
Vditor — это редактор Markdown на стороне браузера. Он поддерживает WYSIWYG, мгновенное отображение (аналогично Typora) и режим предварительного просмотра с разделённым экраном. Vditor реализован на TypeScript и поддерживает нативный JavaScript и такие фреймворки, как Vue, React, Angular и Svelte.
Добро пожаловать на официальный сайт Vditor (https://b3log.org/vditor), чтобы узнать больше.
Предыстория
С популяризацией методов набора текста в Markdown всё больше приложений начинают интегрировать редактор Markdown. Текущее состояние основных интегрируемых редакторов Markdown выглядит следующим образом:
Эти три пункта соответствуют трём сценариям применения:
Поэтому необходим редактор Markdown, который может адаптироваться к сценариям использования. Необходимо учитывать:
Vditor приложил усилия в этих областях, надеясь внести свой вклад в современную общую область редактирования Markdown.
Особенности
Поддержка трёх режимов редактирования: WYSIWYG (wysiwyg), мгновенный рендеринг (ir) и предварительный просмотр с разделённым экраном (sv).
Поддержка структуры, математических формул, mind-карт. Карты, диаграммы, блок-схемы, графики Ганта, временные шкалы, штатное расписание, мультимедиа, голосовое чтение, якорные заголовки, выделение и копирование кода, рендеринг Graphviz.
Экспорт, ленивая загрузка изображений, список задач, мультиплатформенный просмотр, переключение между темами, копирование в WeChat/Zhihu.
Реализация спецификаций CommonMark и GFM, просмотр форматирования и синтаксического дерева Markdown, поддержка более 10 конфигураций.
Панель инструментов содержит более 36 операций. Помимо поддержки расширения, можно настроить сочетания клавиш, всплывающие подсказки, позиции подсказок, значки, события кликов, имена классов и подпанели инструментов.
Расширение автозаполнения для эмодзи/@/# и т. д.
Можно использовать перетаскивание, вставку и вставку для загрузки, отображать прогресс загрузки в реальном времени, поддерживать междоменную загрузку CORS.
Сохранять контент в режиме реального времени для предотвращения случайной потери данных.
Поддержка записи, пользователи могут напрямую публиковать голосовые сообщения.
HTML-разметка автоматически преобразуется в Markdown, если вставка содержит изображения внешних ссылок, их можно загрузить на сервер через указанный интерфейс.
Поддерживается изменение размера главного окна с помощью перетаскивания, подсчёт символов.
Многотемный режим, встроенные чёрная, белая и зелёная темы.
Мультиязычная поддержка, встроенная локализация китайского, английского и корейского текста.
Поддержка основных браузеров, адаптация к мобильным устройствам.
Режимы редактирования:
WYSIWYG — более дружественный к пользователям, которые не знакомы с Markdown, и вы можете использовать его без проблем, если знакомы с Markdown.
Instant Rendering — не должен быть незнакомым для пользователей, знакомых с Typora. Теоретически это самый элегантный способ редактирования Markdown.
Split View — традиционный режим Split View подходит для редактирования Markdown на большом экране.
Поддержка синтаксиса:
Весь синтаксис CommonMark: тематические разрывы, заголовки ATX, заголовки Setext, блоки кода с отступом, блоки кода с ограждением, блоки HTML, определения ссылок на ссылки, абзацы, блочные кавычки, списки, обратные косые черты, ссылки на сущности и числовые символы, диапазоны кода, акценты и сильные акценты, ссылки, изображения, необработанный HTML, жёсткие и мягкие переносы строк, текстовое содержимое.
Весь синтаксис GFM: таблицы, элементы списка задач, зачёркивание, автоссылки, фильтрация XSS.
Общий расширенный синтаксис Markdown: сноски, оглавление, пользовательские идентификаторы заголовков.
Синтаксис диаграмм:
Stave поддерживается abc.js.
Математические формулы: блоки математических формул, математические формулы на уровне строк поддерживаются MathJax и KaTeX.
YAML Front Matter.
Оптимизация китайского контекста:
Большинство вышеперечисленных функций можно включить или отключить с помощью конфигурации переключателя, разработчики могут выбрать соответствие в соответствии со своими сценариями применения.
Примеры использования:
Sym — современная платформа сообщества (форум/BBS/SNS/блог), реализованная на Java.
Solo и Pipe — распределённый узел блога B3log, добро пожаловать в сеть сообществ следующего поколения.
Arya — онлайн-редактор Markdown на основе Vue, Vditor.
Другие примеры. Установить зависимости
npm install vditor --save
import Vditor from 'vditor'
import "~vditor/src/assets/less/index" // Или использовать dark
const vditor = new Vditor(id, {options...})
<!-- ⚠️Пожалуйста, укажите номер версии в рабочей среде, например, https://unpkg.com/vditor@x.x.x/dist... -->
<link rel="stylesheet" href="https://unpkg.com/vditor/dist/index.css" />
<script src="https://unpkg.com/vditor/dist/index.min.js"></script>
class="vditor-reset"
(классическая тема) или class="vditor-reset vditor-reset--dark"
(чёрная тема) к элементу отображения содержимого может сделать отображение содержимого более дружелюбнымМожет быть заполнен элементом id
или самим элементом HTMLElement
⚠️: При заполнении элемента HTMLElement
, необходимо установить options.cache.id
или установить options.cache.enable
в значение false
Объяснение | По умолчанию | |
---|---|---|
i18n | I18n, подробнее см. ITips | - |
undoDelay | Интервал отмены | - |
after | Метод обратного вызова после асинхронного рендеринга редактора завершён | - |
height | Общая высота редактора | 'auto' |
minHeight | Минимальная высота области редактирования | - |
width | Общая ширина редактора, поддерживает % | 'auto' |
placeholder | Советы при пустом поле ввода | '' |
lang | Тип I18n: en_US, fr_FR, pt_BR, ja_JP, ko_KR, ru_RU, sv_SE, zh_CN, zh_TW | 'zh_CN' |
input | Триггер после ввода (значение: строка) | - |
focus | Триггер после фокусировки (значение: строка) | - |
blur | Триггер после потери фокуса (значение: строка) | - |
keydown(event: KeyboardEvent) | Триггер после нажатия клавиши | - |
esc | Триггер после нажатия esc (значение: строка) | - |
ctrlEnter | Триггер после нажатия ⌘/ctrl+enter (значение: строка) | - |
select | Срабатывает после выделения текста в редакторе (значение: строка) | - |
tab | Операция с клавишей tab, поддержка \ t и любой строки |
- |
typewriterMode | Включить ли режим машинистки | false |
cdn | Настроить адрес собственной сборки CDN | https://unpkg.com/vditor@${VDITOR_VERSION} |
mode | Режим редактирования: sv, ir, wysiwyg | 'ir' |
debugger | Отображать ли журнал | false |
value | Значение инициализации редактора | '' |
theme | Тема: classic, dark | 'classic' |
icon | Тема иконок: ant, material | 'ant' |
customRenders: {language: string, render: (element: HTMLElement, vditor: IVditor) => void}[] | Пользовательский рендер | [] |
toolbar: ['emoji', 'br', 'bold', '|', 'line']
. См. по умолчанию src/ts/util/Options.ts
emoji
, headings
, bold
, italic
, strike
, |
, line
, quote
, list
, ordered-list
, check
,outdent
,indent
, code
, inline-code
, insert-after
, insert-before
, code-theme
, content-theme
, export
, undo
, redo
, upload
, link
, table
, record
, edit-mode
, both
, preview
, fullscreen
, outline
, devtools
, info
, help
, br
name
не входит в перечисление, вы можете добавить пользовательскую кнопку в следующем формате:new Vditor('vditor', ```
{
toolbar: [
{
hotkey: '⇧⌘S',
name: 'sponsor',
tipPosition: 's',
tip: 'Стать спонсором',
className: 'right',
icon: '<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2808" width="32" height="32"><path d="M506.6 423.6m-29.8 0a29.8 29.8 0 1 0 59.6 0 29.8 29.8 0 1 0-59.6 0Z" fill="#0F0F0F" p-id="2809"></path><path d="M717.8 114.5c-83.5 0-158.4 65.4-211.2 122-52.7-56.6-127.7-122-211.2-122-159.5 0-273.9 129.3-273.9 288.9C21.5 562.9 429.3 913 506.6 913s485.1-350.1 485.1-509.7c0.1-159.5-114.4-288.8-273.9-288.8z" fill="#FAFCFB" p-id="2810"></path><path d="M506.6 926c-22 0-61-20.1-116-59.6-51.5-37-109.9-86.4-164.6-139-65.4-63-217.5-220.6-217.5-324 0-81.4 28.6-157.1 80.6-213.1 53.2-57.2 126.4-88.8 206.3-88.8 40 0 81.8 14.1 124.2 41.9 28.1 18.4 56.6 42.8 86.9 74.2 30.3-31.5 58.9-55.8 86.9-74.2 42.5-27.8 84.3-41.9 124.2-41.9 79.9 0 153.2 31.5 206.3 88.8 52 56 80.6 131.7 80.6 213.1 0 103.4-152.1 261-217.5 324-54.6 52.6-113.1 102-164.6 139-54.8 39.5-93.8 59.6-115.8 59.6zM295.4 127.5c-72.6 0-139.1 28.6-187.3 80.4-47.5 51.2-73.7 120.6-73.7 195.4 0 64.8 78.3 178.9 209.6 305.3 53.8 51.8 111.2 100.3 161.7 136.6 56.1 40.4 88.9 54.8 100.9 54.8s44.7-14.4 100.9-54.8c50.5-36.3 108-84.9 161.7-136.6 131.2-126.4 209.6-240.5 209.6-305.3 0-74.9-26.2-144.2-73.7-195.4-48.2-51.9-114.7-80.4-187.3-80.4-61.8 0-127.8 38.5-201.7 117.9-2.5 2.6-5.9 4.1-9.5 4.1s-7.1-1.5-9.5-4.1C423.2 166 357.2 127.5 295.4 127.5z" fill="#141414" p-id="2811"></path><path d="M353.9 415.6m-33.8 0a33.8 33.8 0 1 0 67.6 0 33.8 33.8 0 1 0-67.6 0Z" fill="#0F0F0F" p-id="2812"></path><path d="M659.3 415.6m-33.8 0a33.8 33.8 0 1 0 67.6 0 33.8 33.8 0 1 0-67.6 0Z" fill="#0F0F0F" p-id="2813"></path><path d="M411.6 538.5c0 52.3 42.8 95 95 95 52.3 0 95-42.8 95-95v-31.7h-190v31.7z" fill="#5B5143" p-id="2814"></path><path d="M506.6 646.5c-59.6 0-108-48.5-108-108v-31.7c0-7.2 5.8-13 13-13h190.1c7.2 0 13 5.8 13 13v31.7c0 59.5-48.5 108-108.1 108z m-82-126.7v18.7c0 45.2 36.8 82 82 82s82-36.8 82-82v-18.7h-164z" fill="#141414" p-id="2815"></path><path d="M450.4 578.9a54.7 27.5 0 1 0 109.4 0 54.7 27.5 0 1 0-109.4 0Z" fill="#EA64F9" p-id="2816"></path><path d="M256 502.7a32.1 27.5 0 1 0 64.2 0 32.1 27.5 0 1 0-64.2 0Z" fill="#EFAFF9" p-id="2817"></path><path d="M703.3 502.7a32.1 27.5 0 1 0 64.2 0 32.1 27.5 0 1 0-64.2 0Z" fill="#EFAFF9" p-id="2818"></path></svg>',
click () {alert('Пожертвовать: https://ld246.com/sponsor')},
}],
}
``` | scroll(top: number) | Прокрутка | - |
| --- | --- | --- |
| adjustTop(commentsData: ICommentsData[]) | Настройка высоты комментария | - |
#### options.preview
| | Объяснение | По умолчанию |
| - | - | - |
| delay | Интервал миллисекунд для устранения дребезга предварительного просмотра | 1000 |
| maxWidth | Максимальная ширина области предварительного просмотра | 800 |
| mode | Режим отображения: оба, редактор | «оба» |
| url | Запрос на анализ MD | - |
| parse | Предварительный просмотр обратного вызова (элемент: HTMLElement) | - |
| transform | Обратный вызов перед рендерингом (html: строка): строка | - |
#### options.preview.theme
| | Объяснение | По умолчанию |
| - | - | - |
| current | Текущая тема Markdown | «светлая» |
| list | Выбор списка тем Markdown | { «ant-design»: «Ant Design», тёмная: «Dark», светлая: «Light», wechat: «WeChat» } |
| path | Путь CSS | `https://unpkg.com/vditor@${VDITOR_VERSION}/dist/css/content-theme` |
#### options.preview.hljs
| | Объяснение | По умолчанию |
| - | - | - |
| defaultLang | Язык, который используется по умолчанию, когда язык не указан | '' |
| enable | Включать ли подсветку синтаксиса кода | true |
| style | Для необязательных значений см. [Chroma](https://xyproto.github.io/splash/docs/longer/all.html) | `github` |
| lineNumber | Включать ли номера строк | false |
| langs | Пользовательские языки | [CODE_LANGUAGES](https://github.com/Vanessa219/vditor/blob/53ca8f9a0e511b37b5dae7c6b15eb933e9e02ccd/src/ts/constants.ts#L20) |
| renderMenu(code: HTMLElement, copy: HTMLElement) | кнопка рендеринга меню | - |
#### options.preview.markdown
| | Объяснение | По умолчанию |
| - | - | - |
| autoSpace | Автопробел | false |
| gfmAutoLink | Автоматическая ссылка | true |
| fixTermTypo | Автоматическая коррекция терминологии | false |
| toc | Вставить оглавление | false |
| footnotes | Сноски | true |
| codeBlockPreview | Рендерить ли блоки кода в режимах wysiwyg и ir | true |
| mathBlockPreview | Рендерить ли математические блоки в режимах wysiwyg и ir | true |
| paragraphBeginningSpace | Два пробела перед абзацем | false |
| sanitize | Использовать XSS | true |
| listStyle | Добавить атрибут data-style | false |
| linkBase | Префикс относительного пути ссылки | '' |
| linkPrefix | Префикс ссылки | '' |
| mark | Включить тег mark | false |
#### options.preview.math
| | Объяснение | По умолчанию |
| - | - | - |
| inlineDigit | Разрешены ли числа после встроенной математической формулы, начинающейся с $ | false |
| macros | Определение макроса, передаваемое при рендеринге с помощью MathJax | {} |
| engine | Механизм рендеринга математических формул: KaTeX, MathJax | 'KaTeX' |
| mathJaxOptions | Параметры, когда механизм рендеринга математической формулы — MathJax | - |
#### options.preview.actions
По умолчанию: [«рабочий стол», «планшет», «мобильный», «mp-wechat», «zhihu»]
| | Объяснение | По умолчанию |
| - | - | - |
| key | Идентификатор пользовательского действия, не пустой | - |
| tooltip | Подсказка | - |
| text | Текст кнопки | - |
| className | Класс кнопки | - |
| click(key: string) | Событие клика | - |
#### options.preview.render.media
| | Объяснение | По умолчанию |
|--------|-----------|------|
| enable | Включить ли рендеринг мультимедиа | true |
#### options.image
| | Объяснение | По умолчанию |
| - | - | - |
| isPreview | Включить ли предварительный просмотр изображения | true |
| preview(bom: Element) => void | Обработка предварительного просмотра изображения | - |
#### options.link
| | Объяснение | По умолчанию |
| - | - | - |
| isOpen | Открыть ли адрес ссылки | true |
| click(bom: Element) => void | Событие щелчка по ссылке | - |
#### options.hint
| | Объяснение | По умолчанию |
| - | - | - |
| parse | Выполнять ли анализ md | true |
| delay | Интервал устранения дребезга подсказки в миллисекундах | 200 |
| emoji | Можно выбрать эмодзи по умолчанию из [lute/emoji_map](https://github.com/88250/lute/blob/master/parse/emoji_map.go), или можно настроить | { '+1': '👍', '-1': '👎', 'heart': '❤️', 'cold_sweat': '😰' } |
| emojiTail | Общие эмодзи | - |
| emojiPath | Путь к эмодзи | `https://unpkg.com/vditor@${VDITOR_VERSION}/dist/images/emoji` |
| extend: IHintExtend[] | @/# и другое автоматическое расширение ключевых слов | [] | **hint?(value: string): IHintData[] | Promise<IHintData[]>;**
#### options.upload
* Структура данных файла загрузки выглядит следующим образом. Если структура данных, возвращённая бэкэндом, не согласована, вы можете использовать `format` для преобразования.
```js
// POST data
xhr.send(formData); // formData = FormData.append("file[]", File)
// return data
{
"msg": "",
"code": 0,
"data": {
"errFiles": ['filename', 'filename2'],
"succMap": {
"filename3": "filepath3",
"filename4": "filepath4"
}
}
}
linkToImgUrl
может передавать адреса изображений вне станции в буфер обмена для сохранения и обработки на сервере. Структура данных выглядит следующим образом:// POST data
xhr.send(JSON.stringify({url: src})); // src — это адрес изображения вне станции
// return data
{
msg: '',
code: 0,
data : {
originalURL: '',
url: ''
}
}
Объяснение | По умолчанию | |
---|---|---|
url | URL загрузки, пустой не вызовет событий, связанных с загрузкой | '' |
max | Максимальный размер загружаемого файла в байтах | 10 * 1024 * 1024 |
linkToImgUrl | При наличии адреса изображения в буфере обмена используйте этот URL для повторной загрузки | '' |
linkToImgCallback | Обратный вызов при загрузке адреса изображения | — |
linkToImgFormat | Преобразует данные, возвращаемые сервером, в соответствии со встроенной структурой данных (responseText: string): string | — |
success | Обратный вызов успеха загрузки (editor: HTMLPreElement, msg: string) | — |
error | Обратный вызов сбоя загрузки (msg: string) | — |
token | Проверка загрузки CORS, заголовок — X-Upload-Token | — |
withCredentials | Контроль доступа между сайтами | false |
headers | Настройки заголовка запроса | — |
filename | Очистка имён файлов (name: string): string | name => name.replace(/\W/g, '') | |
accept | Тип загрузки файла, такой же, как input accept | — |
validate | Проверить, вернуть true в случае успеха, иначе вернуть сообщение об ошибке (files: File[]) => string | boolean | — |
handler(files: File[]) => string | null | Promise | Promise | Пользовательская загрузка, возвращает сообщение об ошибке при возникновении ошибки | — |
format | Преобразовать данные, возвращаемые сервером, чтобы они соответствовали встроенной структуре данных (files: File[], responseText: string): string | — |
file(files: File[]): File[] | Promise<File[]> | Обработать загруженный файл перед возвратом. | — |
setHeaders | Использовать возвращаемое значение для установки заголовка перед загрузкой (): {[key: string]: string} | — |
extraData | Добавить данные в FormData {[key: string]: string | Blob} |
multiple | Разрешить загрузку нескольких файлов | true |
fieldName | Ключ имени поля | file[] |
Объяснение | По умолчанию | |
---|---|---|
enable | Поддерживает ли изменение размера | false |
position | Положение столбца перетаскивания: «top», «bottom» | «bottom» |
after | Обратный вызов после завершения перетаскивания (height: number) | — |
Объяснение | По умолчанию | |
---|---|---|
preview | Предварительный просмотр className элемента | '' |
Объяснение | По умолчанию | |
---|---|---|
index | Индекс полноэкранного режима | 90 |
Объяснение | По умолчанию | |
---|---|---|
enable | Инициализировать, показывать ли контур | false |
position | Расположение контура: «left», «right» | «left» |
Объяснение | |
---|---|
exportJSON(markdown: string) | Получить JSON по markdown |
getValue() | Получить содержимое редактора |
getHTML() | Получить содержимое области предварительного просмотра |
insertValue(value: string, render = true) | Вставить контент в фокус и рендеринг уценки по умолчанию |
focus() | Сфокусироваться на редакторе |
blur() | Сделать редактор не в фокусе |
disabled() | Отключить редактор |
enable() | Включить редактор |
getSelection(): string | Возвращает выбранную строку |
setValue(markdown: string, clearStack = false) | Установить содержимое редактора |
clearStack() | Удалить стек отмены и повтора |
renderPreview(value?: string) | Установить содержимое области предварительного просмотра |
getCursorPosition():{top: number, left: number} | Получить позицию фокуса |
deleteValue() | Удалить |
- | - |
updateValue(value: string) | Обновить выбранное содержимое |
isUploading() | Проверка, продолжается ли загрузка |
clearCache() | Очистить кэш |
disabledCache() | Отключить кэш |
enableCache() | Включить кэширование |
html2md(value: string) | Преобразование HTML в Markdown |
tip(text: string, time: number) | Уведомление. Если время равно 0, то будет отображаться всегда |
setPreviewMode(mode: "both" | "editor") | Установить режим предварительного просмотра |
setTheme(theme: "dark" | "classic", contentTheme?: string, codeTheme?: string, contentThemePath?: string) |
getCurrentMode(): string | Получить текущий режим редактирования редактора |
destroy() | Уничтожить vditor |
getCommentIds(): {id: string, top: number}[] | Получить все комментарии |
hlCommentIds(ids: string[]) | Выделить комментарий по идентификаторам |
unHlCommentIds(ids: string[]) | Отменить выделение комментария по идентификаторам |
removeCommentIds(removeIds: string[]) | Удалить комментарий по идентификатору |
updateToolbarConfig(config: {hide?: boolean, pin?: boolean}) | Обновить конфигурацию панели инструментов |
method.min.js
и напрямую вызовите:Vditor.mermaidRender(document)
import VditorPreview from 'vditor/dist/method.min'
VditorPreview.mermaidRender(document)
preview
со следующими параметрами:previewElement: HTMLDivElement, // Используйте этот элемент для рендеринга
markdown: string, // Исходный Markdown для рендеринга
options?: IPreviewOptions {
mode: "dark" | "light";
anchor?: number; // 0: не рендерить, 1: рендерить слева, 2: рендерить справа
customEmoji?: { [key: string]: string }; // Пользовательский эмодзи, по умолчанию {}
lang?: (keyof II18nLang); // Язык, по умолчанию 'zh_CN'
emojiPath?: string; // Путь к изображению эмодзи
hljs?: IHljs; // См. параметры.preview.hljs
speech?: { // Чтение выбранного содержимого
enable?: boolean,
};
math?: IMath; // Конфигурация рендеринга математической формулы
transform?(html: string): string; // Обратный вызов перед рендерингом
after?(); // Обратный вызов после рендеринга
cdn?: string; // Собственный адрес CDN
lazyLoadImage?: string; // Используйте «https://unpkg.com/vditor/dist/images/img-loading.svg» для отложенной загрузки изображения
markdown?: options.preview.markdown;
render?: options.preview.render;
renderers?: ILuteRender; // Пользовательский метод рендеринга https://ld246.com/article/1588412297062
}
method.min.js
и index.min.js
нельзя вводить одновременноОбъяснение | |
---|---|
previewImage(oldImgElement: HTMLImageElement, lang: keyof II18n = "zh_CN", theme = "classic") | Предварительный просмотр при нажатии на изображение |
mermaidRender(element: HTMLElement, cdn = options.cdn, theme = options.theme) | Рендеринг flowchart/sequence diagram/gantt diagram |
flowchartRender(element: HTMLElement, cdn = options.cdn) | Рендеринг flowchart.js |
codeRender(element: HTMLElement, option?: IHljs) | Добавить кнопку копирования для блока кода в элементе |
chartRender(element: (HTMLElement| Document) = document, cdn = options.cdn, theme = options.theme) | Рендеринг диаграммы |
plantumlRender(element: (HTMLElement| Document) = document, cdn = options.cdn) | Рендеринг plantuml |
abcRender(element: (HTMLElement| Document) = document, cdn = options.cdn) | Рендеринг нотной записи |
outlineRender(contentElement: HTMLElement, targetElement: Element, vditor?: IVditor) | Рендеринг структуры |
md2html(mdText: string, options?: IPreviewOptions): Promise<string> | Преобразование текста Markdown в HTML, для этого метода необходимо использовать асинхронное программирование |
preview(previewElement: HTMLDivElement, markdown: string, options?: IPreviewOptions) | Рендеринг статьи Markdown на страницу |
highlightRender(hljsOption?: IHljs, element?: HTMLElement | Document, cdn = options.cdn) | Подсветка блока кода в элементе |
mediaRender(element: HTMLElement) | Рендеринг как специфическая ссылка как видео, аудио, встроенный iframe |
npm install
.npm run start
, чтобы запустить локальный сервер, откройте http://localhost:9000.npm run build
, чтобы упаковать код в каталог dist.Благодаря механизму загрузки по запросу, по умолчанию используется CDN https://unpkg.com/vditor@номер версии. Если вы изменили код или вам нужно использовать собственный CDN, следуйте инструкциям ниже:
options
и IPreviewOptions
необходимо добавить конфигурацию cdn
.highlightRender
, mathRender
, abcRender
, chartRender
и mermaidRender
должны иметь параметр cdn
.При обновлении версии внимательно прочитайте CHANGELOG.
Vditor использует открытую лицензию MIT.
На начальном этапе разработки Sym мы напрямую использовали WYSIWYG-редактор с расширенным текстом. В то время HTML-редакторы были очень популярны, и было очень удобно цитировать их в проекте, что также соответствовало привычкам пользователей того времени. Позже появление Markdown постепенно изменило типографику всех. Кроме того, некоторые из наших других проектов предназначены для программистов, поэтому переход на md также является общей тенденцией. Мы выбрали CodeMirror, отличный редактор, который предоставляет богатый программный интерфейс для разработчиков и совместим с различными браузерами. Это хорошо. Позже, когда бизнес-потребности наших проектов обострились, использование CodeMirror иногда казалось более «громоздким». Например, для реализации автоматического завершения списка имён пользователей, вставки эмодзи, загрузки...
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )