如何在PRE或类似的东西显示原始的HTML代码,但不逃避它

我想显示原始的HTML。 我们都知道必须像这样逃避每个“<”和“>”

<PRE> this is a test &ltDIV&gt </PRE> 

但是,我不想这样做。 我想要一种方法来保持HTML代码(因为它更容易阅读,(在编辑器内),我可能想复制它,并再次使用它自己作为实际的HTML代码,并不想再次更改它或有2个版本的相同的代码逃脱一个不逃脱)。

还有其他比PRE更“生”的环境吗? 因此,不必每次都要编辑HTML并更改所有内容,以便每次显示一些原始的HTML代码,都可以在HTML5中进行。

<REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>

屏幕截图

JavaScript的解决scheme不适用于FF 21,这里是屏幕截图 在这里输入图像描述

屏幕截图2

第一个解决scheme仍然不能在Firefox上工作,这里是屏幕截图 在这里输入图像描述

您可以使用xmp元素,请参阅<XMP>标签的用途是什么? 。 它从一开始就一直在HTML中,并得到所有浏览器的支持。 虽然它还告诉作者不要使用它,但它不能真正阻止你),HTML5 CR仍然描述它,并要求浏览器支持它。

xmp所有xmp都是这样的,除了出于明显原因外,没有任何标记(标记或字符引用)被识别,除了元素本身的结束标记</xmp>

否则, xmp就像pre一样呈现。

当使用“真正的XHTML”,即XHTML与XML媒体types(这是罕见的),特殊的parsing规则不适用,所以xmp被视为像pre 。 但在“真正的XHTML”中,可以使用CDATA节,这意味着类似的parsing规则。 它没有特殊的格式,所以你可能想把它包装在一个pre元素中:

 <pre><![CDATA[ This is a demo, tags like <p> will appear literally. ]]></pre> 

我没有看到如何结合xmp和CDATA节来实现所谓的多边形标记

基本上原来的问题可以分成两部分:

  • 主要目标/挑战:在网页的标记中embedded(/传输)原始格式化的代码片段(任何types的代码)(由于没有编码/转义的简单复制/粘贴/编辑)
  • 在浏览器中正确显示/呈现该代码段(可能是编辑它)

(但是)模棱两可的答案是: 你不能但是你可以(非常接近)。
(我知道,这是3个相互矛盾的答案,所以请继续阅读…)

(polyglot)(x)(ht)ml标记语言依赖于包装(几乎)开始/结束和结束/结束标记/字符(序列)之间的所有内容。
所以,为了在你的标记语言中embedded任何types的原始代码/代码片段,我们总是必须转义/编码类似于将closures包装“容器”元素的字符(-sequence)的每个实例标记。 ( 在这篇文章中,我将把它称为规则1)
想一下"some "data" here"或者<i>..close italics with '</i>'-tag</i> ,这是显而易见的。或将容器的引用字符从"更改为' )。

所以,由于规则1, 你不能 '只'embedded任何'未知的原始代码片段内的标记。
因为,如果在原始代码片段中必须转义/编码一个字符,那么该代码片段将不再是原始的“纯原始代码”,任何人都可以在文档的标记中复制/粘贴/编辑, 而不需要进一步考虑 。 这会导致由于实体而导致格式错误/非法标记和Mojibake (主要)。
此外, 如果该代码段包含这样的字符,您仍然需要一些JavaScript将该字符(序列)从(和到)它的转义/编码表示“翻译”为正确显示在“网页”中的片段(用于复制/粘贴/编辑)。

这使我们知道(某些)标记语言指定的数据types。 这些数据types基本上定义了什么被认为是“有效的字符”及其含义(每个标签,属性等):

  • PCDATA (parsing字符数据):将扩展实体,并且必须根据标记语言/版本转义<& (和> )。
    大多数标签,如bodydivpre等,还有textarea (直到HTML5)属于这种types。
    因此,不仅需要在代码片段中编码所有容器的结束字符序列,还必须对所有的<& (, > )字符进行编码(至less)。
    不用说,编码/转义这些字符不在这个目标的embedded原始代码片段的范围之内。
    “但是一个textarea似乎工作…”,是的,无论是因为浏览器错误引擎试图做出来的东西,或因为HTML5:

  • RCDATA (可replace字符数据):不会将文本内的标签视为标记(但仍由规则1pipe理),因此不需要对<> )进行编码。 但实体仍然扩展,所以它们和“模糊的&”( & )需要特别小心。
    目前的 HTML5规范说textarea现在是一个RCDATA字段和(报价):

    raw textRCDATA元素中的raw text 不得包含任何出现的string"</" (U + 003C LESS-THAN SIGN,U + 002F SOLIDUS),后面跟随不区分大小写匹配元素的标签名称的字符U + 009字符进纸(LF),U + 000C进纸进纸(FF),U + 000D装运返回(CR),U + 0020空格,U + 003E大号符号(>)或U + 002F SOLIDUS(/)。

    因此无论如何,textarea需要一个庞大的实体翻译处理程序,或者最终实体Mojibake!

  • CDATA (字符数据) 不会将文本内的标签视为标记,也不会扩展实体
    因此,只要原始代码片段代码不违反规则1(代码片段中不能包含容器closures字符(序列)),则不需要其他转义/编码。

