javascript-parser

Parser for the extended markdown format used at javascript.ru

Парсер для JavaScript.ru

Парсер для адаптированного формата Markdown, который используется на Javascript.ru.

У него есть два режима работы:

  1. Доверенный -- для статей, задач и другого основного материала. Возможны любые теги и т.п.
  2. Безопасный -- для комментариев и другого user-generated content. Большинство тегов HTML можно использовать.

Блок кода вставляется как в github:

```js
alert(1);
```

Или:

```html
<!DOCTYPE HTML>
<title>Viva la HTML5!</title>
```

Поддерживаемые языки (список может быть расширен):

  • html
  • js
  • css
  • coffee
  • php
  • http
  • java
  • ruby
  • scss
  • sql

Если хочется, чтобы посетитель мог запустить код -- добавьте первую строку //+ run:

```js
//+ run
alert(1);
```

Независимо от языка можно использовать любой стиль комментария: //+ ..., /*+ ... */, #+ ... или <!--+ ... -->, главное чтобы он был первой строкой и в начале был плюс и пробел. Этот комментарий не попадёт в итоговый вывод.

Есть два языка, для которых это поддерживается:

  1. js - в доверенном режиме через eval, в безопасном -- в iframe с другого домена.
  2. html - в доверенном режиме показ будет в iframe с того же домена, в безопасном -- с другого домена.

Прочие настройки, возможные в этой же строке:

  • height=100 -- высота (в пикселях) для iframe, в котором будет выполняться пример. Обычно для HTML она вычисляется автоматически по содержимому.
  • src="my.js" -- код будет взят из файла my.js
  • autorun -- пример будет запущен автоматически по загрузке страницы.
  • refresh -- каждый запуск JS-кода будет осуществлён в "чистом" окружении. Этот флаг актуален только для безопасного режима, т.к. обычно iframe с другого домена кешируется и используется многократно.
  • demo - флаг актуален только для решений задач, он означает, что при нажатии на кнопку "Демо" в условии запустится этот код.

Пример ниже возьмёт код из файла my.js и запускает его автоматически:

```js
//+ src="my.js" autorun
```

Этот пример будет при запуске показан в <iframe> высотой 100px:

```html
<!-- run height=100 -->
<!DOCTYPE HTML>
<html>
<body>
  <h1>Привет, мир!</h1>
</body>
</html>
```

Поддерживаются два выделения:

Блочное выделение -- несколько строк выделяются полностью.

Обозначается строками *!* в начале и */!* в конце:

```js
*!*
function important() {
  alert("Важный блок");
}
*/!*
```

Также можно выделить отдельную строку (одну), поставив в конце *!*:

```js
function important() {
  alert("Важная строка");*!*
}
```

Инлайн-выделение выделяет фрагмент текста, например важное слово, для этого оно заключается в *!*...*/!*:

```css
*!*h1*/!* {
  background: pink *!*important*/!*;
}
```

В примере выше выделятся h1 и important.

Для вставки кода в строку он оборачивается в обратные кавычки `...`.

Например:

Функция `_.partial` делает то же, что и `bind`, но без привязки контекста `this`.

Весь HTML внутри таких кавычек автоматически экранируется и оборачивается в <code>:

Теги `<script>` и `<b>`
-- станет
Теги <code>&lt;script&gt;</code> и <code>&lt;b&gt;</code>

Обычно это удобно, но если экранирование не нужно -- можно использовать HTML-тег <code>...</code> напрямую:

Функция <code>reduce<em>Right</em></code>

