html - etiquetas - meta name keywords
Cómo mostrar el código html crudo en PRE o algo parecido pero sin escapar de él (7)
@GitaarLAB y @Jukka elaboran que la etiqueta <xmp>
es obsoleta, pero sigue siendo la mejor. Cuando lo uso así
<xmp>
<div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
luego, la primera EOL se inserta en el código, y se ve horrible .
Se puede resolver eliminando esa EOL
<xmp><div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
pero luego se ve mal en la fuente. Solía resolverlo con wrapping <div>
, pero recientemente descubrí una buena regla de CSS3, espero que también ayude a alguien:
xmp { margin: 5px 0; padding: 0 5px 5px 5px; background: #CCC; }
xmp:before { content: ""; display: block; height: 1em; margin: 0 -5px -2em -5px; }
Esto se ve mejor .
Me gustaría mostrar HTML sin formato. Todos sabemos que uno tiene que escapar de cada "<" y ">" como este
<PRE> this is a test <DIV> </PRE>
Sin embargo, no quiero hacer esto. Me gustaría una forma de mantener el código HTML tal como está (ya que es más fácil de leer, (dentro del editor) y podría querer copiarlo y usarlo de nuevo como código HTML real, y no quiero tener que cámbielo nuevamente o tenga 2 versiones del mismo código, una escapada y otra no escapada).
¿Hay algún otro entorno que esté más "crudo" que PRE que pueda permitir esto? Entonces, ¿uno no tiene que seguir editando HTML y cambiar todo cada vez que quiere mostrar un código HTML sin procesar, puede estar en HTML5?
Algo así como <REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>
captura de pantalla
La solución javascript no funciona en FF 21, aquí está la captura de pantalla
captura de pantalla 2
La primera solución aún no funciona en Firefox, aquí está la captura de pantalla
Esencialmente, la pregunta original se puede dividir en 2 partes:
- Objetivo / desafío principal: incrustación (/ transporte) de un fragmento de código con formato sin formato (cualquier tipo de código) en el marcado de una página web (para copiar / pegar / editar de forma simple debido a que no se codifica / escapa)
- mostrar / renderizar correctamente ese fragmento de código (posiblemente editarlo) en el navegador
La respuesta corta (pero) ambigua es: no puedes , ... pero puedes (acercarte mucho).
(Lo sé, son 3 respuestas contradictorias, así que sigue leyendo ...)
(políglota) (x) (ht) ml Los lenguajes de marcado se basan en envolver (casi) todo entre comenzar / abrir y terminar / cerrar etiquetas / caracteres (secuencias).
Por lo tanto, para insertar cualquier tipo de código / fragmento sin formato dentro de su lenguaje de marcado, siempre tendrá que escapar / codificar cada instancia (dentro de ese fragmento) que se asemeja al carácter (-secuencia) que cerraría el elemento ''contenedor'' de ajuste en el marcado. ( Durante esta publicación me referiré a esto como la regla no 1 ).
Piense en "some "data" here"
o <i>..close italics with ''</i>''-tag</i>
, donde es obvio que uno debe escapar / codificar (algo en) </i
y "
( o cambie el carácter de cita del contenedor de "
a ''
).
Por lo tanto, debido a la regla n. ° 1, no puede ''solo'' incrustar ''ningún'' fragmento de código sin formato dentro del marcado.
Porque, si uno tiene que escapar / codificar incluso un carácter dentro del fragmento sin procesar, entonces ese fragmento ya no será el mismo ''código puro puro'' original que cualquiera puede copiar / pegar / editar en el marcado del documento sin pensarlo más . Mojibake marcado malformado / ilegal y Mojibake (principalmente) a causa de entidades.
Además, si ese fragmento contiene tales caracteres, aún necesitaría un javascript para ''traducir'' ese carácter (secuencia) de (y para) su representación escapada / codificada para mostrar el fragmento correctamente en la ''página web'' (para copiar / pegar /editar).
Eso nos lleva a (algunos de) los tipos de datos que especifican los lenguajes de marcado. Estos tipos de datos esencialmente definen lo que se consideran ''caracteres válidos'' y su significado (por etiqueta, propiedad, etc.):
PCDATA
(DATA de Caracteres Parsed): ampliará las entidades y se deberá escapar de<
,&
(y>
según el lenguaje de marcado / versión).
La mayoría de las etiquetas comobody
,div
,pre
, etc., pero tambiéntextarea
(hasta HTML5) se clasifican en este tipo.
Por lo tanto, no solo necesita codificar todas las secuencias de caracteres de cierre del contenedor dentro del fragmento, sino que también debe codificar todos los caracteres<
,&
(>
(como mínimo).
Huelga decir que codificar / escapar de este número de caracteres queda fuera del alcance de este objetivo al incrustar un fragmento en bruto en el marcado.
''..Pero un área de texto parece funcionar ...'', sí, ya sea porque el motor de errores de los navegadores intenta hacer algo con él, o porque HTML5:RCDATA
(DATA de caracteres reemplazables): no tratará las etiquetas dentro del texto como marcas (pero aún se rigen por la regla 1), por lo que no es necesario codificar<
(>
). PERO las entidades todavía están expandidas, por lo que ellas y ''ampersands ambiguos'' (&
) necesitan cuidados especiales.
La especificación HTML5 actual dice que el área de texto ahora es un campoRCDATA
y (cita):El texto en texto
raw text
y los elementosRCDATA
no deben contener ninguna aparición de la cadena"</"
(U + 003C MENOS QUE SIGNO, U + 002F SOLIDUS) seguido de caracteres que distinguen mayúsculas y minúsculas con el nombre de la etiqueta del elemento seguido por uno de U + 0009 TABULACIÓN DE CARÁCTER (pestaña), U + 000A ALIMENTACIÓN DE LÍNEA (LF), U + 000C FORMA DE ALIMENTACIÓN (FF), U + 000D RETORNO DE CARRITO (CR), U + 0020 ESPACIO, U + 003E MAYOR QUE SEÑAL (>), o U + 002F SOLIDUS (/).Por lo tanto, no importa qué, textarea necesita un manejador de traducción entidad fuerte o eventualmente Mojibake en las entidades!
CDATA
(Datos de caracteres) no tratará las etiquetas dentro del texto como marcas y no expandirá las entidades .
Por lo tanto, siempre que el código de fragmento sin procesar no infrinja la regla 1 (que uno no puede tener el carácter de cierre de contenedor (secuencia) dentro del fragmento), esto no requiere otro escape / codificación.
Claramente, esto se reduce a: cómo podemos minimizar el número de caracteres / secuencias de caracteres que aún deben codificarse en la fuente sin procesar del fragmento y el número de veces que ese carácter (secuencia) puede aparecer en un fragmento promedio; algo que también es importante para el javascript que maneja la traducción de estos caracteres (si se producen).
Entonces, ¿qué ''contenedores'' tienen este contexto CDATA
?
La mayoría de las propiedades de valor de las etiquetas son CDATA, por lo que uno podría (ab) usar una propiedad de valor de la entrada oculta ( prueba de concepto jsfiddle aquí ).
Sin embargo (regla de conformidad 1) crea un problema de codificación / escape con comillas anidadas ( "
y ''
) en el fragmento sin procesar y se necesita algo de javascript para obtener / traducir y establecer el fragmento en otro elemento (visible) (o simplemente configurarlo como un valor de área de texto). De alguna manera esto me dio problemas con entidades en FF (al igual que en un área de texto). Pero en realidad no importa, ya que el ''precio'' de tener que escapar / codificar citas anidadas es mayor que a ( HTML5) textarea (las comillas son bastante comunes en el código fuente ...).
¿Qué hay de intentar (ab) usar <![CDATA[<tag>bla & bla</tag>]]>
?
Como señala Jukka en su respuesta extendida, esto solo funcionaría en (raro) ''xhtml real''.
Pensé en usar una secuencia de comandos (con o sin esa envoltura de CDATA dentro de la secuencia de comandos) junto con un comentario de varias líneas /* */
que envuelve el fragmento en bruto (las etiquetas de secuencia de comandos pueden tener una id
y se puede acceder ellos por cuenta). Pero como esto obviamente introduce un problema de escape con */
, ]]>
y </script
en el fragmento sin formato, esto tampoco parece ser una solución .
Por favor, publique otros ''contenedores'' viables en los comentarios a esta respuesta.
Por cierto, codificar o contar el número de caracteres y equilibrarlos dentro de una etiqueta de comentario <!-- -->
es una locura para este propósito (aparte de la regla 1).
Eso nos deja con la excelente respuesta de Jukka K. Korpela : ¡ la etiqueta <xmp>
parece la mejor opción!
El ''olvidado'' <xmp>
contiene CDATA
, está destinado para este fin Y todavía está en la especificación actual de HTML 5 (y ha sido al menos desde HTML3.2); exactamente lo que necesitamos! También es ampliamente compatible, incluso en IE6 (es decir, hasta que sufre de la misma regresión que el cuerpo de la tabla desplazable).
Nota: como señaló Jukka, esto no funcionará en xhtml verdadero o políglota (que lo tratará como un pre
) y la etiqueta xmp
todavía debe adherirse a la regla n. ° 1. Pero esa es la regla ''única''.
Considere el siguiente marcado:
<!-- ATTENTION: replace any occurrence of </xmp with </xmp -->
<xmp id="snippet-container">
<div>
<div>this is an example div & holds an xmp tag:<br />
<xmp>
<html><head> <!-- indentation col 0!! -->
<title>My Title</title>
</head><body>
<p>hello world !!</p>
</body></html>
</xmp> <!-- note this encoded/escaped tag -->
</div>
This line is also part of the snippet
</div>
</xmp>
El bloque de código anterior ilustra una pieza bruta de marcado donde <xmp id="snippet-container">
contiene un fragmento de código (casi en bruto) (que contiene div>div>xmp>html-document
).
Observe la etiqueta de cierre codificada en este marcado? Para cumplir con la regla no 1, esto fue codificado / escapado).
Así que la inclusión / transporte del código (a veces casi) sin procesar es / parece resuelto.
¿Qué hay de mostrar / renderizar el fragmento (y el codificado </xmp>
)?
El navegador (o debería) renderizar el fragmento (el contenido dentro snippet-container
) exactamente de la manera que lo ve en el bloque de código anterior (con alguna discrepancia entre los navegadores, ya sea que el fragmento comience o no con una línea en blanco).
Eso incluye el formateo / sangría, entidades (como la cadena &
), etiquetas completas, comentarios Y la etiqueta de cierre codificada </xmp>
(tal como estaba codificada en el marcado) . Y dependiendo del navegador (versión), uno podría intentar usar la propiedad contenteditable="true"
para editar este fragmento (todo eso sin javascript habilitado). Hacer algo como textarea.value=xmp.innerHTML
también es muy sencillo.
Entonces puede ... si el fragmento no contiene los contenedores que cierran la secuencia de caracteres.
Sin embargo , si un fragmento en bruto contiene la secuencia de caracteres de cierre </xmp
(porque es un ejemplo de xmp o contiene alguna expresión regular, etc.), debe aceptar que debe codificar / escapar esa secuencia en el fragmento sin formato Y necesita un manejador de Javascript para traducir esa codificación para mostrar / renderizar el </xmp>
como </xmp>
dentro de un área de textarea
(para editar / publicar) o (por ejemplo) un pre
justo para renderizar correctamente el código del fragmento (o parece).
Un ejemplo jsfiddle muy rudimentario de esto aquí . Tenga en cuenta que get / embedding / displaying / retrieving-to-textarea funcionó perfectamente incluso en IE6. Pero establecer el xmp
de xmp
reveló un comportamiento interesante de ''sería-inteligente'' por parte de IE. Hay una nota más amplia y una solución sobre eso en el violín.
Pero ahora viene el kicker importante (otra razón por la que solo te acercas mucho ): al igual que un ejemplo demasiado simplificado, imagina este agujero de conejo :
Fragmento de código sin procesar intencionado:
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Bueno, para cumplir con la regla 1, ''solo'' necesitamos codificar esas </xmp[> /n/r/t/f//]
, ¿verdad?
Eso nos da el siguiente marcado (utilizando solo una posible codificación):
<xmp id="container">
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
</xmp>
Hmm ... ¿obtendré mi bola de cristal o lanzaré una moneda? No, deje que la computadora mire su reloj de sistema y establezca que un número derivado es ''aleatorio''. Sí, eso debería hacerlo ...
Usar una expresión regular como : xmp.innerHTML.replace(/<(?=//xmp[> /n/r/t/f//])/gi, ''<'');
, traduciría ''atrás'' a esto:
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Hmm ... parece que este generador aleatorio está roto ... ¿Houston ...?
Si se olvidó de la broma / problema, vuelva a leer desde el ''fragmento de código sin formato''.
Espera, lo sé, nosotros (también) necesitamos codificar ... para ...
De acuerdo, rebobine el ''fragmento de código sin procesar'' y vuelva a leer.
De alguna manera, todo esto comienza a oler a la famosa respuesta rexgex hilarante pero verdadera en SO , una buena lectura para las personas que dominan el mojibake.
Tal vez alguien sepa un algoritmo o solución inteligente para solucionar este problema, pero supongo que el código incrustado incrustado se volverá cada vez más oscuro hasta el punto en que sería mejor que escapara / codifiques solo tus <
, &
(y >
) , al igual que el resto del mundo.
Conclusión: (usando la etiqueta xmp
)
- se puede hacer con fragmentos conocidos que no contengan la secuencia de caracteres de cierre del contenedor,
- podemos acercarnos mucho al objetivo original con fragmentos conocidos que solo usan el escape / codificación de "primer nivel básico" para que no caigamos en el rabbithole,
- pero al final parece que no se puede hacer esto de manera confiable en un ''entorno de producción'' donde la gente puede / debe copiar / pegar / editar ''cualquier fragmento'' desconocido sin saber / comprender las implicaciones / reglas / rabbithole (dependiendo de su implementación de manejo / traducción para la regla 1 y el agujero de conejo).
¡Espero que esto ayude!
PD: Aunque apreciaría un voto positivo si encuentras útil esta explicación, creo que la respuesta de Jukka debería ser la respuesta aceptada (si no hubiera una mejor opción / respuesta), ya que él era quien recordaba la etiqueta xmp (que yo se olvidó durante años y se "distrajo" con los elementos de PCDATA comúnmente defendidos como pre
, textarea
, etc.).
Esta respuesta se originó al explicar por qué no se puede hacer (con cualquier fragmento de código RAW desconocido) y explicar algunos errores obvios que algunas otras respuestas (ahora eliminadas) se pasan por alto al recomendar un área de texto para incrustación / transporte. Expandí mi explicación existente para que también sea compatible y explique mejor la respuesta de Jukka (dado que toda esa entidad y * CDATA es casi más difícil que las páginas de códigos).
Puede usar el elemento xmp
, ver ¿ Para qué se usó la etiqueta <XMP>? . Ha estado en HTML desde el principio y es compatible con todos los navegadores. Las especificaciones fruncen el ceño, pero HTML5 CR todavía lo describe y requiere que los navegadores lo admitan (aunque también le dice a los autores que no lo usen, pero realmente no puede evitarlo).
Todo dentro de xmp
se toma como tal, no se reconoce ningún marcado (etiquetas o referencias de caracteres), excepto, por razones aparentes, la etiqueta final del elemento en sí, </xmp>
.
De xmp
contrario, xmp
se representa como pre
.
Cuando se utiliza "XHTML real", es decir, XHTML se sirve con un tipo de medio XML (que es raro), las reglas de análisis especiales no se aplican, por lo que xmp
se trata como pre
. Pero en "XHTML real", puede usar una sección CDATA, que implica reglas de análisis similares. No tiene un formato especial, por lo que probablemente quieras envolverlo dentro de un elemento pre
:
<pre><![CDATA[
This is a demo, tags like <p> will
appear literally.
]]></pre>
No veo cómo se podría combinar la sección xmp
y CDATA para lograr el llamado marcado políglota
Respuesta barata y alegre:
<textarea>Some raw content</textarea>
El área de texto manejará pestañas, espacios múltiples, saltos de línea, envoltura de líneas, todo al pie de la letra. Copia y pega bien y su HTML válido hasta el final. También permite al usuario cambiar el tamaño del cuadro de código. No necesita ningún CSS, JS, escape, codificación.
Puedes alterar la apariencia y el comportamiento también. Aquí hay una fuente monoespacial, edición desactivada, fuente más pequeña, sin borde:
<textarea
style="width:100%; font-family: Monospace; font-size:10px; border:0;"
rows="30" disabled
>Some raw content</textarea>
Esta solución probablemente no es semánticamente correcta. Entonces, si lo necesita, podría ser mejor elegir una respuesta más sofisticada.
Si tiene jQuery habilitado, puede usar una función escapeXml y no tener que preocuparse por las flechas o caracteres especiales que se escapan.
<pre>
${fn:escapeXml(''
<!-- all your code -->
'')};
</pre>
xmp
es el camino a seguir, es decir:
<xmp>
# your code...
</xmp>
echo ''<pre>'' . htmlspecialchars("<div><b>raw HTML</b></div>") . ''</pre>'';
Creo que eso es lo que estás buscando?
En otras palabras, use htmlspecialchars () en PHP