style initial html whitespace indentation pre

html - style - white space initial



¿Cómo preservar la sangría del espacio en blanco del texto incluido en las etiquetas HTML<pre> excluyendo el nivel de sangría actual de la etiqueta<pre> en el documento? (10)

Intento mostrar mi código en un sitio web pero tengo problemas para preservar la sangría del espacio en blanco correctamente.

Por ejemplo, dado el siguiente fragmento:

<html> <body> Here is my code: <pre> def some_funtion return ''Hello, World!'' end </pre> <body> </html>

Esto se muestra en el navegador como:

Here is my code: def some_funtion return ''Hello, World!'' end

Cuando me gustaría que se muestre como:

Here is my code: def some_funtion return ''Hello, World!'' end

La diferencia es que ese nivel de sangría actual de la pre etiqueta HTML se agrega a la sangría del código. Estoy usando nanoc como generador de sitios web estáticos y estoy usando google prettify para agregar también resaltado de sintaxis.

¿Puede alguien ofrecer algunas sugerencias?


Sangría con comentarios

Como los navegadores ignoran los comentarios, puede usarlos para sangrar pre contenidos de su etiqueta pre .

Solución

<html> <body> <main> Here is my code with hack: <pre> <!-- -->def some_function <!-- --> return ''Hello, World!'' <!-- -->end </pre> Here is my code without hack: <pre> def some_function return ''Hello, World!'' end </pre> </main> <body> </html>

NOTA: se agregó un contenedor principal para proporcionar suficiente espacio para los comentarios.

Ventajas

  • No se requiere JavaScript
  • Se puede agregar estáticamente
  • La minificación no afectará la sangría y reduce el tamaño del archivo

Desventajas

  • Requiere una cantidad mínima de espacio para los comentarios
  • No es muy elegante a menos que se utilicen herramientas de construcción

Eliminar sangría con nodo

Una mejor solución es eliminar el espacio en blanco líder usando su proceso de compilación o proceso de renderización de back-end. Si está utilizando node.js, puede usar una secuencia que escribí llamada predentation . Puede usar cualquier idioma que desee para construir una herramienta similar.

antes de

<html> <body> Here is my code: <pre> def some_function return ''Hello, World!'' end </pre> </body> </html>

Después

<html> <body> Here is my code: <pre> def some_function return ''Hello, World!'' end </pre> </body> </html>

Ventajas

  • Forma perfecta de escribir etiquetas pre
  • Tamaño de archivo de salida más pequeño

Desventajas

  • Requiere un paso de compilación en su flujo de trabajo
  • No maneja elementos no pre con white-space: pre añadidos por CSS

Eliminar sangría con JavaScript

Vea esta respuesta para eliminar la sangría con JavaScript

Ventajas

  • Posible apuntar elementos con white-space: pre

Desventajas

  • JavaScript puede ser deshabilitado
  • El espacio en blanco se agrega al tamaño del archivo

