如何在PRE或类似的东西中显示原始html代码但不转义它

Rob*_*t H 58 html pre

我想显示原始HTML.我们都知道必须像这样逃避每个"<"和">"

     <PRE> this is a test  &ltDIV&gt </PRE>
Run Code Online (Sandbox Code Playgroud)

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

是否有任何其他环境比PRE更"原始"可能允许这样做?因此,每次他们想要显示一些原始HTML代码时,不必继续编辑HTML并更改所有内容,可能是HTML5中的?

就像是 <REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>

屏幕截图

JavaScript解决方案在FF 21上不起作用,这是屏幕截图 在此输入图像描述

屏幕截图2

第一个解决方案仍然无法在Firefox上运行,这里是屏幕截图 在此输入图像描述

Juk*_*ela 91

您可以使用该xmp元素,请参阅用于的<XMP>标记是什么?.它从一开始就是HTML,并且得到所有浏览器的支持.规格不好看,但HTML5 CR仍然描述它并要求浏览器支持它(虽然它也告诉作者不要使用它,但它不能真正阻止你).

内部的所有内容xmp都是这样的,没有标记(标记或字符引用)在那里被识别,除了明显的原因,元素本身的结束标记,</xmp>.

否则xmp呈现为pre.

当使用"真正的XHTML"时,即XHTML使用XML媒体类型(很少见),特殊的解析规则不适用,因此xmp被视为pre.但在"真正的XHTML"中,您可以使用CDATA部分,这意味着类似的解析规则.它没有特殊的格式,所以你可能想把它包装在一个pre元素中:

<pre><![CDATA[
This is a demo, tags like <p> will
appear literally.
]]></pre>
Run Code Online (Sandbox Code Playgroud)

