Как я собираюсь убить HTML

от автора

Если вы считаете, что язык, на котором вы пишете, идеален, значит, у вас просто нет фантазии.

Существует проблема

Здравствуйте, меня зовут Андрей, и я собираюсь убить HTML. Его не ругал только самый ленивый из веб-разработчиков. Он синтаксически избыточен, полон костылей, призванных обеспечить обратную совместимоcть со стандартами 20-летней давности, код на нём редко семантически соответствует содержанию документа, однако HTML остаётся стандартом де-факто в вебе. Главным образом, из-за отсутствия реальных альтенатив. А также из-за необходимости поддержки обратной совместимости со старыми браузерами, которые не понимают ничего, кроме HTML.

Эту проблему уже пытались решить

image

Использование XML делает код более семантически чистым, но не решает проблему избыточности синтаксиса. К тому же, оно заставляет вводить новую сущность — XSLT-преобразования, что повышает порог вхождения и зачастую усугубляет избыточность.
TeX не избыточен и семантически чист, имеет очень широкие возможности, но сложен для изучения новичком. К тому же, не поддерживается ни одним из существующих веб-браузеров, да и реализвать трансляцию TeX-кода в HTML для осуществления совместимости с ними — задача весьма нетривиальная. Всё-таки, он разрабатывался для иных целей.
Markdown красив, семантически чист, лаконичен, но имеет недостаточные для создания серьёзных веб-страниц возможности.
БЭМ близок по духу к тому, что я хотел бы видеть, но на мой вкус он некрасив и плохо читаем, когда размер документа вырастает хотя бы до 100 строк, а уровень вложенности — до четырёх. Да, разумеется, этого следует избегать, и да, разумеется, я понимаю, что всё это — дань совместимости с Javascript-синтаксисом, и вообще, он предназначен в первую очередь не для этого.

И я попытаюсь ещё раз

Изучив достоинства существующих альтернатив и выявив их недостатки, можно обобщить требования к будущему языку (Назовём его для начала SPML — Sematic Page Markup Language. Я знаю, что название уже занято, так что, вероятно, оно не окончательное).

  1. SPML должен однозначно транслироваться в валидный HTML 5 как на сервере, так и на клиенте.
  2. SPML должен быть полон: с его помощью можно реализовать всё, что можно реализовать на HTML, и больше;
  3. Код на SPML должен быть легко читаем и понятен даже человеку, не знакомому с языками разметки и программирования;
  4. SPML должен быть лаконичен, код на нём всегда должен быть заметно короче, чем эквивалентный код на HTML;
  5. SPML должен включать в себя функцию шаблонизатора: необходимо предусмотреть вставку динамически изменяемых значений;
  6. Любой текстовый файл должен быть валидным SPML-документом.

И вот как я предлагаю это делать

Пункт 1. Советский анекдот.

На площади старый еврей раздает листовки. Люди берут, отходят и обнаруживают, что у них в руках пустые листки.
Некоторые снова подходят к нему.
— Так ведь здесь ничего не написано!
— А чего зря писать? И так все ясно!

Первым делом, необходимо выбросить из языка элементы, общие для всех HTML5-страниц. DOCTYPE, корневой тег HTML, теги HEAD и BODY избыточны — их наличие подразумевается само собой.
Если минимальный валидный HTML-файл выглядит так:

<!DOCTYPE html> <html> <head>   <title></title> </head> <body> </body> </html> 

то минимальный валидный SPML-файл должен выглядеть так:

То есть, быть пустым текстовым документом. Зачем писать то, что само собой разумеется?

Пункт 2. Вложенность.

image
Вложенность элементов понятнее всего выражается табуляциями (как в Python или Coffescript) — это избавляет от избыточности и визуального мусора в виде закрывающих тегов или фигурных скобочек, а также обязывает красиво форматировать исходный код: неправильно отформатированный код будет неправильно транслироваться.

Так, код вида:

<div class="parent">   <div class="child">     Child 1 content.   </div>   <div class="child">     Child 2 content.   </div> </div> 

в SPML будет выглядеть так:

parent:   child: Child 1 content   child: Child 2 content 

или так:

parent:   child:     Child 1 content   child:     Child 2 content 
Пункт 3. Что транслировать в класс div-a, а что — в другой html-элемент?

Поясню, что происходит в процессе трансляции, ибо это важно.
В случае если считая от первого значащего символа строки двоеточие встречается раньше пробела, этот участок кода (от первого значащего символа до двоеточия) считается названием ноды. Если название ноды совпадает с одним из существующих HTML тегов (например, h1), оно транслируется в соответствующий тег. Иначе — оно транслируется в универсальный блочный элемент div, а название ноды становится именем класса этой ноды.
Всё, что идёт в такой строке после двоеточия, преобразуется в текстовую ноду.
Если пробел встречается в строке раньше двоеточия, либо ни то, ни другое не встречается вообще, то вся строка преобразуется в текстовую ноду.
То есть, код

h1: Заголовок p:    Содержимое параграфа.   Продолжение содержимого параграфа copyright: 2013 Василий Пупкин 

будет преобразован в следующий эквивалентный ему HTML:

<h1>   Заголовок </h1> <p>   Содержимое параграфа   Продолжение содержимого параграфа </p> <div class="copyright">   2013 Василий Пупкин </div> 
Пункт 4. Куда, всё же, делась голова?

image

Разделение на Head и Body в HTML тоже появилось неспроста. Так, в head помимо обязательного title могут быть указаны (и, как правило, указываются) ссылки на CSS-стили, на скрипты, применяемые на странице, различная метаинформация (кодировка, перенаправления, ключевые слова, описание страницы для поисковых машин). Это тоже необходимо учесть в языке.

