我想显示原始HTML。我们都知道必须逃避每个“<”和“>”像这样
<PRE> this is a test <DIV> </PRE>
但是,我不想这样做。我想要一种方法来保持HTML代码(因为它更容易阅读,(在编辑器内)我可能想要复制它并自己再次使用它作为实际的HTML代码,并且不希望再次更改它或者有两个版本的相同代码一个转义,一个没有转义)。
是否有任何其他环境比PRE更“原始”可能允许这样做?因此,每次他们想要显示一些原始HTML代码时,不必继续编辑HTML并更改所有内容,可能是HTML5格式吗?
像<REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>
屏幕截图
javascript解决方案在FF 21上不起作用,这是屏幕截图
屏幕截图2
第一个解决方案仍然无法在firefox上运行,这里是屏幕截图
答案 0 :(得分:89)
您可以使用xmp
元素,请参阅What was the <XMP> tag used for?。它从一开始就是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>
我看不出如何将xmp
和CDATA部分结合起来实现所谓的多语言标记
答案 1 :(得分:22)
基本上,原始问题可以分为两部分:
简短(但)含糊不清的答案是:你不能, ......但你可以(非常接近)。
(我知道,这是3个相互矛盾的答案,请继续阅读......)
(polyglot)(x)(ht)ml标记语言依赖于(几乎)包含开始/打开和结束/结束标记/字符(序列)之间的所有内容。
因此,要在您的标记语言中嵌入任何类型的原始代码/代码段,人们将始终必须转义/编码类似于将关闭的字符(-sequence)的每个实例(在该代码段内)包装容器&#39;标记中的元素。 (在这篇文章中,我将其称为规则1 。)
想想"some "data" here"
或<i>..close italics with '</i>'-tag</i>
,很明显应该逃避/编码(某些内容)</i
和"
(或更改容器&#39; s引用字符来自"
到'
)。
所以,由于规则1, 你不能 &#39;只是&#39;嵌入任何&#39;标记内的未知原始代码片段。
因为,如果必须在原始代码段内转义/编码甚至一个字符,那么该代码段将不再是原始纯粹的原始代码&#39;任何人都可以在文档的标记中进行复制/粘贴/编辑,而无需进一步考虑。由于实体,它会导致格式错误/非法标记和Mojibake(主要)
此外, 该片段包含此类字符,您仍需要一些javascript来翻译&#39;该字符(序列)来自(和)其转义/编码表示,以便在&#39;网页中正确显示 的片段 (用于复制/粘贴/编辑)。
这将我们带到标记语言指定的(某些)数据类型。这些数据类型基本上定义了什么被认为是有效字符&#39;及其含义(每个标签,财产等):
PCDATA
(Parsed Character DATA):将扩展实体,必须
转义<
,&
(和>
取决于标记语言/版本)
大多数代码,例如body
,div
,pre
等,还有textarea
(直到
HTML5)属于这种类型。
因此,您不仅需要对所有容器的关闭字符序列进行编码
在代码段内,您还必须对所有<
,&
(,>
)个字符进行编码
(至少)
不用说,编码/转义这么多字符不属于此范围
目标在标记中嵌入原始代码段的范围
&#39; ..但是textarea似乎有效...&#39;,是的,或者是因为浏览器
错误引擎尝试用它做出一些东西,或者因为HTML5:
RCDATA
(可替换的字符数据):不会处理内部的标签
文本作为标记(但仍受规则1管辖),因此不需要
编码<
(>
)。但实体仍在扩展,因此它们不明确
&符号&#39; (&
)需要特别小心
当前 HTML5 spec says the textarea is now a RCDATA
field和(引用):
raw text
和RCDATA
元素中的文字不得包含任何内容 出现字符串"</"
(U + 003C LESS-THAN SIGN,U + 002F SOLIDUS) 后跟与字符串不敏感匹配的标记名称的字符 该元素后跟U + 0009 CHARACTER TABULATION(标签)之一, U + 000A LINE FEED(LF),U + 000C FORM FEED(FF),U + 000D CARRIAGE RETURN (CR),U + 0020 SPACE,U + 003E GREATER-THAN SIGN(&gt;)或U + 002F SOLIDUS(/)。
因此无论如何,textarea需要一个庞大的实体翻译处理程序或 它将最终Mojibake实体!
CDATA
(字符数据)不会将文本中的标记视为
标记,不会扩展实体
因此,只要原始代码段代码不违反规则1(那个人就不能违反规则1)
让容器在代码片段内关闭字符(序列),这个
需要没有其他转义/编码。
显然归结为:我们如何最小化仍然需要在代码段的原始来源中编码的字符/字符序列的数量以及字符(序列)在平均片段中出现的次数;对于处理这些字符翻译的javascript(如果它们出现)也很重要的东西。
那是什么&#39;容器&#39;有这个CDATA
上下文?
标签的大多数值属性都是CDATA,因此一个可以(ab)使用隐藏输入的值属性(proof of concept jsfiddle here)。
但是(符合规则1)这会在原始代码段中创建嵌套引号("
和'
)的编码/转义问题,并且需要一些javascript来获取/翻译并将代码段设置为另一个(可见)元素(或简单地将其设置为文本区域的值)。不知怎的,这给了我FF实体的问题(就像在textarea中一样)。但它并不重要,因为价格和价格相同。必须转义/编码嵌套引号高于(HTML5)textarea(引用在源代码中很常见..)。
尝试(ab)使用<![CDATA[<tag>bla & bla</tag>]]>
怎么样?
正如Jukka在他的扩展答案中指出的那样,这只适用于(罕见的)真正的xhtml&#39;。
我想过使用脚本标记(在脚本标记内有或没有这样的CDATA包装)以及包含原始片段的多行注释/* */
(脚本标记可以有{{1}并且您可以通过计数访问它们)。但是,由于这显然在原始代码段中引入了id
,*/
和]]>
的转义问题,这似乎不是解决方案。
请发布其他可行的容器&#39;在对这个答案的评论中。
顺便说一句,编码或计算</script
个字符的数量并在注释标记-
内平衡它们只是为此目的而疯狂(除了规则1)。
我们留下了Jukka K. Korpela's excellent answer: <!-- -->
代码似乎是最佳选择!
被遗忘的&#39; <xmp>
保留<xmp>
,用于此目的并且确实仍然是in the current HTML 5 spec(并且至少自HTML3.2起);正是我们需要的!它也得到了广泛的支持,即使在IE6中也是如此(直到它遭受与滚动表体相同的回归)。
注意:正如Jukka指出的那样,这不适用于真正的xhtml或多语言(将其视为CDATA
)并且pre
标记必须仍然遵守规则1。但是这样做&#39;只有&#39;规则。
考虑以下标记:
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>
包含一个(几乎是原始的)代码片段(包含<xmp id="snippet-container">
)。
注意这个标记中的编码结束标记?为了遵守规则1,这是编码/转义的。
因此嵌入/传输(有时几乎)原始代码似乎已经解决了。
显示/呈现代码段(以及编码的div>div>xmp>html-document
)怎么样?
浏览器将(或者它应该)以上面的代码块中的方式呈现代码片段(</xmp>
)中的内容完全(浏览器之间存在一些差异,无论是否存在差异)该片段以空行开头。)
包括格式/缩进,实体(如字符串snippet-container
),完整标记,注释和编码的结束标记&
(就像它编码的一样)标记)。根据浏览器(版本),甚至可以尝试使用属性</xmp>
来编辑此代码段(所有这些都没有启用javascript)。像contenteditable="true"
这样的事情也是轻而易举的事。
所以你可以 ... 如果该代码段并不包含关闭字符序列的容器。
但是,应原始代码段包含结束字符序列textarea.value=xmp.innerHTML
(因为它是xmp本身的一个示例,或者它包含一些正则表达式等),你必须接受你必须在原始片段中编码/转义该序列并且需要一个javascript处理程序来转换该编码以在{{1}内显示/呈现编码</xmp
,如</xmp>
}(用于编辑/发布)或(例如)</xmp>
只是为了正确呈现代码段的代码(或者看起来如此)。
非常简陋jsfiddle example of this here。请注意,获取/嵌入/显示/检索到textarea即使在IE6中也能完美运行。但设置textarea
&#39; pre
会显示出一些有趣的“智能”#39}。 IE的行为部分。在小提琴中有更广泛的注释和解决方法。
但现在出现重要踢球者(另一个原因你只是非常接近): 就像一个过于简化的例子,想象一下 rabbit-hole :
预期的原始代码段:
xmp
嗯,为了遵守规则1,我们只是&#39;需要编码那些innerHTML
序列,对吧?
这样就为我们提供了以下标记(仅使用可能的编码):
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
嗯..我得到我的水晶球还是翻硬币?不,让计算机查看其系统时钟,并说明派生的数字是随机的&#39;。是的,应该这样做..
使用像这样的正则表达式:</xmp[> \n\r\t\f\/]
,会翻译回来&#39;对此:
<xmp id="container">
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
</xmp>
嗯..似乎这个随机发电机坏了...休斯顿..? 如果您错过了笑话/问题,请从“原始代码 - 片段”开始再次阅读。
等等,我知道,我们(也)需要编码......来.... 好的,请回到原定的原始代码段&#39;并再次阅读 不知怎的,这一切都开始闻起来像the famous hilarious-but-true rexgex-answer on SO,对于流利的mojibake的人来说是一个很好的读物。
也许有人知道一个聪明的算法或解决方案来解决这个问题,但我认为嵌入的原始代码会变得越来越模糊,以至于你更好地正确地转义/编码你的{{ 1}},xmp.innerHTML.replace(/<(?=\/xmp[> \n\r\t\f\/])/gi, '<');
(和<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
),就像世界其他地方一样。
结论:(使用<
代码)
希望这有帮助!
PS:
虽然如果你觉得这个解释很有用,我会很感激,我觉得Jukka的答案应该是公认的答案(不应该有更好的选择/答案),因为他是那个记住xmp标签的人(多年来我忘记了这一点,并且被普遍提倡的PCDATA元素分散了注意力,例如&
,>
等。)
这个答案起源于解释为什么你不能这样做(使用任何未知的原始片段)并解释一些明显的陷阱,其他一些(现在删除的)答案在建议textarea嵌入/传输时被忽略了。我已经扩展了我现有的解释,以支持和进一步解释Jukka的答案(因为所有实体和* CDATA的东西几乎比代码页更难)。
答案 2 :(得分:6)
便宜又开朗的回答:
<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>
此解决方案可能在语义上不正确。因此,如果您需要,最好选择更复杂的答案。
答案 3 :(得分:3)
echo '<pre>' . htmlspecialchars("<div><b>raw HTML</b></div>") . '</pre>';
我认为这就是你要找的东西?
换句话说,在PHP中使用htmlspecialchars()
答案 4 :(得分:3)
@GitaarLAB和@Jukka详细说明<xmp>
标签已过时,但仍然是最好的。当我像这样使用它时
<xmp>
<div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
然后在代码中插入第一个EOL,并looks awful。
可以通过删除EOL
来解决<xmp><div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
但是它在源头看起来很糟糕。我曾经用包裹<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; }
答案 5 :(得分:2)
xmp
是要走的路,即:
<xmp>
# your code...
</xmp>
答案 6 :(得分:1)
如果你启用了jQuery,你可以使用escapeXml函数,而不必担心转义箭头或特殊字符。
<pre>
${fn:escapeXml('
<!-- all your code -->
')};
</pre>
答案 7 :(得分:1)
<code>
标签是个好方法,因为 <xmp>
和 <pre>
标签不支持换行
echo '<code>' . htmlspecialchars("<div><b>hello world</b></div>") . '</code>';