- PVSM.RU - https://www.pvsm.ru -

Позволяет работать одновременно в режиме WYSIWYG [1] и markdown [2] markup (с превью и cплитом).
Поддерживает большое количество блоков из коробки.
Позволяет дополнять функциональность — в режиме WYSIWYG есть extension system.
Создан для работы в React-приложениях.
Использует темизацию и компоненты из Gravity UI [3].
Полностью построен на опенсорс-технологиях (ProseMirror [4], CodeMirror [5], markdown-it [6], Diplodoc [7], Gravity UI [3]).
Соответствует стандарту CommonMark [8], поддерживает стандартный язык markdown и Yandex Flavored Markdown (YFM) [9].
Привет! Меня зовут Сергей Махнаткин, я работаю разработчиком в отделе User Experience в Yandex Cloud. В прошлом году мы писали о нашей дизайн‑системе и библиотеке компонентов Gravity UI [10]. С тех пор система не раз обновлялась и обрастала новыми функциями, и сегодня я хочу рассказать о новом инструменте — Markdown Editor, который значительно упрощает процесс работы с документацией.
Поговорим об истории создания пользовательского интерфейса, архитектурных особенностях и технических деталях интеграции и разработки собственных расширений, а потом — почему всё это доступно в опенсорсе.
Кстати, попробовать инструмент можно здесь:
Чтобы было удобно хранить и структурировать корпоративную информацию, мы разработали платформу Wiki [14], которая позволяет создавать базы знаний. Кроме базы знаний, мы развивали подходы к документации, такие как Docs as Code, где документация и код живут бок о бок в файловом хранилище (.md‑файлы). Так появилась платформа Diplodoс [7].
Wiki и Diplodoc объединяет то, что обе платформы работают с диалектом markdown — Yandex Flavored Markdown (YFM), который используется в Nebius, Bitrix, DoubleCloud, Mappable, Meteum.
Со временем мы заметили, что есть две группы пользователей, которые по‑разному представляют себе процесс создания и редактирования текста. Одни предпочитают сразу видеть финальный результат, работая с текстом, как в MS Word, Confluence или Notion. Другие доверяют только разметке и предпочитают оформлять страницы с помощью markdown. Известных библиотек, которые работают одновременно в режиме WYSIWYG/markdown, мы не нашли. Например, Notion — это только WYSIWYG, а в редакторах кода есть только markdown и режим превью.
Мы разработали markdown‑редактор, который может работать одновременно в двух режимах: визуальном (WYSIWYG) и режиме разметки (markdown). В первом режиме разметить текст помогают значки на панели, а во втором пользователи могут вручную редактировать markdown‑код. Кроме того, наше решение сохраняет документ как md‑файл, независимо от того, какой режим использовался при его создании.
Так выглядит визуальный редактор, в котором текст можно форматировать с помощью кнопок:

А так — режим разметки, в котором элементы форматирования обозначаются с помощью специальных символов:

Редактор соответствует стандарту CommonMark, поддерживает стандартный язык markdown и язык YFM. Также мы добавили возможность расширять синтаксис и другими диалектами markdown, например Github Flavored Markdown. При этом редактор позволяет переключаться из режима markup в режим WYSIWYG, а сам документ будет храниться как разметка md или расширенный md (например, в случае с YFM).
В редактор изначально вшито много расширений и настроек. Например, диаграммы Mermaid [15] и блоки HTML:


Мы старались сделать ядро редактора легкорасширяемым. Разработчики могут создать собственное расширение или дополнительную функциональность, которые помогут:
добавить новые сущности — блоки или текстовые модификаторы;
дополнительно конфигурировать парсер markdown;
добавить actions, которые позволяют работать с редактором извне;
обогатить функциональность интерфейса, например показывать меню доступных команд при вводе слеша;
модифицировать текущее поведение, например вставлять изображения и файлы и загружать их в хранилище.
Вот ряд примеров таких расширений, который мы разработали для нашей Wiki:
коллаборативный режим редактирования;

блок диаграмм draw.io [16];

плагин YandexGPT [17];


инклюды;

структура раздела;

секции для создания удобной сетки;

режим markdown с превью;

и множество других.

