Рендеринг списков

Библиотека Marked предоставляет мощные средства для преобразования Markdown-разметки в HTML. Одним из ключевых элементов Markdown являются списки, которые могут быть нумерованными и маркированными. Рассмотрим подробно, как Marked обрабатывает списки и какие возможности предоставляет для их кастомизации.


1. Маркированные списки

Маркированный список создаётся с использованием символов -, + или *. Marked автоматически распознаёт все три варианта как элементы одного списка. Пример Markdown:

- Элемент 1
- Элемент 2
- Элемент 3

После обработки через Marked результат будет следующим:

<ul>
  <li>Элемент 1</li>
  <li>Элемент 2</li>
  <li>Элемент 3</li>
</ul>

Ключевые моменты:

  • Все пробелы и отступы внутри списка учитываются для вложенных элементов.
  • Marked поддерживает вложенные списки с произвольным уровнем вложенности.
  • Можно использовать смешанные маркеры (-, *, +) в пределах одного списка, и это не нарушит разметку.

2. Нумерованные списки

Нумерованные списки создаются с использованием цифр с точкой:

1. Первый элемент
2. Второй элемент
3. Третий элемент

Результат:

<ol>
  <li>Первый элемент</li>
  <li>Второй элемент</li>
  <li>Третий элемент</li>
</ol>

Особенности обработки:

  • Порядок цифр в исходном Markdown не обязательно должен быть корректным. Marked корректно перестроит HTML, формируя последовательность <li> элементов.
  • Можно задавать начальное значение для <ol> с помощью атрибута start, например:
const markdown = "3. Третий элемент\n4. Четвёртый элемент";
const html = marked(markdown);

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


3. Вложенные списки

Markdown позволяет создавать списки внутри списков. Marked корректно поддерживает любую глубину вложенности. Пример:

- Элемент 1
  - Подэлемент 1.1
  - Подэлемент 1.2
- Элемент 2

HTML-результат:

<ul>
  <li>Элемент 1
    <ul>
      <li>Подэлемент 1.1</li>
      <li>Подэлемент 1.2</li>
    </ul>
  </li>
  <li>Элемент 2</li>
</ul>

Важные нюансы:

  • Отступы в Markdown критически важны. Каждый уровень вложенности должен иметь хотя бы два пробела (рекомендуется использовать 2–4 пробела).
  • Marked автоматически конвертирует вложенные списки в корректную HTML-структуру без необходимости дополнительного парсинга.

4. Настройка рендеринга списков

Marked предоставляет возможность переопределять стандартное поведение через объект renderer. Это особенно полезно, если требуется добавить кастомные CSS-классы или изменить структуру HTML.

Пример создания кастомного рендерера для списков:

const renderer = new marked.Renderer();

renderer.list = function(body, ordered) {
  if (ordered) {
    return `<ol class="custom-ol">${body}</ol>`;
  } else {
    return `<ul class="custom-ul">${body}</ul>`;
  }
};

const markdown = `
- Элемент A
- Элемент B
1. Первый
2. Второй
`;

const html = marked(markdown, { renderer });

Результат:

<ul class="custom-ul">
  <li>Элемент A</li>
  <li>Элемент B</li>
</ul>
<ol class="custom-ol">
  <li>Первый</li>
  <li>Второй</li>
</ol>

Преимущества кастомного рендерера:

  • Возможность добавлять атрибуты или классы к спискам.
  • Изменение обёртки элементов списка для внедрения дополнительных HTML-тегов.
  • Полная совместимость с вложенными списками.

5. Дополнительные возможности

  • Task-листы (чекбоксы): Marked поддерживает GitHub-style task lists:
- [x] Выполнено
- [ ] В процессе

Рендеринг:

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" checked> Выполнено</li>
  <li class="task-list-item"><input type="checkbox"> В процессе</li>
</ul>
  • Смешанные списки: можно комбинировать маркированные и нумерованные списки, а также включать текст и блоки кода внутри элементов.
  • Интерпретация пробелов и переносов: Marked корректно учитывает перенос строк между элементами, предотвращая ошибки при генерации HTML.

6. Практические рекомендации

  • Использовать единообразные маркеры для маркированных списков для удобства поддержки кода.
  • Для вложенных списков строго соблюдать пробельные отступы, чтобы избежать некорректной генерации HTML.
  • При необходимости кастомизации применять renderer.list и renderer.listitem для полной контроля над конечным HTML.
  • Task-листы лучше включать через опцию gfm: true при инициализации Marked для корректной поддержки чекбоксов.

Marked обеспечивает гибкий и мощный механизм рендеринга списков, включая вложенные, нумерованные, маркированные и task-листы, с возможностью полной кастомизации через рендерер. Это делает библиотеку удобным инструментом для генерации динамического и структурированного HTML из Markdown-разметки.