Вместо этого:

<!DOCTYPE html> <html> <head>   <title>Title</title>   <link href="style.css" rel="stylesheet">   <script src="script.js" type="text/javascript"></script>   <meta http-equiv="Content-Type" content="text/html" />   <meta http-equiv="refresh" content="5; url=http://www.example.com/" />   <meta name="description" content="Описание страницы" />   <meta name="generator" content="Super-Puper CMS"> </head> <body> </body> </html> 

в SPML будет достаточно написать вот это:

title:Title css: style.css js: script.js http-equiv:   Content-Type: text/html   refresh: 5; url=http://www.example.com/ meta:    description:  Описание страницы   generator: Super-Puper CMS 

То есть, группы мета-тегов http-equiv и name будут существовать отдельно. Я считаю этот шаг разумным, так как они предназначены для совершенно разных вещей. http-equiv имитируют HTTP-заголовки, а name — предоставляют дополнительную информацию для поисковых роботов и разработчиков.
Эти элементы в SPML можно вставлять в любое место страницы, также их может быть несколько — код не потеряет свою валидность.

Пункт 5. Строчные и строчно-блочные элементы. Списки

Такие элементы как b, i, a, img и т.д. не имеет смысла выносить в отдельный блок SPML. Вместо этого лучше позаимствовать синтаксис Markdown.

<div class="text">   Однажды, в <b>студёную</b> <i>зимнюю</i> пору<br/>   Я из <a href="http://forest.com">лесу</a> вышел, был сильный мороз.   <img src="nekrasov.jpg" alt="Некрасов"> </div> 

В SPML следует записать так:

text:   Однажды, в **студёную** *зимнюю* пору   Я из [лесу](http://forest.com) вышел, был сильный мороз.   ![Некрасов](nekrasov.jpg) 

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

- Какой-то текст - опять текст 1. Ещё какой-то текст list:   - Элемент неупорядоченного списка   - опять элемент списка list:   1. элемент упорядоченного списка   2. вновь элемент упорядоченного списка 

Превратится в эквивалентный HTML:

- Какой-то текст - опять текст 1. Ещё какой-то текст <ul>   <li>Элемент неупорядоченного списка</li>   <li>опять элемент списка</li> </ul> <ol>   <li>элемент упорядоченного списка</li>   <li>вновь элемент упорядоченного списка</li> </ol> 
Пункт 6. Атрибуты

Атрибуты по своей сути являются обычными именованными нодами, за исключением того, что их содержимое не выводится на страницу напрямую.
В XSLT, CSS- и jQuery-селекторах принято начинать название атрибута с символа @. Разумно будет сохранить этот синтаксис для облегчения перехода разработчиков на SPML.

Так, код

<audio src="mucic.mp3" loop autoplay> 

Превратится в:

audio[@loop @autoplay]:music.mp3 
Пункт 7. Динамические элементы (Шаблонизация)

К сожалению (хотя, скорее, к счастью) без динамических элементов сейчас никак. Легко и красиво выводить в коде значения JS-переменных предлагаю с помощью конструкции {{ }} следующим образом:

Новые сообщения - {{ newMessagesCount }} 

или, например, таким:

Новые сообщения - {{ messages.getNew() }} 

В общем, надеюсь, суть понятна.

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

Пункт последний. Соберём всё воедино

Возьмём для примера небольшой типичный HTML-файл и перепишем его на SPML.

Было:

<!DOCTYPE html> <html>   <head>     <title>Веб-страничка</title>     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">     <link href="css/style.css" rel="stylesheet" />     <script src="js/script.js" type="text/javascript"></script>   </head>   <body>     <div class="header">         <div class="logo">           <img src="images/logo.png" alt="логотип">         </div>         <div class="menu">           <ul>             <li><a href="/">Главная</a></li>             <li><a href="/catalog/index.php">Каталог</a></li>             <li><a href="/contacts">Контакты</a></li>           </ul>         </div>     </div>      <div class="content">       <h1>Веб-страничка</h1>       <p>         Параграф какого-нибудь текста.       </p>       <p>         Ещё параграф какого-нибудь текста.       </p>     </div>          <div class="footer">       <div class="copyright">Василий Пупкин</div>       <div class="year">2013</div>     </div>   </body> </html> 

Стало:

title: Веб-страничка Content-Type: text/html; charset=utf-8 css: css/style.css js: js/script.js  header:   logo: ![логотип](images/logo.png)   menu:     list:       - [Главная](/)       - [Каталог](/catalog/index.php) 	  - [Контакты](/contacts)  content:   h1: Веб-страничка   p: Параграф какого-нибудь текста.   p: Ещё параграф какого-нибудь текста.  footer:   copyright: Василий Пупкин   year: 2013 

38 строк, 969 символов превратились в 20 строк и 400 символов соответственно. Ну и, согласитесь, в коде стало значительно проще разобраться. Для эксперимента можете также дать почитать этот код своей маме. Уверен, она всё поймёт 🙂

Заключение

В общем, первый концепт языка выглядит как-то так. Разумеется, множество деталей, в том числе, довольно крупных, не учтено, но на то он и концепт. Хочу услышать критику, замечания и дополнения, а также мнения о том, нужен ли такой язык. В случае, если сообществу понравится идея, продолжу работу и напишу транслятор/интерпретатор для него. Да и если не понравится, пожалуй, всё равно продолжу и напишу. Но ваши мнения для меня всё равно очень важны.

Большое спасибо за внимание к моему воспалённому воображению.

ссылка на оригинал статьи http://habrahabr.ru/post/188970/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *