Семантика, стандарты и использование атрибута "lang" для исходного кода в разметке - PullRequest
18 голосов
/ 27 февраля 2011

Мне не удалось найти авторские объяснения, микроформаты или рекомендации для следующего, поэтому я раскрываю это. Если я что-то пропустил, говорите!

Допустим, у вас есть HTML-страница, которая включает пример некоторого исходного кода программирования внутри элемента <pre>:

<code><pre>
    # code...

( Обновление: как Пекка указывает ниже, <code> может быть лучше, чем <pre>, но следующие примеры / обсуждение могут относиться к обоим. И как Брайан Кэмпбелл указывает оба элемента конечно, следует использовать для предварительно отформатированного кода )

Теперь: как вы - семантически правильным и совместимым со спецификацией способом - объявляете язык программирования содержимого блока <pre>?

Эту информацию было бы полезно включить в разметку семантически согласованным образом.

Очевидным выбором с семантической точки зрения было бы использование атрибута lang:

<pre lang="ruby">

Но в соответствии со спецификацией HTML 4, раздел 8.1.1 :

Значением атрибута lang является код языка, который идентифицирует естественный язык [...] Компьютерные языки явно исключены из кодов языка.

(акцент мой)

И, кроме того, "ruby" в любом случае не является стандартным языковым кодом.

Спецификация допускает добавление кодов "экспериментального" или "личного использования" с использованием основного тега x. Пример из спецификации: lang="x-klingon".

Теоретически, вы можете использовать x-ruby, x-java и т. Д. Для объявления языка программирования, содержащегося в блоке <pre>, за исключением того, что, похоже, спецификация не одобряется при использовании атрибута lang для языков программирования в общий.

Спецификация HTML 5 по теме не проясняет ситуацию. Сама спецификация явно не упоминает «естественные» против «языков программирования». Вместо этого он отсылает читателя к BCP 47 , в котором говорится (снова):

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

Тем не менее, далее упоминается (в разделе 4.1, стр. 56) основной тег языка zxx, который:

определяет контент, для которого языковая классификация не подходит или не применяется. Некоторые примеры могут включать инструментальную или электронную музыку [...] или программный исходный код .

(акцент мой)

Опять же, спецификация, кажется, противоречит самой себе, но она открывает возможность использования zxx-x-ruby (или аналогичного) в качестве полностью совместимого со спецификацией способа объявления чего-то написанного на языке * . (только не человеческий) и декларирование конкретного (не человеческого) языка.

Итак, есть ли сходство стандартного / микроформата / микросинтаксиса / джентльменского соглашения / что-нибудь о том, что делать?

Лично мне нравится zxx-x-ruby как наиболее полный. x-ruby само по себе короче и аккуратнее, конечно, но, если я не ошибаюсь, блок <pre> все равно будет наследовать основной язык своего родителя (например, en или fr или аналогичный).


Добавление:

Как упоминает Пекка ниже, тег <code>, вероятно, будет более уместным, и семантически это будет очень аккуратно, чтобы просто сказать <code lang="...">. Однако тег <code> также является встроенным элементом, и я изначально думал только о более длинных прогонах исходного кода, то есть объявлял язык для всех элементов <code>, содержащихся в элементах <pre> уровня блока.

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

Второе: я случайно набрал "zzx" везде вместо правильного "zxx"! Это один 'z', два 'x's. Извиняюсь за путаницу.

Ответы [ 2 ]

22 голосов
/ 27 февраля 2011

Чтобы ответить на этот вопрос, мы должны взглянуть на две вещи;любые потенциально важные спецификации, и что на самом деле делается в реальном мире.Вы уже упомянули, что соответствующие спецификации сказали в атрибуте lang;он обычно используется для указания языка, на который ссылается контент, а не языка программирования.Хотя в BCP 47 упоминается тег zxx для нелингвистического контента, я не верю, что действительно целесообразно использовать атрибут lang и вложенный тег zxx для указания языка программирования.Причина в том, что в большинстве исходных текстов действительно есть некоторое лингвистическое содержание, которое написано на естественном языке;комментарии, имена переменных, строки и тому подобное.Атрибут lang, вероятно, следует использовать для их указания, особенно в таких случаях, как использование символов CJK, когда выбор шрифта может основываться на атрибуте lang.Язык программирования, содержащийся в примере кода, действительно ортогонален человеческому языку, содержащемуся в нем;совмещение этих двух значений, скорее всего, приведет к путанице, а не к ясности.