После открывающей и перед закрывающей обратными кавычками ` не должно быть пробелов, такой текст не будет отформатирован:

От ` до `

Это позволяет избежать неверных интерпретаций в тексте. Если нужно вставить именно саму обратную кавычку, а она воспринимается как код - используйте Unicode-entity: &#96;.

Во-первых, заметим, что любой js/html-код можно сделать запускаемым, добавив в начало //+ run.

При этом HTML будет при запуске показываться в <iframe> снизу. Можно даже добавить autorun для автозапуска при загрузке страницы.

ББ-теги, описанные ниже, дают альтернативные способы показа примера.

Для того, чтобы они работали, пример должен быть в отдельной директории без поддиректорий, выложенной как plunk при помощи утилиты https://github.com/iliakan/plunk. Кроме того, в примере должен быть файл index.html.

ББ-тег [iframe] позволяет показать пример в действии в <iframe>'е с минимальными "декорациями".

Например:

[iframe src="cool-stuff"]

Покажет пример cool-stuff/index.html, без кода.

Параметры:

  • height=100 -- высота (если автовычисленная не подходит)
  • link -- добавить в ифрейм ссылку для открытия в новом окне
  • play -- добавить в ифрейм ссылку для открытия в песочнице
  • zip -- добавить в ифрейм ссылку на скачивание архива с примером

Обычно чистый [iframe src="..."] используется для показа "как работает" пример без возможности залезть в код, например в качестве демки для задачи.

Если пример содержит несколько важных файлов -- его можно показать через [example].

Это то же самое, что [iframe], но дополнительно над <iframe>'ом будет лента с табами файлов примера. Любой файл можно выбрать и посмотреть.

Например:

[example src="cool-stuff"]

Для показа списка достоинств/недостатков:

[compare]
+ WebSocket'ы дают минимальную задержку в передаче данных
+ WebSocket'ы позволяют непрерывно передавать данные в обе стороны
- Не поддерживаются в IE<10
[/compare]

У достоинств в начале должен стоять плюс +, у недостатков минус -, строки без ± недопустимы.

Ссылки можно задавать вместо <a href="http://wikipedia.org">Википедия</a> вот так:

[Википедия](http://wikipedia.org)

Для показа ссылки без особого заголовка:

[http://wikipedia.org]()
-- станет
<a href="http://wikipedia.org">http://wikipedia.org</a>

Для ссылки на статью или задачу с сайта можно использовать только её абсолютный URL, заголовок подставится автоматически, например:

Читайте об этом в главе [](/events)
-- станет (из базы будет получен заголовок)
Читайте об этом в главе <a href="/events">События</a> 

Для того, чтобы сослаться на заголовок, у которого есть [#anchor]:

[Оператор `instanceof`](#instanceof)
-- станет (если есть статья с заголовокм [#instanceof])
<a href="/url-этой-статьи#instanceof">Оператор <code>instanceof</code></a>

Не применяется форматирование в HTML-комментариях <!-- ... --> и тегах:

  • <script> <style> <object> <embed> <video> <audio> <pre>

Также форматирование не будет применяться, если обернуть секцию в [pre]...[/pre]:

[pre]
В этом блоке.

Новые строки.

Не переносятся. И вообще, парсер не работает, просто обычный HTML. [/pre]

Заголовки начинаются с символа решётки #, сколько решёток -- такой и уровень.

На любой заголовок можно сделать общесайтовую ссылку, добавив к нему [#anchor], где anchor -- имя для <a name="...">, в который заголовок обёрнут.

Это имя также запоминается в базе и далее в любой другой статье или задаче можно просто использовать ссылку [читайте тут](#anchor) для отправки посетителя сразу на нужный заголовок.

Как в обычном Markdown:

**жирный**
*курсив*
~перечёркивание~

Выделение в середине слова не работает.

  • Перед открывающим символом должен быть пробел, а после -- нет.
  • После закрывающего символа должен быть побел или пунктуация, а перед -- нет пробела

Например:

Мой *красивый* текст -- выделение сработает
*Мой красивый текст* -- выделение сработает
Мой*красивый*текст -- выделение не сработает (внутри слова)
a * b * c -- выделение не сработает (пробелы вокруг *)

Автоматически заменяются:

  • (c) (r) (tm) (p) +- -> <- на символы © ® ±
  • троеточие ... на один юникодный символ-троеточие
  • одиночный дефис - на юникодный символ-аналог &ndash;, двойной дефис -- на длинное тире &mdash;
  • смайлы :) :( и ряд других - на картинки <img src="файл для смайла">
  • кавычки "..." - на ёлочки «...»

Двойной (или более) перевод строки означает параграф <p>.

Не ставятся <p> между блочными тегами, например в таком тексте параграфа между <div> и <table> не будет:

<div> ... </div>

<table> ... </table>

Для красивого отображения сочетаний клавиш используется бб-тег [key Ctrl+Shift+P].

Если нужны одна или несколько библиотек -- перечислите их построчно в секции [libs].

Например:

[libs]
http://code.jquery.com/jquery-latest.js
http://code.jquery.com/ui/1.10.4/jquery-ui.js
http://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css
[/libs]

Все они попадут в <head>, CSS будут до скриптов.

Можно перечислить не полные скрипты, а мнемо-имена, сейчас поддерживается только d3:

[libs]
d3  
[/libs]
--- аналогично
[libs]
http://d3js.org/d3.v3.min.js
[/libs]

Скрипты и стили, которые хочется отправить в <head>, можно обернуть в [head]:

[head]
$(function() {
  $('#slider-example').slider();
});
[/head]
  • Списки (используйте <ul>, <ol> и <dl>).
  • Таблицы (используйте <table>).
  • Код при помощи отступов.
  • Подчёркивание (лучше не использовать, достаточно * и **).
  • Ряд других возможностей, используемых редко и имеющих HTML-аналоги.