显然, 这可以归结为:我们怎样才能最大限度地减less片段的原始来源中仍然需要编码的字符/字符序列的数量以及字符(序列)在平均片段中可能出现的次数; 这对于处理这些字符的翻译(如果它们发生的话)来说也是重要的。

那么什么“容器”有这个CDATA上下文?

标签的大部分属性值都是CDATA,所以可以 (ab)使用一个隐藏的input的值属性( 这里是jsfiddle的概念certificate )。
然而(符合规则1)这会在原始代码片段中使用嵌套引号( "' )创build一个编码/转义问题,需要一些JavaScript来获取/翻译,并在另一个(可见)元素中设置片段(或者简单地将其设置为一个文本区域的值),不知怎的,这给了FF中的实体问题(就像在textarea中一样),但这并不重要,因为必须对嵌套引号进行转义/编码的“价格”高于HTML5)textarea(引号在源代码中很常见..)。

如何尝试(ab)使用<![CDATA[<tag>bla & bla</tag>]]>
Jukka在他的扩展答案中指出,这只会在(罕见的)“真正的xhtml”中起作用。
我想过使用一个脚本标签(在脚本标签内有或没有这样一个CDATA包装器)和一个包含原始代码片段的多行注释/* */ (脚本标签可以有一个id ,你可以访问他们通过计数)。 但是,因为这显然引入了原始代码片段中的*/]]></script的转义问题,所以这看起来似乎也不是解决scheme

请发表其他可行的“容器”在这个答案的评论。

顺便说一下,编码或计算字符数量并在注释标记<!-- -->内平衡它们只是为了这个目的而疯狂(除了规则1之外)。


这让我们留下了Jukka K. Korpela的出色答案 : <xmp>标签似乎是最好的select!

“被遗忘”的<xmp>包含CDATA ,是为了这个目的,并且确实仍然在当前的 HTML 5规范中 (至less从HTML3.2开始); 正是我们需要的! 它也被广泛的支持,即使在IE6中(也就是说,直到它遭受与滚动表体相同的回退)。
注意:正如Jukka所指出的那样,在真正的xhtml或者polyglot中(这将被视为pre ), xmp标签仍然必须遵守规则1,这是xmp 。但是这是'唯一'的规则。

考虑以下标记:

 <!-- ATTENTION: replace any occurrence of &lt;/xmp with </xmp --> <xmp id="snippet-container"> <div> <div>this is an example div &amp; holds an xmp tag:<br /> <xmp> <html><head> <!-- indentation col 0!! --> <title>My Title</title> </head><body> <p>hello world !!</p> </body></html> &lt;/xmp> <!-- note this encoded/escaped tag --> </div> This line is also part of the snippet </div> </xmp> 

上面的codeblok演示了一个原始的标记,其中<xmp id="snippet-container">包含一个(几乎是原始的)代码片段(包含div>div>xmp>html-document )。
注意这个标记中的编码结束标记? 遵守规则1,这是编码/逃脱)。

所以embedded/传输(有时几乎)原始代码似乎已经解决了。

显示/呈现片段(和编码的&lt;/xmp> )是什么?

浏览器将(或它应该)以上面代码块中的方式呈现代码片段( snippet-container的内容)(浏览器之间有些差异,无论代码片段是否以空行开头)。
包括格式化/缩进,实体(如string&amp; ),完整标记,注释和编码结束标记&lt;/xmp> (就像它在标记中被编码一样) 。 根据浏览器(版本),甚至可以尝试使用属性contenteditable="true"编辑此片段(所有没有启用javascript的)。 做一些像textarea.value=xmp.innerHTML也是一件轻而易举的事情。

所以你可以如果代码片段不包含closures字符序列的容器。

但是如果原始代码片段包含结束字符序列</xmp (因为它是xmp本身的一个例子,或者它包含一些正则expression式等),您必须接受必须在原始代码片段中编码/转义该序列需要一个JavaScript处理程序来翻译该编码,以在textarea (用于编辑/发布)内显示/呈现编码的&lt;/xmp> like </xmp>或(例如)只是为了正确地呈现片段的代码它似乎)。

这是一个非常简单的jsfiddle例子 。 请注意,即使在IE6中,获取/embedded/显示/检索到textarea也是完美的。 但是设置xmpinnerHTML显示出一些IE上有意思的“将会聪明”的行为。 在小提琴上有一个更广泛的注意和解决方法。