Итак, давайте проверим спецификации на альтернативу атрибуту lang.Как указывает Пекка в другом ответе, элемент <code> более семантически значим для разметки исходного кода, чем элемент <pre>, поэтому давайте проверим это.Согласно спецификации HTML5 :

Элемент code представляет собой фрагмент компьютерного кода.Это может быть имя элемента XML, имя файла, компьютерная программа или любая другая строка, которую может распознать компьютер.

Хотя формального способа указать язык разметки компьютерного кода не существует, авторы, которыехотите пометить элементы code используемым языком, например, чтобы скрипты с подсветкой синтаксиса могли использовать правильные правила, могут сделать это, добавив к элементу класс с префиксом "language-".

...

В следующем примере показано, как можно разметить блок кода с использованием элементов pre и code.

<pre><code class="language-pascal">var i: Integer;
begin
   i := 1;
end.</code>

В этом примере используется класс дляукажите используемый язык.

Теперь это не формальная спецификация, а просто неофициальная рекомендация о том, как вы можете использовать класс для обозначения представленного языка.В примере также показано, как использовать тег <pre> и тег <code> для разметки блока кода.

Мы можем искать другие стандарты в другом месте, но я не нашел ни одного;Микроформаты для форматирования кода отсутствуют, и я не нашел других спецификаций, в которых это упоминается.Итак, мы переходим к тому, что на самом деле делают люди.Лучший способ выяснить это - взглянуть на то, что делают библиотеки подсветки синтаксиса HTML, поскольку они являются основными производителями и потребителями кода, встроенного в веб-страницы, на которых язык действительно имеет значение.

Существует два основных типа подсветки синтаксиса HTML;те, которые работают на сервере или в автономном режиме, в Ruby, Python или PHP, и генерируют статический HTML и CSS для отображения в браузере, и те, которые написаны на JavaScript, которые находят и выделяют элементы <pre> или <code> на клиентебоковая сторона.Вторая категория более интересна, так как им нужно определять язык по предоставленному им HTML;в первой категории вы обычно указываете язык вручную через API или через какой-то механизм, специфичный для вашего вики, блога или синтаксиса CMS, и поэтому нет фактического потребителя какой-либо языковой информации, которая может быть встроена в HTML.Для полноты картины мы рассмотрим обе категории.

Для подсветки синтаксиса JavaScript я нашел следующее с примерами их синтаксиса для указания блока кода и его языка:

  • SyntaxHighligher : <pre class="brush: html">...</pre>. Похоже, что полностью игнорируется использование class путем введения собственного синтаксиса для атрибутов class на основе синтаксиса CSS с ключевым словом brush, используемым для обозначения языка. Также имеется опция для использования тега <script>, чтобы упростить копирование и вставку кода без экранирования <, используя тот же синтаксис class.
  • Highlight.js : <pre><code class="html">... или class="language-html" или то же самое на <pre>. Это дает вам несколько опций, одна из которых соответствует рекомендации в спецификации HTML5, а другая просто использует простое имя языка в качестве имени класса.
  • SHJS : <pre class="sh_html">...</pre>. Использует собственный префикс для имен языков в классе и работает только на <pre>, но не на других элементах.
  • beautyOfCode : <pre class="code"><code class="html">.... Основан на SyntaxHighlighter, но с несколько менее странным синтаксисом. Требуется тег <pre> с классом code и тег code с классом, указывающим язык.
  • Чили : <code class="html">.... Использует только тег <code> и использует пустой язык в качестве имени класса.
  • Lighter.js : <pre class="html">.... Использует голый язык в качестве имени класса. Вы выбираете элементы, к которым он будет применяться, используя API, но пример демонстрирует это на тегах <pre>.
  • DlHighlight : <pre name="code" class="html">...</pre>. Использует голый язык в качестве имени класса. Через API вы выбираете, какой тип элемента выделять (в примере используется pre), и значение атрибута name, которое нужно искать, чтобы указать, что вы хотите выделить синтаксис. Я считаю, что это злоупотребление атрибутом name.
  • google-code-prettify : <pre class="prettyprint lang-html">. Использует имена классов с префиксом lang-, чтобы указать язык, и класс prettyprint, чтобы указать, что вы хотите подсветку синтаксиса. Языковой класс не является обязательным; он попытается автоматически определить язык, если он не указан.
  • JUSH : <code class="jush-html">... или <code class="language-html">.... Использует тег code с языками в классе с префиксом jush- или language-.
  • Rainbow : <pre><code data-language="javascript">... использует пользовательский атрибут data-language, применяемый к элементу <code> или <pre> для поддержки таких сайтов, как Tumblr, который удаляет <code> элементов.
  • Prism : <pre><code class="language-css">... соответствует спецификации HTML5 для вложенных <pre> и <code> и рекомендациям для имени класса.

