如何在PRE或类似的东西显示原始的HTML代码,但不逃避它
我想显示原始的HTML。 我们都知道必须像这样逃避每个“<”和“>”
<PRE> this is a test <DIV> </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字符数据):将扩展实体,并且必须根据标记语言/版本转义<
,&
(和>
)。
大多数标签,如body
,div
,pre
等,还有textarea
(直到HTML5)属于这种types。
因此,不仅需要在代码片段中编码所有容器的结束字符序列,还必须对所有的<
,&
(,>
)字符进行编码(至less)。
不用说,编码/转义这些字符不在这个目标的embedded原始代码片段的范围之内。
“但是一个textarea似乎工作…”,是的,无论是因为浏览器错误引擎试图做出来的东西,或因为HTML5: -
RCDATA
(可replace字符数据):不会将文本内的标签视为标记(但仍由规则1pipe理),因此不需要对<
(>
)进行编码。 但实体仍然扩展,所以它们和“模糊的&”(&
)需要特别小心。
目前的 HTML5规范说textarea现在是一个RCDATA
字段和(报价):raw text
和RCDATA
元素中的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 </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>
上面的codeblok演示了一个原始的标记,其中<xmp id="snippet-container">
包含一个(几乎是原始的)代码片段(包含div>div>xmp>html-document
)。
注意这个标记中的编码结束标记? 遵守规则1,这是编码/逃脱)。
所以embedded/传输(有时几乎)原始代码似乎已经解决了。
显示/呈现片段(和编码的</xmp>
)是什么?
浏览器将(或它应该)以上面代码块中的方式呈现代码片段( snippet-container
的内容)(浏览器之间有些差异,无论代码片段是否以空行开头)。
这包括格式化/缩进,实体(如string&
),完整标记,注释和编码结束标记</xmp>
(就像它在标记中被编码一样) 。 根据浏览器(版本),甚至可以尝试使用属性contenteditable="true"
编辑此片段(所有没有启用javascript的)。 做一些像textarea.value=xmp.innerHTML
也是一件轻而易举的事情。
所以你可以 … 如果代码片段不包含closures字符序列的容器。
但是 , 如果原始代码片段包含结束字符序列</xmp
(因为它是xmp本身的一个例子,或者它包含一些正则expression式等),您必须接受必须在原始代码片段中编码/转义该序列需要一个JavaScript处理程序来翻译该编码,以在textarea
(用于编辑/发布)内显示/呈现编码的</xmp>
like </xmp>
或(例如)只是为了正确地呈现片段的代码它似乎)。
这是一个非常简单的jsfiddle例子 。 请注意,即使在IE6中,获取/embedded/显示/检索到textarea也是完美的。 但是设置xmp
的innerHTML
显示出一些IE上有意思的“将会聪明”的行为。 在小提琴上有一个更广泛的注意和解决方法。
但现在是重要的踢球者 (另一个你为什么只能靠得很近的原因):就像一个过于简化的例子,想象一下这个兔子洞 :
原定的原始代码片段:
<!-- remember to translate between </xmp> and </xmp> --> <xmp> <p>a paragraph</p> </xmp>
那么为了符合规则1,我们只需要编码这些序列,对吗?
所以给我们下面的标记(只使用一个可能的编码):
<xmp id="container"> <!-- remember to translate between </xmp> and </xmp> --> <xmp> <p>a paragraph</p> </xmp> </xmp>
嗯,我要拿到水晶球还是掷硬币? 不,让电脑看看它的系统时钟,并说明派生号码是“随机的”。 是的,应该这样做..
使用正则expression式: xmp.innerHTML.replace(/<(?=\/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元素(如pre
, textarea
等)所“分心”。
这个答案起源于解释为什么你不能做到这一点(与任何未知的原始代码片段),并解释一些明显的陷阱,其他(现在删除)答案忽略了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>