html - the - w3c standards
Semántica, estándares y uso del atributo "lang" para el código fuente en el marcado (2)
No he podido encontrar explicaciones autoritarias, microformatos o pautas para lo siguiente, así que lo estoy abriendo. Si me he perdido algo, ¡habla!
Digamos que tiene una página HTML que incluye un ejemplo de código fuente de programación dentro de un elemento <pre>
:
<pre>
# code...
</pre>
( Actualización: como señala Pekka a continuación, <code>
puede ser mejor que <pre>
pero los siguientes ejemplos / discusión pueden aplicarse a ambos. Y como Brian Campbell señala que ambos elementos deben usarse para el código preformateado )
Ahora: ¿Cómo declara el lenguaje de programación del contenido del bloque <pre>
una manera semánticamente correcta y compatible con las especificaciones?
Esta sería información útil para incluir en el marcado de forma semánticamente consistente.
La elección obvia, desde un punto de vista semántico, sería utilizar el atributo lang
:
<pre lang="ruby">
Pero de acuerdo con la especificación de HTML 4, sección 8.1.1 :
El valor del atributo lang es un código de idioma que identifica un idioma natural. [...] Los idiomas de computadora se excluyen explícitamente de los códigos de idioma.
(énfasis mío)
Y además, "ruby" no es un código de idioma estándar de todos modos.
La especificación permite agregar códigos "experimentales" o "de uso privado" usando la etiqueta primaria x
. El ejemplo de la especificación es lang="x-klingon"
.
En teoría, podría usar x-ruby
, x-java
y así sucesivamente para declarar el lenguaje de programación contenido en el bloque <pre>
, excepto que parece que las especificaciones fruncen el ceño al usar el atributo lang
para los lenguajes de programación en general.
La especificación de HTML 5 en el tema no hace las cosas más claras. La especificación en sí misma no menciona explícitamente los lenguajes "natural" vs "programación". En su lugar, refiere al lector a BCP 47 , que establece (de nuevo):
Las etiquetas de idioma se usan para ayudar a identificar [...] idiomas, pero excluye los idiomas que no están destinados principalmente para la comunicación humana, como los lenguajes de programación.
Sin embargo, continúa mencionando (en la sección 4.1, página 56) la subetiqueta de idioma principal de zxx
, que:
identifica el contenido para el cual una clasificación de idioma es inapropiada o no se aplica. Algunos ejemplos pueden incluir música [...] instrumental o electrónica o código fuente de programación .
(énfasis mío)
De nuevo, la especificación parece contradecirse a sí misma, pero abre la posibilidad de usar zxx-x-ruby
(o similar) como una forma totalmente compatible con las especificaciones de declarar que algo está escrito en un idioma (pero no en uno humano) y declarar el lenguaje específico (no humano) involucrado.
Entonces, ¿hay algo parecido a un estándar / microformato / microsyntax / acuerdo de caballero / algo sobre qué hacer?
Personalmente, me gusta zxx-x-ruby
ya que es el más completo. x-ruby
por sí mismo es más corto y más limpio, por supuesto, pero a menos que me equivoque, el bloque <pre>
todavía heredaría el idioma principal de su padre (por ejemplo, en
o fr
o similar).
Apéndice:
Como Pekka menciona a continuación, la etiqueta <code>
probablemente sería más apropiada, y semánticamente sería muy ordenado simplemente decir <code lang="...">
. Sin embargo, la etiqueta <code>
también es un elemento en línea, e inicialmente pensaba en series más largas de código fuente, es decir, declarar el idioma para todos los elementos <code>
contenidos en los elementos <pre>
nivel de bloque.
Afortunadamente, el atributo lang
es global y puede aplicarse a cualquiera de los elementos, por lo que cualquiera de los dos funcionaría.
Segundo: accidentalmente escribí "zzx" en todas partes en lugar de la correcta "zxx"! Es una ''z'', dos ''x''s. Disculpas por la confusión.
Para responder a esta pregunta, debemos mirar dos cosas; cualquier especificación potencialmente relevante, y lo que realmente se hace en el mundo real. Ya ha mencionado lo que las especificaciones relevantes han dicho en el atributo lang
; generalmente se utiliza para indicar el lenguaje humano del contenido al que se hace referencia, no el lenguaje de programación. Si bien BCP 47 menciona la etiqueta zxx
para contenido no lingüístico, no creo que sea realmente apropiado usar el atributo lang
y la subetiqueta zxx
para especificar el lenguaje de programación. La razón es que la mayoría del código fuente realmente tiene algún contenido lingüístico, que está en un lenguaje natural; comentarios, nombres de variables, cadenas y similares. El atributo lang
probablemente debería usarse para indicar esto, especialmente en casos como el uso de caracteres CJK donde la selección de fuente podría basarse en el atributo lang
. El lenguaje de programación contenido en un ejemplo de código es realmente ortogonal al lenguaje humano contenido en él; la combinación de los dos probablemente llevará a la confusión, no a la claridad.
Entonces, revisemos las especificaciones para una alternativa al atributo lang
. Como señala Pekka en otra respuesta, el elemento <code>
es más significativo semánticamente para marcar el código fuente que el elemento <pre>
, así que revisemos allí. Según la especificación HTML5 :
El elemento de
code
representa un fragmento de código de computadora. Esto podría ser un nombre de elemento XML, un nombre de archivo, un programa de computadora o cualquier otra cadena que una computadora reconocería.Aunque no hay una manera formal de indicar el idioma del código de computadora que se está marcando, los autores que deseen marcar los elementos del
code
con el idioma utilizado, por ejemplo, para que las secuencias de comandos de resaltado de sintaxis puedan usar las reglas correctas, pueden hacerlo agregando una clase con el prefijo "language-
" al elemento....
El siguiente ejemplo muestra cómo se puede marcar un bloque de código usando los elementos pre y código.
<pre><code class="language-pascal">var i: Integer; begin i := 1; end.</code></pre>
En este ejemplo se utiliza una clase para indicar el idioma utilizado.
Ahora, esto no es una especificación formal, solo una recomendación informal sobre cómo podría usar una clase para indicar el idioma representado. El ejemplo también muestra cómo usar una etiqueta <pre>
y una etiqueta <code>
para marcar un bloque de código.
Podemos buscar en cualquier otro lado estándares, pero no he encontrado ninguno; no hay microformatos para el formato de código, y no he encontrado ninguna otra especificación que lo mencione. Entonces, pasamos a lo que la gente realmente hace. La mejor manera de descubrir esto es ver qué hacen las bibliotecas de resaltado de sintaxis HTML, ya que son los principales productores y consumidores de código incrustado en páginas web en las que el idioma realmente importa.
Hay dos tipos principales de resaltadores de sintaxis HTML; los que se ejecutan en el servidor o fuera de línea, en Ruby o Python o PHP, y producen HTML y CSS estáticos para que los muestre el navegador, y los que están escritos en JavaScript, que encuentran y resaltan los elementos <pre>
o <code>
en el cliente lado. La segunda categoría es más interesante, ya que necesitan detectar el lenguaje del HTML que se les proporcionó; en la primera categoría, normalmente especifica el idioma manualmente a través de la API o mediante algún mecanismo específico de su wiki, blog o sintaxis de CMS, por lo que no hay un consumidor real de ninguna información de idioma que pueda estar incrustada en el HTML. Vamos a echar un vistazo a las dos categorías por el bien de la integridad.
Para los resaltadores de sintaxis de JavaScript, he encontrado lo siguiente, con ejemplos de su sintaxis para especificar un bloque de código y su idioma:
- SyntaxHighligher :
<pre class="brush: html">...</pre>
. Parece ignorar completamente cómo se debe usar laclass
introduciendo su propia sintaxis paraclass
atributos declass
basados en la sintaxis CSS con la palabra clavebrush
utilizada para indicar el idioma. También tiene una opción para usar la etiqueta<script>
, para que sea más fácil copiar y pegar el código sin tener que escapar<
, usando la misma sintaxis declass
. - Highlight.js :
<pre><code class="html">...</code></pre>
oclass="language-html"
o el mismo en<pre>
. Esto le da varias opciones, una de las cuales corresponde a la recomendación en la especificación HTML5, la otra simplemente usa el nombre del idioma como el nombre de la clase. - SHJS :
<pre class="sh_html">...</pre>
. Utiliza su propio prefijo para los nombres de idiomas en la clase y solo funciona en<pre>
, no en otros elementos. - beautyOfCode :
<pre class="code"><code class="html">...</code></pre>
. Basado en SyntaxHighlighter, pero con una sintaxis algo menos rara. Requiere una etiqueta<pre>
concode
clase y la etiqueta decode
con una clase que indica el idioma. - Chili :
<code class="html">...</code>
. Utiliza solo la etiqueta<code>
y usa el lenguaje simple como nombre de clase. - Lighter.js :
<pre class="html">...</code>
. Utiliza el lenguaje simple como un nombre de clase. Selecciona los elementos a los que se aplicará el uso de la API, pero el ejemplo lo muestra en<pre>
etiquetas<pre>
. - DlHighlight :
<pre name="code" class="html">...</pre>
. Utiliza el lenguaje simple como un nombre de clase. Usted elige a través de la API qué tipo de elemento resaltar (el ejemplo usadopre
) y el valor del atributo dename
debe buscar para indicar que desea resaltar la sintaxis. Creo que esto es un abuso del atributo dename
. - google-code-prettify :
<pre class="prettyprint lang-html">
. Utiliza nombres de clase con el prefijolang-
para especificar el idioma y la claseprettyprint
para indicar que desea resaltar la sintaxis. La clase de idiomas es opcional; intentará detectar automáticamente el idioma si no se especifica. - JUSH :
<code class="jush-html">...</code>
o<code class="language-html">...</code>
. Utiliza la etiqueta decode
, con idiomas en una clase con el prefijojush-
olanguage-
. - Rainbow :
<pre><code data-language="javascript">...</code></pre>
usa el atributo personalizadodata-language
, aplicado a un elemento<code>
o un elemento<pre>
, con el fin de apoyar sitios como Tumblr que eliminan los elementos<code>
. - Prism :
<pre><code class="language-css">...</code></pre>
sigue la especificación de HTML5 para<pre>
y<code>
anidadas, y la recomendación para el nombre de la clase.
Para los resaltadores de sintaxis basados en servidor y fuera de línea, la mayoría ( CodeRay , UltraViolet , Pygments , Highlight ) no incrustan ninguna información de idioma en el HTML que se imprime. GeSHi es el único que encontré que incrusta el idioma, como <pre class="html">...</pre>
, una etiqueta <pre>
con un nombre de idioma simple como la clase.
Fuera de esa lista, no parece haber un consenso real. La opción más popular es usar el nombre de lenguaje simple como clase. El siguiente más popular es el uso de alguna forma de nombre de idioma prefijado, ya sea prefijado por el nombre de la biblioteca, language-
o language-
. Hay algunos que tienen sus propias convenciones extrañas, o no especifican el idioma en el HTML en absoluto.
Si bien la única cosa lo suficientemente común como para ser un estándar de facto es usar el nombre de lenguaje simple como una clase, recomendaría seguir con lo que recomienda la especificación de HTML5, un nombre de clase de language-
seguido del nombre del idioma. Esto está respaldado por algunos de los resaltadores de sintaxis, el resto probablemente podría modificarse fácilmente para admitirlo. Es menos ambiguo y es menos probable que entre en conflicto con otras clases que solo con el nombre de lenguaje simple como clase. Y, aunque no se especifique formalmente, al menos se menciona en una especificación.
También usaría la etiqueta <code>
para indicar el código fuente, ya sea desnudo o incrustado en una etiqueta <pre>
; la combinación de una etiqueta <code>
y una clase con prefijo de language-
se puede usar para indicar que tiene un código fuente en un idioma en particular, y se podría usar para indicar que desea que se resalte, y es más clara y se ajusta mejor a la semántica de los elementos que algunos de los otros indicadores utilizados por las bibliotecas de resaltado de sintaxis. Para los casos en los que no se puede usar una etiqueta <code>
, como incrustar en sitios que solo aceptan un subconjunto de HTML limitado como Tumblr, lo mejor es usar la etiqueta <pre>
con la misma convención de clase.
edición para agregar : la especificación CommonMark , que intenta estandarizar Markdown para que las implementaciones puedan ser interoperables, produciendo el mismo HTML con la misma entrada, también ha adoptado esta convención sugerida. Agrega bloques de código cercados a Markdown, rodeados con ```
o ~~~
, que pueden ser más fáciles de usar que los bloques de código basados en sangría. Inmediatamente después de la apertura de la cerca puede ser una cadena de información , que se define como:
Una cadena de información se puede proporcionar después de la cerca del código de apertura. Los espacios de apertura y cierre se eliminarán, y la primera palabra, con el prefijo
language-
, se utilizará como valor para el atributo declass
del elemento decode
dentro del elementopre
contiene.
También puede ser instructivo comprobar qué hacen las implementaciones reales. Al probar un bloque de código cercado en Babelmark se muestra que de aquellas implementaciones que admiten bloques de código cercado (no todos hacen como es una extensión del Markdown original), vemos el siguiente desglose:
- showdown, blakfriday, haskell markdown:
<pre><code class="python">...</code></pre>
- marcado:
<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>
(bastante la exageración) - Maruku:
<pre class="python"><code class="python">...</code></pre>
Mirando otros lenguajes de marcado de documentos que se convierten a HTML y tienen cierta comprensión de los bloques de código:
- AsciiDoc:
<pre>...</pre>
; simplemente usa Pygments para resaltar y no incluye información de idioma en el HTML. -
rst2html
me dio<pre class="code python literal-block">...</pre>
, resaltado con Pygments. - Sphinx:
<div class="highlight-python"><div class="highlight"><pre>...</pre></div></div>
, también resaltado con Pygments.
Así que, en general, hay una diversidad bastante grande en las opciones de los diferentes proyectos, pero parece que hay cierto movimiento hacia la estandarización en <pre><code class="language-python">...</code></pre>
.
Parece que no hay una mejor manera de utilizar mal el atributo lang
con el prefijo zzx
que mencionas (¡un hallazgo interesante por cierto!). El atributo de type
podría ser un poco más adecuado, pero por supuesto no es válido en pre
elementos pre
.
Por cierto, <code>
(referencia W3C here ) podría ser más adecuado que <pre>
:
El elemento de código HTML (
<code>
) representa un fragmento de código de computadora. De forma predeterminada, se muestra en la fuente monoespaciada predeterminada del navegador.