Decidí llegar a algo más concreto que cambiar la forma en que funciona el pre o el code . Así que hice algunos regex para obtener el primer carácter de nueva línea /n (precedido de posibles espacios en blanco - el /s* se usa para limpiar espacios en blanco adicionales al final de una línea de código y antes del carácter de nueva línea (que noté que el tuyo tenía)) y encuentre los caracteres de tabulación o de espacios en blanco que lo siguen [/t/s]* (lo que significa carácter de tabulación, carácter de espacio en blanco (0 o más) y establezca ese valor en una variable. instancias de ello y reemplazarlo con /n (nueva línea). Dado que la segunda línea (donde se establece el pattern ) no tiene la bandera global (una g después de la expresión regular), encontrará la primera instancia del carácter /n nueva línea y establecer la variable de pattern a ese valor. Por lo tanto, en el caso de una línea nueva, seguida de 2 caracteres de tabulación, el valor del pattern será /n/t/t técnicamente, que se reemplazará cuando se encuentre cada carácter /n en ese elemento de pre code (ya que se ejecuta a través de cada función) y reemplazado con /n

$("pre code").each(function(){ var html = $(this).html(); var pattern = html.match(//s*/n[/t/s]*/); $(this).html(html.replace(new RegExp(pattern, "g"),''/n'')); });

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <body> Here is some code: <pre><code> Here is some fun code! More code One tab One more tab Two tabs and an extra newline character precede me </code></pre> </body>


Esto es engorroso, pero funciona si el plegado de código es importante para usted:

<pre>def some_funtion</pre> <pre> return ''Hello, World!''</pre> <pre>end</pre>

En tu css,

pre { margin:0 }

En vim, escriba su código normalmente y luego ejecute:

:s//t/t/([^/n]/+/)/<pre>/1<//pre>/

para cada línea funcionaría.


Esto se puede hacer en cuatro líneas de JavaScript:

var pre= document.querySelector(''pre''); //insert a span in front of the first letter. (the span will automatically close.) pre.innerHTML= pre.textContent.replace(/(/w)/, ''<span>$1''); //get the new span''s left offset: var left= pre.querySelector(''span'').getClientRects()[0].left; //move the code to the left, taking into account the body''s margin: pre.style.marginLeft= (-left + pre.getClientRects()[0].left)+''px'';

<body> Here is my code: <pre> def some_funtion return ''Hello, World!'' end </pre> <body>


La etiqueta previa conserva todos los espacios en blanco que ha usado mientras escribía en el cuerpo. Donde normalmente, si no usas pre, mostrará el texto normalmente ... (HTML hará que el navegador descuide esos espacios en blanco) Aquí prueba esto. He usado la etiqueta de párrafo. Salida:-

Aquí está mi código:

def some_function

return ''Hello, World!''

fin

<html> <body> Here is my code: <p> def some_function<br> <pre> return ''Hello, World!''<br></pre> end </p> </body> </html>

Se las arregló para hacer esto con JavaScript. Funciona en Internet Explorer 9 y Chrome 15, no he probado versiones anteriores. Debería funcionar en Firefox 11 cuando se agrega soporte para outerHTML (ver here ), mientras tanto, hay algunas implementaciones personalizadas disponibles en la web. Un ejercicio para el lector es deshacerse de la sangría final (hasta que tenga tiempo de terminarla y actualizar esta respuesta).

También marcaré esto como wiki de la comunidad para una fácil edición.

Tenga en cuenta que tendrá que volver a formatear el ejemplo para usar pestañas como sangría, o cambiar la expresión regular para trabajar con espacios.

<!DOCTYPE html> <html> <head> <title>Hello, World!</title> </head> <body> <pre> &lt;html&gt; &lt;head&gt; &lt;title&gt;Hello World Example&lt;/title&gt; &lt;/head&gt; &lt;body&gt; Hello, World! &lt;/body&gt; &lt;/html&gt; </pre> <pre> class HelloWorld { public static int Main(String[] args) { Console.WriteLine(&amp;quot;Hello, World!&amp;quot;); return 0; } } </pre> <script language="javascript"> var pre_elements = document.getElementsByTagName(''pre''); for (var i = 0; i < pre_elements.length; i++) { var content = pre_elements[i].innerHTML; var tabs_to_remove = ''''; while (content.indexOf(''/t'') == ''0'') { tabs_to_remove += ''/t''; content = content.substring(1); } var re = new RegExp(''/n'' + tabs_to_remove, ''g''); content = content.replace(re, ''/n''); pre_elements[i].outerHTML = ''<pre>'' + content + ''</pre>''; } </script> </body> </html>


Si está usando esto en un bloque de código como:

<pre> <code> ... </code> </pre>

Simplemente puede usar css como este para compensar esa gran cantidad de espacio en blanco en el frente.

pre code { position: relative; left: -95px; // or whatever you want }


También encontré que si está utilizando haml puede usar el método de preserve . Por ejemplo:

preserve yield

Esto preservará el espacio en blanco en el yield producido, que generalmente es un descuento que contiene los bloques de código.


PRE está destinado a preservar el espacio en blanco exactamente como aparece (a menos que sea alterado por white-space en white-space en CSS, que no tiene suficiente flexibilidad para admitir el código de formato).

antes de

El formato se conserva, pero también lo es toda la sangría fuera de la etiqueta PRE . Sería bueno tener una preservación del espacio en blanco que usara la ubicación de la etiqueta como punto de partida.

Después

Los contenidos están formateados como declarados, pero se eliminan los espacios en blanco iniciales extraños causados ​​por la posición de la etiqueta PRE dentro del documento.

He creado el siguiente complemento para resolver el problema de querer eliminar el espacio en blanco superfluo causado por la sangría del contorno del documento. Este código usa la primera línea dentro de la etiqueta PRE para determinar cuánto se ha sangrado por pura indentación del documento.

Este código funciona en IE7, IE8, IE9, Firefox y Chrome. Lo he probado brevemente con la biblioteca Prettify para combinar el formato preservado con una bonita impresión. Asegúrese de que la primera línea dentro del PRE realidad represente el nivel de sangría inicial que desea ignorar (o puede modificar el plugin para que sea más inteligente).

Este es un código aproximado. Si encuentra un error o no funciona de la manera que desea, corrija / comente; no solo downvote. ¡Escribí este código para solucionar un problema que estaba teniendo y lo estoy usando activamente así que me gustaría que sea lo más sólido posible!

/*! *** prettyPre ***/ (function( $ ) { $.fn.prettyPre = function( method ) { var defaults = { ignoreExpression: //s/ // what should be ignored? }; var methods = { init: function( options ) { this.each( function() { var context = $.extend( {}, defaults, options ); var $obj = $( this ); var usingInnerText = true; var text = $obj.get( 0 ).innerText; // some browsers support innerText...some don''t...some ONLY work with innerText. if ( typeof text == "undefined" ) { text = $obj.html(); usingInnerText = false; } // use the first line as a baseline for how many unwanted leading whitespace characters are present var superfluousSpaceCount = 0; var currentChar = text.substring( 0, 1 ); while ( context.ignoreExpression.test( currentChar ) ) { currentChar = text.substring( ++superfluousSpaceCount, superfluousSpaceCount + 1 ); } // split var parts = text.split( "/n" ); var reformattedText = ""; // reconstruct var length = parts.length; for ( var i = 0; i < length; i++ ) { // cleanup, and don''t append a trailing newline if we are on the last line reformattedText += parts[i].substring( superfluousSpaceCount ) + ( i == length - 1 ? "" : "/n" ); } // modify original if ( usingInnerText ) { $obj.get( 0 ).innerText = reformattedText; } else { // This does not appear to execute code in any browser but the onus is on the developer to not // put raw input from a user anywhere on a page, even if it doesn''t execute! $obj.html( reformattedText ); } } ); } } if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) ); } else if ( typeof method === "object" || !method ) { return methods.init.apply( this, arguments ); } else { $.error( "Method " + method + " does not exist on jQuery.prettyPre." ); } } } )( jQuery );

Este complemento se puede aplicar utilizando un selector jQuery estándar:

<script> $( function() { $("PRE").prettyPre(); } ); </script>


<script> $("pre[name=''pre'']").each(function () { var html = $(this).html() var blankLen = (html.split(''/n'')[0].match(/^/s+/)[0]).length $(this).html($.trim(html.replace(eval("/^ {" + blankLen + "}/gm"), ""))) }) </script>

<div> <pre name="pre"> 1 2 3 </pre> </div>