Logo

Markdown редактор

Markdown редактор с визуализацией форматирования в реальном времени.

Редактор реализован в виде контрола под Cocoa (macOS) и появился как побочный для другого проекта, где необходимо много работы с текстом. В изначальном проекте стандартный системный WYSIWYG редактор был сразу отринут, а обычный слишком беден. Было решено реализовать поддержку markdown, тем более что он стал довольно привычен и в том или ином виде внедрен уже во многих популярных сервисах, от комментариев в блогах до комментариев на youtube, так что среднестатистический пользователь более-менее имеет о нём представление.

Изначально была попытка посмотреть на существующие решения с открытым кодом, но увы, ничего приличного не нашлось. Большей частью это решения которые позволяют лишь производить рендринг markdown документа в виде html, что совершенно не подходит для редактора (хотя и существует целый класс редакторов, где текст пишется в одной панели, а то, как он будет выглядеть отображается в соседней). Были и решения которые пытаются в визуализацию, но у всех это сделано довольно примитивно, например обнаружив строку представляющую заголовок, она лишь просто раскрашивается заданным цветом. Это получался типичный редактор с синтаксической подсветкой.

Данная же реализация скорее ближе к WYSIWYG редактору, форматирование хоть и осуществляется прямо в тексте, но управляющие символы могут, в том числе и скрываться.

В примере выше можно наблюдать как выглядит процесс работы с заголовком (в markdown это строка, которая начинается с символа решётки, а перед самим заголовком содержит пробел). Крайне некрасиво иметь в редакторе текст вроде ##### Заголовок, поэтому управляющие символы решётки скрываются и заменяются на иконку отображающую уровень заголовка. Иконка ведет себя как обычный символ, её можно стереть, либо поставив курсор рядом и введя символ решётки, автоматически увеличить уровень заголовка. А стоит удалить пробел между текстом и иконкой, как пользователь сразу увидит все символы.

Аналогично ведут себя разделители, например строка --- автоматически отображается как линия, а сами символы скрыты, хотя пользователь по-прежнему может перемещать курсор между ними.

Списки

Поддерживается работа со списками, они представлены в нескольких видах:

  • упорядоченные списки, при этом индексация осуществляется автоматически.
  • не упорядоченные списки (каждый уровень вложений имеет свой символ).
  • списки задач, где каждый элемент имеет разные состояния и их можно интерактивно переключать.

Цитаты

Поддержка цитат реализована в расширенном виде, кроме стандартного кода
> цитата так же анализируется возможное наличие подписи/авторства, визуально такой блок отличается от основного текста.

Так же поддерживаются сноски, это по сути разновидность цитат, только с заголовком и разных цветов. Определяются они по наличию в первой строке какого-либо эмодзи, что задаёт цвет сноски.

Данные

В режиме реального времени происходит поиск различных данных, будь то ссылка, адрес электронной почты, телефоны, адреса, даты, цвета. Имеется экспериментальная возможность определять места, имена, названия компаний. Такие данные ведут себя интерактивно, при клике на телефон, будет осуществлён звонок, по адресу - откроется карта и т.п.

Ссылки

Стандартные ссылки в markdown имеют формат [заголовок](ссылка). Поскольку непосредственно ссылка может быть длинной, вплоть до нескольких строк, при этом имеет заголовок, ссылка всегда скрывается чтобы не мешать пользователю.

При вставке ссылки из буфера обмена на выбор предлагается несколько способов вставки:

  • стандартная ссылка markdown.
  • как есть, в виде текста.
  • для ряда сервисов, как то youtube, возможно встроить непосредственно контент.

Встраивание контента реализовано в виде внедрения отдельного контрола в редактор представляющего собой html/js код. Для youtube это код загружающий плеер и предоставляющий собственное визуальное оформление и управление плеером. Таким образом поддержка различных сервисов легко расширяется.




Проект полностью написан на Objective-C, функционал в процессе расширения.