我不知道如何组合xmp和CDATA部分来实现所谓的多语言标记

  • +1优秀!你知道在多语言等中是否也支持这个`<xmp>`吗?另外,是否有一个(x)(ht)ml版本,其中可以使用`<![CDATA [<tag> bla&bla </ tag>]]>` (3认同)
  • xmp是一个过时的标签. (3认同)
  • @jlguenego,当然有这样的声明,你知道你需要[\ [[需要引用]](http://xkcd.com/285)? (2认同)

Git*_*LAB 22

基本上,原始问题可以分为两部分:

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

简短(但)含糊不清的答案是:你不能,......但你可以(非常接近).
(我知道,这是3个相互矛盾的答案,所以请继续阅读......)

(polyglot)(x)(ht)ml标记语言依赖于(几乎)包含开始/打开和结束/结束标记/字符(序列)之间的所有内容.
因此,要在标记语言中嵌入任何类型的原始代码/片段,人们将始终必须转义/编码类似于将关闭包装"容器"元素的字符(-sequence)的每个实例(在该片段内)标记.(在这篇文章中,我将其称为规则1.)
想想"some "data" here"或者<i>..close italics with '</i>'-tag</i>,显而易见的是,应该转义/编码(某些内容)</i"(或将容器的引号字符更改"').

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

这将我们带到(某些)标记语言指定的数据类型.这些数据类型基本上定义了什么被认为是"有效字符"及其含义(每个标记,属性等):

  • PCDATA(解析的字符数据):将扩大实体和一个必须逃脱<,&(并>视标记语言/版).
    最喜欢的标签body,div,pre等,但也textarea(直到HTML5)属于这一类型下.
    因此,您不仅需要对代码段内所有容器的结束字符序列进行编码<,还必须对所有&(,>)字符进行编码(至少).
    毋庸置疑,编码/转义这么多字符不属于此目标在标记中嵌入原始片段的范围.
    '但是,textarea似乎有用......',是的,要么是因为浏览器错误引擎试图用它做出一些东西,要么是因为HTML5:

  • RCDATA(可替换字符数据):不会将文本中的标记视为标记(但仍受规则1控制),因此不需要编码<(>).但实体仍在扩展,因此他们和"模糊的&符"(&)需要特别小心.
    目前的 HTML5规范说,现在textarea的是RCDATA和(报价):

    文本raw textRCDATA元素不得包含任何出现的字符串"</"(U + 003C LESS-THAN SIGN,U + 002F SOLIDUS),后跟字符不区分大小写的元素的标记名称后跟U + 0009 CHARACTER TABULATION (标签),U + 000A LINE FEED(LF),U + 000C FORM FEED(FF),U + 000D CARRYAGE RETURN(CR),U + 0020 SPACE,U + 003E GREATER-THAN SIGN(>)或U + 002F SOLIDUS(/).

    无论如何,textarea需要一个庞大的实体翻译处理程序,否则它最终成为Mojibake实体!

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

显然,这归结为:我们如何最小化仍然需要在片段的原始源中编码的字符/字符序列的数量以及字符(序列)可能出现在平均片段中的次数; 对于处理这些字符翻译的javascript(如果它们发生)也很重要的东西.

那么'容器'有这种CDATA背景吗?

标签的大多数值属性都是CDATA,因此可以(ab)使用隐藏输入的值属性(此处概念证明为jsfiddle).
但是(符合规则1)这会在原始代码段中创建嵌套引号("')的编码/转义问题,并且需要一些javascript来获取/翻译并将代码段设置为另一个(可见)元素(或者只是将其设置为文本-area的价值).不知何故,这给了我FF实体的问题(就像在textarea中一样).但这并不重要,因为必须转义/编码嵌套引号的"价格"高于(HTML5)textarea(引用在源代码中非常常见..).

尝试(ab)使用<![CDATA[<tag>bla & bla</tag>]]>怎么样?
正如Jukka在他的扩展答案中指出的那样,这只适用于(罕见的)"真正的xhtml".
我想过使用脚本标记(在脚本标记内有或没有这样的CDATA包装)以及包含/* */原始片段的多行注释(脚本标记可以有一个id,你可以通过计数访问它们).但是,由于这显然引入了一个逃避问题*/,]]>并且</script在原始片段中,这似乎也不是解决方案.

请在评论的评论中发布其他可行的"容器".

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


这给我们留下了Jukka K. Korpela的出色答卷:<xmp>标签似乎是最好的选择!

'遗忘' <xmp>成立CDATA,用于此目的并且确实仍然当前的 HTML 5规范中(并且至少从HTML3.2开始); 正是我们需要的!它也被广泛支持,即使在IE6中(直到它遭受与滚动表体相同的回归).
注意:正如Jukka指出的那样,这不适用于真正的xhtml或多语言(将其视为a pre),并且xmp标签必须仍然遵守规则1.但这是"唯一"规则.

考虑以下标记:

<!-- 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>
Run Code Online (Sandbox Code Playgroud)

上面的代码插图说明了一个原始的标记,其中<xmp id="snippet-container">包含一个(几乎是原始的)代码片段(包含div>div>xmp>html-document).
注意这个标记中的编码结束标记?为了遵守规则1,这是编码/转义的.

因此,嵌入/传输(有时几乎)原始代码似乎已经解决了.

那么显示/渲染片段(以及编码的&lt;/xmp>)呢?

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

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

但是,如果原始片段包含结束字符序列</xmp(因为它是xmp本身的一个示例或它包含一些正则表达式等),您必须接受必须在原始片段中编码/转义该序列并且需要javascript处理器把这种编码显示/渲染编码&lt;/xmp></xmp>textarea(编辑/发帖)或(例如)pre只是为了正确渲染片断的代码(或者看起来是这样).

这里有一个非常基本的jsfiddle例子.请注意,即使在IE6中,获取/嵌入/显示/检索到textarea也能完美运行.但设置xmpinnerHTML透露了一些有趣的'关于IE的部分将待智能’的行为.在小提琴中有更广泛的注释和解决方法.

但现在是重要的踢球者(另一个原因,你只能非常接近):就像一个过于简化的例子,想象一下这个兔子洞:

预期的原始代码段:

<!-- remember to translate between </xmp> and &lt;/xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Run Code Online (Sandbox Code Playgroud)

那么,为了遵守规则1,我们只需要对这些</xmp[> \n\r\t\f\/]序列进行编码,对吧?

这样就为我们提供了以下标记(仅使用可能的编码):

<xmp id="container">
<!-- remember to translate between &lt;/xmp> and &lt;/xmp> -->
<xmp>
<p>a paragraph</p>
&lt;/xmp>
</xmp>
Run Code Online (Sandbox Code Playgroud)

嗯..我得到我的水晶球还是翻硬币?不,让计算机查看其系统时钟并声明派生数字是"随机"的.是的,应该这样做..

使用正则表达式一样:xmp.innerHTML.replace(/&lt;(?=\/xmp[> \n\r\t\f\/])/gi, '<');,将转化"回"到这一点:

<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Run Code Online (Sandbox Code Playgroud)

嗯..似乎这个随机发电机坏了...休斯顿..?
如果您错过了笑话/问题,请从"预期的原始代码片段"开始再次阅读.

等等,我知道,我们(也)需要编码......来......
好吧,回到'预期的原始代码片段'并再次阅读.
不知何故,这一切都开始闻起来就像着名的热闹但真实的rexgex-answer on SO,对于流利的mojibake的人来说是一个很好的阅读.

也许有人知道一个聪明的算法或解决方案来解决这个问题,但我认为嵌入式原始代码会变得越来越模糊,以至于你更好地正确转义/编码你的<,&(和>),就像剩下的世界.

结论:(使用xmp标签)

  • 它可以使用不包含容器的关闭字符序列的已知片段来完成,
  • 我们可以使用已知的片段非常接近原始目标,这些片段仅使用"基本的第一级"转义/编码,因此我们不会落入rabbithole,
  • 最终似乎无法在"生产环境"中可靠地做到这一点,人们可以/应该复制/粘贴/编辑"任何未知的"原始片段,同时不知道/理解含义/规则/ rabbithole(取决于你的)执行处理/翻译规则1和兔子洞).

希望这可以帮助!

PS:虽然如果你觉得这个解释很有用,我会很感激,我觉得Jukka的答案应该是公认的答案(不应该有更好的选择/答案),因为他是那个记住xmp标签的人(我忘了多年来得到了由共同倡导PCDATA元素,如"分心" pre,textarea等).
这个答案起源于解释为什么你不能这样做(带有任何未知的原始片段)并解释一些明显的陷阱,其他一些(现在删除的)答案在建议textarea嵌入/传输时被忽略了.我已经扩展了我现有的解释,也支持并进一步解释了Jukka的答案(因为所有实体和*CDATA的东西几乎比代码页更难).


Hen*_*nry 8

便宜又开朗的回答:

<textarea>Some raw content</textarea>
Run Code Online (Sandbox Code Playgroud)

textarea将逐字处理标签,多个空格,换行符,换行.它可以很好地复制和粘贴它的有效HTML.它还允许用户调整代码框的大小.您不需要任何CSS,JS,转义,编码.

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

<textarea
    style="width:100%; font-family: Monospace; font-size:10px; border:0;"
    rows="30" disabled
>Some raw content</textarea>
Run Code Online (Sandbox Code Playgroud)

该解决方案可能在语义上不正确.因此,如果您需要,最好选择更复杂的答案.


Ped*_*ito 5

xmp 是要走的路,即:

<xmp>
  # your code...
</xmp>
Run Code Online (Sandbox Code Playgroud)