Подтвердить что ты не робот

Семантика, стандарты и использование атрибута "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 (или подобного) как полностью spec-совместимого способа как объявления того, что должно быть написано на языке (просто не человека ) и объявление конкретного (нечеловеческого) языка.

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

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


Добавление:

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

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

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

4b9b3361

Ответ 1

Чтобы ответить на этот вопрос, мы должны рассмотреть две вещи; любые потенциально соответствующие спецификации и то, что на самом деле сделано в реальном мире. Вы уже упоминали, что в спецификациях lang указаны соответствующие спецификации; он обычно используется для указания языка на языке, на который ссылается контент, а не на языке программирования. Хотя BCP 47 упоминает тег zxx для неязыкового контента, я не считаю, что действительно полезно использовать атрибут lang и zxx subtag для указания языка программирования. Причина в том, что в большинстве исходных текстов действительно есть лингвистический контент, который находится на естественном языке; комментарии, имена переменных, строки и т.п. Атрибут 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>
     

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

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

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

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

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

  • СинтаксисHighligher: <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 с классом, указывающим язык.
  • Chili: <code class="html">...</code>. Использует только тег <code> и использует голый язык как имя класса.
  • Lighter.js: <pre class="html">...</code>. Использует голый язык как имя класса. Вы выбираете элементы, которые будут применяться для использования 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> или <code class="language-html">...</code>. Использует тег code с языками в классе с префиксом jush- или language-.
  • Rainbow: <pre><code data-language="javascript">...</code></pre> использует пользовательский атрибут data-language, применяемый к элементу <code>, или <pre>, чтобы поддерживать такие сайты, как Tumblr, которые выделяют элементы <code>.
  • Prism: <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- prefixed class может использоваться, чтобы указать, что у вас есть исходный код на определенном языке, и может использоваться, чтобы указать, что вы хотите, чтобы он был выделен, и более четко и лучше соответствует семантике элементов, чем некоторые другие индикаторы, используемые библиотеками подсветки синтаксиса. Для случаев, когда нельзя использовать тег <code>, например, встраивание сайтов, которые принимают только ограниченное подмножество HTML, например Tumblr, возможно, лучше всего использовать тег <pre> с тем же соглашением классов.

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

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

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

  • showdown, blakfriday, haskell markdown: <pre><code class="python">...</code></pre>
  • отмечен: <pre><code class="lang-python">...</code></pre>
  • commonmark, parsedown, cebe/markdown: <pre><code class="language-python">...</code></pre>
  • cheapskate, minima: <pre class="python">...</pre>
  • pandoc: <div class="sourceCode"><pre class="sourceCode python"><code class="sourceCode python">...</code></pre></div> (довольно переполненный)
  • Маруку: <pre class="python"><code class="python">...</code></pre>

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

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

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

Ответ 2

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

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

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