如何保留包含在HTML <pre>标记中的文本的空格缩进,排除文档中<pre>标记的当前缩进级别?

我试图在网站上显示我的代码,但我有问题正确保留空白的缩进。

例如给出以下片段:

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

这在浏览器中显示为:

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

当我希望显示为:

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

不同的是HTML标签的当前缩进级别被添加到代码的缩进中。 我使用nanoc作为一个静态网站生成器,我正在使用谷歌美化也添加语法突出显示。

任何人可以提供任何build议?

PRE旨在保留空格,正如出现的一样(除非被CSS中white-space改变,这没有足够的灵活性来支持格式化代码)。

之前

格式化被保留,但PRE标签之外的所有缩进也是如此。 将标签的位置作为起点的空白保存会很好。

在这里输入图像说明

内容仍然按声明格式化,但由PRE标签在文档中的位置引起的外部前导空白将被删除。

在这里输入图像说明

我想出了下面的插件来解决想要删除文档大纲压缩造成的多余的空白的问题。 此代码使用PRE标记中的第一行来确定纯粹由于文档的缩进而缩进了多less。

此代码适用于IE7,IE8,IE9,Firefox和Chrome。 我已经用Prettify库对它进行了简短的testing,将保存的格式与漂亮的打印相结合。 确保PRE中的第一行实际上代表要忽略的缩进的基线级别(或者,您可以修改插件以使其更加智能化)。

这是粗略的代码。 如果您发现错误或者不按照您的方式工作,请修复/评论; 不要只是downvote。 我编写了这个代码来解决我正在使用的一个问题,我正在积极地使用它,所以我希望它尽可能的坚实!

 /*! *** 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 ); 

这个插件可以使用标准的jQueryselect器来应用:

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

缩进评论

由于浏览器忽略注释,因此可以使用它们缩进pre标签内容。

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

pipe理用JavaScript来做到这一点。 它适用于Internet Explorer 9和Chrome 15,我还没有testing旧版本。 当添加了对outerHTML支持时,它应该在Firefox 11中工作(请参阅此处 ),同时在Web上提供了一些自定义实现。 读者的练习是摆脱尾随缩进(直到我花时间完成它并更新这个答案)。

我还会将其标记为社区维基,以便于编辑。

请注意,您将不得不重新格式化该示例以将制表符用作缩进,或更改正则expression式以使用空格。

 <!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> 

这可以在四行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> 
 <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> 

我还发现如果你使用haml,你可以使用preserve方法。 例如:

 preserve yield 

这将保留yield的空白,通常是包含代码块的降价。

我决定拿出更具体的东西,而不是改变precode工作方式。 所以我做了一些正则expression式来获得第一个换行符\n (在可能的空格之前 – \s*用于清除一行代码的末尾的空格,并且在换行符之前(我注意到了它们))并find它后面的制表符或空格字符[\t\s]* (这意味着制表符,空格字符(0或更多),并将该值设置为一个variables。该variables然后用于正则expression式replace函数来查找所有因为第二行( pattern被设置)没有全局标志(在正则expression式之后的一个g ),它会find\n换行符的第一个实例并将patternvariables设置为该值,所以对于换行符,后跟2个制表符, pattern的值在技术上将是\n\t\t ,这将被replace,其中每个\n字符被findpre code元素(因为它正在运行每个函数)并被\nreplace

 $("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> 

这很麻烦,但是如果代码折叠对你很重要的话,

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

在你的CSS中,

  pre { margin:0 } 

在vim中,正常编写代码然后执行:

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

为每一行将工作。

如果你正在使用这样的代码块,如:

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

你可以像这样使用css来抵消前面大量的空白。

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

pre标签保留了在写入身体时使用的所有空白空间。 通常情况下,如果你不使用pre,它会正常显示文本…(HTML将使浏览器忽略这些空白)在这里试试这个我已经使用了段落标记。 输出: –

这是我的代码:

def some_function

 返回'你好,世界!' 

结束

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