但现在是重要的踢球者 (另一个为什么只能靠得很近的原因):就像一个过于简化的例子,想象一下这个兔子洞

原定的原始代码片段:

 <!-- remember to translate between </xmp> and &lt;/xmp> --> <xmp> <p>a paragraph</p> </xmp> 

那么为了符合规则1,我们只需要编码这些序列,对吗?

所以给我们下面的标记(只使用一个可能的编码):

 <xmp id="container"> <!-- remember to translate between &lt;/xmp> and &lt;/xmp> --> <xmp> <p>a paragraph</p> &lt;/xmp> </xmp> 

嗯,我要拿到水晶球还是掷硬币? 不,让电脑看看它的系统时钟,并说明派生号码是“随机的”。 是的,应该这样做..

使用正则expression式: xmp.innerHTML.replace(/&lt;(?=\/xmp[> \n\r\t\f\/])/gi, '<'); ,将“回”翻译成:

 <!-- remember to translate between </xmp> and </xmp> --> <xmp> <p>a paragraph</p> </xmp> 

嗯..似乎这个随机发生器坏了…休斯敦..?
如果您错过了这个笑话/问题,请从“原始代码片段”开始重新阅读。

等等,我知道,我们(也)需要编码….到….
好的,回到“原始代码片段”并重新阅读。
不知何故,这一切开始闻起来像这个着名的欢闹,但是真正的rexgex-答案 ,这是一个很好的阅读,让人stream利mojibake。

也许有人知道一个聪明的algorithm或解决scheme来解决这个问题,但我认为embedded的原始代码会变得越来越模糊,你会更好地转义/编码只是你的<& (和) ,就像世界其他地方一样。

结论:(使用xmp标签)

  • 可以用已知的片段来完成,该片段不包含容器的closures字符序列,
  • 我们可以非常接近最初的目标,只使用“基本的第一级”转义/编码的已知片段,所以我们不落入拉比,
  • 最终看来,人们不能在“生产环境”中可靠地做到这一点,人们可以/应该复制/粘贴/编辑“任何未知的”原始片段,而不知道/理解含义/规则/拉比索(取决于您的执行规则1和兔子洞的处理/翻译)。

希望这可以帮助!

PS:虽然如果你觉得这个解释很有用的话,我会很高兴,但我认为Jukka的答案应该是被接受的答案(应该没有更好的select/答案来),因为他是记得xmp标签的人忘记了多年来被普遍主张的PCDATA元素(如pretextarea等)所“分心”。
这个答案起源于解释为什么你不能做到这一点(与任何未知的原始代码片段),并解释一些明显的陷阱,其他(现在删除)答案忽略了build议textareaembedded/运输。 我已经扩展了我现有的解释,以支持和进一步解释Jukka的答案(因为所有的实体和* CDATA的东西比代码页更难)。

 echo '<pre>' . htmlspecialchars("<div><b>raw HTML</b></div>") . '</pre>'; 

我想这就是你要找的东西?

换句话说,在PHP中使用htmlspecialchars()

@GitaarLAB和@Jukka详细说明<xmp>标签已经过时,但仍然是最好的。 当我这样使用它

 <xmp> <div>Lorem ipsum</div> <p>Hello</p> </xmp> 

那么在代码中插入第一个EOL, 看起来很糟糕 。

可以通过删除EOL来解决

 <xmp><div>Lorem ipsum</div> <p>Hello</p> </xmp> 

但是在源头上看起来很糟糕。 我曾经用wrap <div>来解决它,但是最近我想出了一个很好的CSS3规则,我希望它也能帮助别人:

 xmp { margin: 5px 0; padding: 0 5px 5px 5px; background: #CCC; } xmp:before { content: ""; display: block; height: 1em; margin: 0 -5px -2em -5px; } 

这看起来更好 。

便宜又快乐的回答:

 <textarea>Some raw content</textarea> 

textarea将处理制表符,多个空格,换行符,逐行换行。 它一路复制并粘贴好它的有效HTML。 它也允许用户调整代码框的大小。 你不需要任何CSS,JS,转义,编码。

您也可以改变外观和行为。 这是一个等宽字体,禁止编辑,较小的字体,没有边框:

 <textarea style="width:100%; font-family: Monospace; font-size:10px; border:0;" rows="30" disabled >Some raw content</textarea> 

这个解决scheme可能在语义上不正确。 所以如果你需要的话,最好select一个更复杂的答案。

如果你已经启用了jQuery,你可以使用escapeXml函数,而不必担心转义的箭头或特殊字符。

 <pre> ${fn:escapeXml(' <!-- all your code --> ')}; </pre> 

xmp是要走的路,即:

 <xmp> # your code... </xmp>