Для серверной и автономной подсветки синтаксиса большинство ( CodeRay , UltraViolet , Pygments , Highlight ) не встраивают любую языковую информацию в HTML они выводят вообще. GeSHi - единственный, который я нашел, который встраивает язык, как <pre class="html">...</pre>, тег <pre> с голым именем языка в качестве класса.

Из этого списка, похоже, нет реального консенсуса. Самый популярный вариант - просто использовать голое название языка в качестве класса. Следующим по популярности является использование какой-либо формы имени языка с префиксом, с префиксом имени библиотеки lang- или language-. Некоторые из них имеют свои странные соглашения или вообще не задают язык в HTML.

Хотя единственной вещью, достаточно распространенной, чтобы быть стандартом де-факто, является использование в качестве класса пустого имени языка, я бы порекомендовал придерживаться того, что рекомендует спецификация HTML5, имени класса language-, за которым следует имя язык. Это поддерживается несколькими подсветками синтаксиса, остальные могут быть легко изменены для поддержки. Это менее двусмысленно и менее вероятно конфликтовать с другими классами, чем просто название языка как класса. И, даже если формально не указано, это, по крайней мере, упомянуто в спецификации.

Я бы также использовал тег <code> для обозначения исходного кода, открытого или встроенного в тег <pre>; Комбинация тега <code> и класса с префиксом language- может использоваться, чтобы указать, что у вас есть исходный код на определенном языке, и может использоваться, чтобы указать, что вы хотите, чтобы он был выделен, а также более ясен и лучше соответствует семантике. элементов, чем некоторые другие индикаторы, используемые библиотеками подсветки синтаксиса. Для случаев, когда тег <code> нельзя использовать, например, для встраивания в сайты, которые принимают только ограниченное подмножество HTML, такое как Tumblr, лучше всего использовать тег <pre> с тем же соглашением классов.

изменить, чтобы добавить : спецификация CommonMark , которая пытается стандартизировать Markdown, чтобы реализации могли взаимодействовать, создавая один и тот же HTML при одинаковом входном сигнале, также приняла это предложенное соглашение , Он добавляет огражденные кодовые блоки к Markdown, окруженные ``` или ~~~, что может быть проще в использовании, чем кодовые блоки на основе отступов. Сразу за открывающим ограждением может быть информационная строка , которая определяется как:

Информационная строка может быть предоставлена ​​после открывающего кода забора. Открывающие и закрывающие пробелы будут удалены, а первое слово с префиксом language- используется в качестве значения для атрибута class элемента code внутри включающего элемента pre.

Может быть поучительно также проверить, что делают реальные реализации. Попытка блока изолированного кода на Babelmark показывает, что из тех реализаций, которые поддерживают блоки изолированного кода (не все делают, так как это расширение к исходной Markdown), мы видим следующую разбивку:

  • вскрытие, Blakfriday, уценка haskell: <pre><code class="python">...
  • отмечено: <pre><code class="lang-python">...
  • общий знак, анализ, cebe / уценка: <pre><code class="language-python">...
  • Cheapskate, минимумы: <pre class="python">...</pre>
  • pandoc: <div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">... (довольно много)
  • Маруку: <pre class="python"><code class="python">...

Рассматривая другие языки разметки документов, которые конвертируются в HTML и имеют некоторое понимание блоков кода:

  • AsciiDoc: ...; просто использует Pygments для выделения и не включает информацию о языке в HTML.
  • rst2html дал мне <pre class="code python literal-block">...</pre>, выделено Pygments.
  • Сфинкс: <div class="highlight-python"><div class="highlight"><pre>...</pre></div></div>, также выделен Пигментами.

Таким образом, в целом, довольно большое разнообразие в выборе различных проектов, но, кажется, есть некоторый шаг в направлении стандартизации <pre><code class="language-python">....

0 голосов
/ 27 февраля 2011

Нет лучшего способа, чем неправильно использовать атрибут lang с упомянутым вами префиксом zzx (кстати, интересная находка!).Атрибут type может быть немного более подходящим, но он, конечно, недопустим для pre элементов.

Кстати, <code>(Ссылка W3C здесь ) может быть более подходящей, чем <pre>:

Элемент HTML Code (<code>) представляет собой фрагмент компьютерного кода.По умолчанию он отображается в стандартном моноширинном шрифте браузера.

...