Ответ 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>
.