Семантика, стандарты и использование атрибута "lang" для исходного кода в разметке

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

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

<pre>
    # code...
</pre>

(Обновление: как указывает Пекка ниже, <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". Извиняюсь за путаницу.

2 ответа

Решение

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

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

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

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

...

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

 
  var i: Integer;
начать
   я:= 1;
конец.   

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

Теперь это не формальная спецификация, а просто неформальная рекомендация о том, как вы можете использовать класс для обозначения представленного языка. В примере также показано, как использовать оба <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">...</code></pre> или же class="language-html" или то же самое на <pre>, Это дает вам несколько опций, одна из которых соответствует рекомендации в спецификации HTML5, а другая просто использует имя языка в качестве имени класса.
  • SHJS: <pre class="sh_html">...</pre>, Использует свой собственный префикс для имен языков в классе и работает только на <pre>, а не другие элементы.
  • beautyOfCode: <pre class="code"><code class="html">...</code></pre>, Основан на SyntaxHighlighter, но с несколько менее странным синтаксисом. Требуется <pre> тег с классом code и code тег с классом, указывающим язык.
  • Чили: <code class="html">...</code>, Использует только <code> тег и использует пустой язык в качестве имени класса.
  • Lighter.js: <pre class="html">...</code>, Использует голый язык в качестве имени класса. Вы выбираете элементы, к которым он будет применяться, используя API, но пример демонстрирует это на <pre> теги.
  • DlHighlight: <pre name="code" class="html">...</pre>, Использует голый язык в качестве имени класса. Вы выбираете через API, какой тип элемента выделить (используемый пример pre) и значение name атрибут для поиска, чтобы указать, что вы хотите подсветку синтаксиса. Я считаю, что это злоупотребление name приписывать.
  • http://code.google.com/p/google-code-prettify/: <pre class="prettyprint lang-html">, Использует имена классов с префиксом lang- указать язык и класс prettyprint чтобы указать, что вы хотите подсветку синтаксиса. Языковой класс не является обязательным; он попытается автоматически определить язык, если он не указан.
  • ДЖУШ: <code class="jush-html">...</code> или же <code class="language-html">...</code>, Использует code тег, с языками в классе с префиксом jush- или же language-,
  • Радуга: <pre><code data-language="javascript">...</code></pre> использует пользовательский атрибут data-language, применяется к любому <code> элемент или <pre> элемент, чтобы поддерживать такие сайты, как Tumblr, которые удаляют <code> элементы.
  • Призма: <pre><code class="language-css">...</code></pre> следует спецификации 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">...</code></pre>
  • отметил: <pre><code class="lang-python">...</code></pre>
  • общий знак, анализ, cebe/ уценка: <pre><code class="language-python">...</code></pre>
  • Cheapskate, минимумы: <pre class="python">...</pre>
  • pandoc: <div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">...</code></pre></div> (довольно излишнее)
  • Maruku: <pre class="python"><code class="python">...</code></pre>

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

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

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

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

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

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

Другие вопросы по тегам