Разметка может преобразовываться автоматически. Если вы предпочитаете работать без мыши, в режиме визуального редактора предусмотрены специальные символы, позволяющие применять разметку прямо в тексте. Например, ** переводят текст в жирное начертание в режиме WYSIWYG. С помощью этих символов можно форматировать текст, создавать инлайновый и блочный код.
Также можно вызывать меню расширений, введя символ /.

Редактор позволяет сконфигурировать панель с инструментами для каждого проекта отдельно, но поставляется он с рядом готовых конфигураций — пресетов.
Редактор без пресетов:

Пресет CommonMark [18] обеспечивает поддержку стандартных элементов markdown: жирного шрифта, курсива, заголовков, списков, ссылок, цитат, блоков кода.

В пресете по умолчанию [19] также появляется перечёркнутый текст, а ещё таблица, в ячейках которой может быть только текст. Такой пресет соответствует стандартному markdown‑it.

Как было сказано выше, редактор поддерживает и YFM, поэтому отлично интегрируется с Diplodoc. В пресете YFM [20] появляются дополнительные элементы: прокачанные таблицы, вставка файлов и изображений, чекбоксы, кат, табы, моноширинный шрифт.

Полный пресет [21] содержит ещё больше элементов.

В основе редактора в режиме WYSIWYG лежит известная библиотека ProseMirror [22], а для разметки используется CodeMirror [5]. ProseMirror поддерживает редактирование с форматированием, тогда как CodeMirror подходит для ситуаций, где необходимо работать с неразмеченным текстом.
Мы выбрали именно эти библиотеки, потому что они разработаны одним автором, едины в архитектуре и подходах к реализации, поддерживаются большим комьюнити, используются во многих редакторах и хорошо оптимизированы для работы с текстом. Например, система транзакции для внесения изменений в документ, декорации для view, виртуализация DOM или поддержка синтаксиса множества языков программирования.
Наш редактор легко подключается как hook React [23]:
import React from 'react';
import {useMarkdownEditor, MarkdownEditorView} from '@gravity-ui/markdown-editor';
import {toaster} from '@gravity-ui/uikit/toaster-singleton-react-18';
function Editor({onSubmit}) {
const editor = useMarkdownEditor({allowHTML: false});
React.useEffect(() => {
function submitHandler() {
// Serialize current content to markdown markup
const value = editor.getValue();
onSubmit(value);
}
editor.on('submit', submitHandler);
return () => {
editor.off('submit', submitHandler);
};
}, [onSubmit]);
return <MarkdownEditorView stickyToolbar autofocus toaster={toaster} editor={editor} />;
}
Мы используем компоненты из библиотеки uikit GravityUI. Это гарантирует, что весь интерфейс будет консистентным и соответствовать единым стилевым гайдам. Использование этих компонентов также обеспечивает высокую степень согласованности и узнаваемости для пользователей, что делает работу с редактором ещё удобнее.
У нас есть подробные инструкции [24], как подключить редактор в приложение React, а также о том, как подключить разного рода расширения: например, YandexGPT [25], Mermaid [26] или LaTeX [27].
В редактор уже интегрирован ряд дополнительных расширений. Но если этого мало, то разработчики могут добавлять свои расширения в WYSIWYG‑режим редактора. О том, что могут дать расширения, мы говорили выше.
Если вы хотите добавить новый блок или текстовый модификатор, сначала нужно сконфигурировать внутренний экземпляр markdown‑it c помощью метода configureMd. Затем следует добавить знание о новой сущности с помощью методов addNode или addMark, передав имя сущности и колбэк‑функцию, которая возвращает объект с тремя обязательными полями:
import insPlugin from 'markdown-it-ins';
export const underlineMarkName = 'ins';
export const UnderlineSpecs: ExtensionAuto = (builder) => {
builder
.configureMd((md) => md.use(insPlugin))
.addMark(underlineMarkName, () => ({
spec: {
parseDOM: [{tag: 'ins'}, {tag: 'u'}],
toDOM() {
return ['ins'];
},
},
toMd: {open: '++', close: '++', mixable: true, expelEnclosingWhitespace: true},
fromMd: {tokenSpec: {name: underlineMarkName, type: 'mark'}},
}));
};
spec — спецификация для ProseMirror;
fromMd — конфигурация парсинга markdown‑разметки в представление внутри ProseMirror;
toMd — конфигурация для сериализации сущности в markdown‑разметку.
Например, ниже конфигурация расширения для подчёркнутого текста. Он может быть расширен добавлением action с помощью метода addAction:
import {toggleMark} from 'prosemirror-commands';
const undAction = 'underline';
builder
.addAction(undAction, ({schema}) => ({
isActive: (state) => Boolean(isMarkActive(state, markType)),
isEnable: toggleMark(underlineType(schema)),
run: toggleMark(underlineType(schema)),
})
)
Такой action может быть вызван в коде следующим образом:
// editor – инстанс редактора, полученный в результате вызова useMarkdownEditor
editor.actions.underline.run(),
В документации [28] можно посмотреть полную инструкцию по созданию нового расширения.
Мы постоянно расширяем горизонты использования нашего редактора: сейчас работаем над плагином для VS Code [29], который позволит работать с md‑файлами в удобном WYSIWYG‑режиме прямо из редактора. Ещё мы планируем добавить полнофункциональный мобильный режим. Это позволит каждому пользователю работать в нашем редакторе, имея под рукой только мобильный телефон.
Наш редактор не возник мгновенно: это результат накопления опыта и знаний. Мы гордимся, что редактор полностью базируется на опенсорс‑продуктах, включая надёжные и проверенные инструменты ProseMirror, CodeMirror, markdown‑it, а также наши собственные разработки — Diplodoc и Gravity UI.
Вы всегда можете внести свой вклад в развитие редактора: создать пул‑реквест [30] или помочь с решением текущих проблем, перечисленных в разделе Issues [31]. Ваша поддержка и свежий взгляд помогут нам сделать редактор лучше. А если вы считаете наш проект полезным — поставьте звезду на нашем репозитории в GitHub [32], это ценно :)
Автор: m_sergey
Источник [33]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/editor/398179
Ссылки в тексте:
[1] WYSIWYG: https://ru.wikipedia.org/wiki/WYSIWYG
[2] markdown: https://en.wikipedia.org/wiki/Markdown
[3] Gravity UI: https://gravity-ui.com/
[4] ProseMirror: https://prosemirror.net/
[5] CodeMirror: https://codemirror.net/
[6] markdown-it: https://github.com/markdown-it/markdown-it
[7] Diplodoc: https://diplodoc.com/
[8] CommonMark: https://spec.commonmark.org/
[9] Yandex Flavored Markdown (YFM): https://diplodoc.com/docs/ru/index-yfm
[10] дизайн‑системе и библиотеке компонентов Gravity UI: https://habr.com/ru/companies/yandex/articles/773870/
[11] Демо: https://gravity-ui.com/libraries/markdown-editor/playground
[12] Гитхаб: https://github.com/gravity-ui/markdown-editor/
[13] Storybook: https://preview.gravity-ui.com/md-editor/
[14] Wiki: https://wiki.yandex.ru/
[15] Mermaid: https://mermaid.js.org/
[16] draw.io: http://draw.io/
[17] YandexGPT: https://ya.ru/ai/gpt-3
[18] Пресет CommonMark: https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--common-mark
[19] пресете по умолчанию: https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--default
[20] пресете YFM: https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--yfm
[21] Полный пресет: https://preview.gravity-ui.com/md-editor/?path=/story/markdown-editor-presets--full
[22] ProseMirror: http://prosemirror.net/
[23] hook React: https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-add-editor-with-create-react-app.md
[24] инструкции: https://github.com/gravity-ui/markdown-editor/blob/main/README.md#getting-started
[25] YandexGPT: https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-gpt-extensions.md
[26] Mermaid: https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-mermaid-extension.md
[27] LaTeX: https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-connect-latex-extension.md
[28] В документации: https://github.com/gravity-ui/markdown-editor/blob/main/docs/how-to-create-extension.md
[29] VS Code: https://code.visualstudio.com/
[30] создать пул‑реквест: https://github.com/gravity-ui/markdown-editor/pulls
[31] Issues: https://github.com/gravity-ui/markdown-editor/issues
[32] репозитории в GitHub: https://github.com/gravity-ui/markdown-editor
[33] Источник: https://habr.com/ru/companies/yandex/articles/845802/?utm_source=habrahabr&utm_medium=rss&utm_campaign=845802
Нажмите здесь для печати.