语义,标准和标记中的源代码使用"lang"属性

Fla*_*ino 19 html standards web-standards semantic-markup

我无法找到以下的授权解释,微格式或指南,所以我把它打开了.如果我错过了什么,请说出来!

假设您有一个HTML页面,其中包含<pre>元素中某些编程源代码的示例:

<pre>
    # code...
</pre>
Run Code Online (Sandbox Code Playgroud)

(更新:正如Pekka在下面指出的那样,<code>可能会比<pre>以下示例/讨论更好.但正如Brian Campbell指出这两个元素当然应该用于预先格式化的代码)

现在:你如何-在一个语义正确,规范兼容的方式-声明编程语言<pre>块的内容是什么?

这将是以语义一致的方式包含在标记中的有用信息.

从语义的角度来看,明显的选择是使用lang属性:

<pre lang="ruby">
Run Code Online (Sandbox Code Playgroud)

根据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(或类似)作为一种完全符合规范的方式的可能性,既宣称要用语言编写的东西(只是不是人类语言)声明特定的(涉及非人类语言.

那么,有没有一个标准/微格式/ microsyntax /君子协定/任何假象东西做什么?

就个人而言,我喜欢zxx-x-ruby它最完整.x-ruby本身较短,当然整洁,但除非我弄错了,该<pre>块仍然会继承其父(例如主要语言enfr或类似).


附录:

正如Pekka在下面提到的那样,<code>标签可能更合适,从语义上来说,简单地说就是非常简洁<code lang="...">.但是,<code>标记也是一个内联元素,我最初只考虑较长的源代码运行,即声明<code>块级<pre>元素中包含的所有元素的语言.

幸运的是,该lang属性是全局的,可以应用于任何一个元素,因此任何一个都可以工作.

第二:我不小心在任何地方输入"zzx" 而不是正确的"zxx"!它是一个 'z',两个 'x'.为混乱道歉.

Bri*_*ell 22

要回答这个问题,我们应该看看两件事; 任何可能相关的规范,以及在现实世界中实际完成的内容.您已经提到了相关规范在lang属性上所说的内容; 它通常用于指示所引用内容的人类语言,而不是编程语言.虽然BCP 47提到了zxx非语言内容的标签,但我不认为使用lang属性和zxx子标签来指定编程语言是非常合适的.原因是大多数源代码确实有一些语言内容,这是一种自然语言; 注释,变量名称,字符串等.该lang属性应该用于表示这些,特别是在使用CJK字符的情况下,字体选择可能基于lang属性.代码示例中包含的编程语言实际上与其中包含的人类语言正交; 将两者混为一谈可能会导致混淆,而不是清晰.

因此,让我们检查规格以获取该lang属性的替代方案.正如Pekka在另一个答案中指出的那样,<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或通过特定于您的wiki,博客或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>带有类codecode标记和带有指示语言的类的标记.
  • 辣椒:<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>元素的网站.
  • 棱镜:<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>无法使用标记的情况,例如嵌入仅接受像Tumblr这样的有限HTML子集的网站,只使用<pre>具有相同类约定的标记可能是最好的.

编辑添加:CommonMark规范尝试标准化Markdown,以便实现可以互操作,在给定相同输入的情况下生成相同的HTML,也采用了这种建议的约定.它将屏蔽的代码块添加到Markdown,用```or 包围,~~~比基于缩进的代码块更容易使用.在打开围栏之后,可以立即使用信息字符串,其定义为:

可以在打开代码栏后提供信息字符串.打开和关闭空格将被剥离,并且前缀为的第一个单词language-用作封闭元素内元素class属性的值.codepre

检查实际实现的作用也很有启发性.在Babelmark上试用一个带隔离的代码块表明,那些支持受防护代码块的实现(并非所有这些都是原始Markdown的扩展),我们看到以下细分:

  • 摊牌,blakfriday,haskell降价: <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>相当矫枉过正)
  • Maruku: <pre class="python"><code class="python">...</code></pre>

查看转换为HTML并对代码块有一定了解的其他文档标记语言:

  • AsciiDoc : <pre>...</pre>; 只需使用Pygments突出显示,并且不包含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>.

  • @Flambino我认为这和`zxx`有同样的问题;lang标签和BCP 47语言代码旨在表示自然语言,而不是编程语言。HTML 4明确指出了这一点,HTML5引用了BCP 47,该语言说:“语言标签用于帮助识别语言,无论是口语,书面,签名还是其他信号方式,以进行交流。这包括构造语言和人工语言,但不包括语言并非主要用于人类交流,例如编程语言。” (2认同)