web-dev-qa-db-ja.com

生のHTMLコードをPREなどでエスケープせずに表示する方法

生のHTMLを表示したい。このように、各「<」と「>」をエスケープする必要があることは誰もが知っています。

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

しかし、私はこれをしたくありません。 HTMLコードをそのまま(エディタ内で)読みやすくするために、それをコピーして、実際のHTMLコードとして自分で再度使用したい場合があります。もう一度変更するか、同じコードの2つのバージョンのうち1つをエスケープし、もう1つをエスケープしないでください)。

これを可能にするPREよりも「生」の環境は他にありますか? HTML5にあるかもしれない生のHTMLコードを表示するたびにHTMLを編集し、すべてを変更し続ける必要はありませんか?

<REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>のようなもの

スクリーンショット

JavascriptソリューションはFF 21では機能しません。スクリーンショットはこちら enter image description here

スクリーンショット2

最初の解決策はまだFirefoxでは動作しません、ここにスクリーンショットがあります enter image description here

57
Robert H

xmp要素を使用できます。 <XMP>タグは何に使用されましたか? を参照してください。それは最初からHTMLであり、すべてのブラウザでサポートされています。仕様はそれを嫌っていますが、HTML5 CRはまだそれを記述しており、それをサポートするためにブラウザーを必要とします(ただし、作成者に使用しないよう指示していますが、実際に防ぐことはできません)。

xmp内のすべてはそのように解釈され、マークアップ(タグまたは文字参照)はそこに認識されません。ただし、明らかな理由により、エレメント自体の終了タグ</xmp>を除きます。

それ以外の場合、xmppreのようにレンダリングされます。

「実際のXHTML」、つまりXMLメディアタイプで配信されるXHTML(まれですが)を使用する場合、特別な解析ルールは適用されないため、xmppreのように扱われます。しかし、「実際のXHTML」では、CDATAセクションを使用できます。これは、同様の解析ルールを意味します。特別な書式設定はないため、おそらくpre要素で囲む必要があります。

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

xmpとCDATAセクションを組み合わせて、いわゆるポリグロットマークアップを実現する方法がわかりません

90

基本的に、元の質問は2つの部分に分けられます。

  • 主な目的/課題:Webページのマークアップに生のフォーマット済みコードスニペット(あらゆる種類のコード)を埋め込む(/トランスポートする)(エンコード/エスケープがないため、単純なコピー/貼り付け/編集用)
  • ブラウザでそのコードスニペットを正しく表示/レンダリングします(おそらく編集します)。

短い(but)ambiguous答えは、you cant...but you can (非常に近くなる).
(私は知っている、それは3つの矛盾する答えなので、読んでください...)

(polyglot)(x)(ht)mlマークアップ言語は、開始/開始タグと終了/終了タグ/文字(シーケンス)の間の(ほぼ)すべてをラップすることに依存しています。
したがって、any種類の生のコード/スニペットをマークアップ言語内に埋め込むには、常にすべてのインスタンスをエスケープ/エンコードする必要があります(スニペット内)マークアップのラッピング「コンテナ」要素を閉じる文字(-sequence)に似ています。 (この投稿では、これをrule no 1と呼びます。)
"some "data" here"または<i>..close italics with '</i>'-tag</i>を考えてみてください。明らかに、</i"をエスケープ/エンコードする必要があります(または、コンテナの引用文字を"から'に変更します)。

したがって、ルール1ではないため、you't'just'埋め込み 'any' unknownマークアップ内の生のコードスニペット。
生のスニペット内の文字をエスケープ/エンコードeven one文字にする必要がある場合、そのスニペットは元の「純粋な生コード」とは異なる'誰でもドキュメントのマークアップをさらに考えずにコピー/貼り付け/編集できます。エンティティが原因で、不正な形式または不正なマークアップおよび Mojibake (主に)につながります。
また、shouldスニペットにそのような文字が含まれている場合は、stillにjavascriptが必要ですエスケープ/エンコードされた表現の文字(シーケンス)を「翻訳」して、「webpage」にスニペットcorrectlyを表示します(コピー/貼り付け/編集用) 。

これにより、マークアップ言語が指定するデータ型(の一部)が得られます。これらのデータ型は、基本的に「有効な文字」と見なされるものとその意味(タグごと、プロパティごとなど)を定義します。

  • PCDATA(解析された文字データ):エンティティを展開し、<&(およびマークアップ言語/バージョンに応じて>)をエスケープする必要があります。
    bodydivpreなどのほとんどのタグだけでなく、textarea(HTML5まで)もこのタイプに分類されます。
    したがって、スニペット内のすべてのコンテナの終了文字シーケンスをエンコードする必要があるだけでなく、すべての<&(、>)文字をエンコードする必要があります.
    言うまでもなく、この多くの文字のエンコード/エスケープは、マークアップに生のスニペットを埋め込むというこの目的の範囲外です。
    '..しかし、テキストエリアは機能しているようです...'、はい、ブラウザのエラーエンジンが何かを作ろうとしているため、またはHTML5のために:

  • RCDATA(Replaceable Character DATA):テキスト内のタグをマークアップとして扱いません(ただし、ルール1によって管理されます)。したがって、<>)をエンコードする必要はありません。ただし、エンティティはまだ拡張されているため、それらと「あいまいなアンパサンド」(&)には特別な注意が必要です。
    currentHTML5の仕様では、textareaがRCDATAフィールドになりました and(quote):

    raw textおよびRCDATA要素のテキストmust notには、文字列"</"(U + 003C LESS-THAN SIGN、U + 002F SOLIDUS)の出現が含まれ、その後にタグ名と大文字小文字を区別せずに一致する文字が含まれますU + 0009 CHARACTER TABULATION(tab)、U + 000A LINE FEED(LF)、U + 000C FORM FEED(FF)、U + 000D CARRIAGE RETURN(CR)、U + 0020 SPACE、U + 003E GREATERのいずれかが続く要素-THAN SIGN(>)、またはU + 002F SOLIDUS(/)。

    したがって、textareaには、非常に大きなエンティティ変換ハンドラーが必要です。または、will最終的にエンティティをMojibakeします。

  • CDATA(文字データ)テキスト内のタグをマークアップとして扱わず、エンティティを展開しません
    したがって、未加工のスニペットコードがルール1(スニペット内でコンテナを閉じる文字(シーケンス)を持つことはできない)に違反しない限り、これにはno otherが必要です。escaping/encoding。

明らかにこれは次のように要約されます:どのようにすれば最小化スニペットの生のソースでエンコードする必要がある文字/文字シーケンスの数そして、その文字(シーケンス)が平均スニペットに表示される回数。これらの文字の翻訳を処理するjavascriptにとっても重要なものです(発生した場合)。

では、この「CDATA」コンテキストを持つ「コンテナ」は何ですか?

タグのほとんどの値プロパティはCDATAであるため、could(ab)隠された入力の値プロパティを使用します( proof of concept jsfiddle here )。
ただし(ルール1に準拠)、これにより、生のスニペットにネストされた引用符("および')が含まれるエンコード/エスケープの問題が発生します。または、単にテキスト領域の値として設定します)。どういうわけか、これはFFのエンティティ(テキストエリアのように)に問題をもたらしました。ただし、ネストされた引用符をエスケープ/エンコードする必要がある「価格」は(HTML5)テキスト領域よりも高いため(引用符はソースコードでは非常に一般的です)。

<![CDATA[<tag>bla & bla</tag>]]>を(ab)使用しようとしてはどうですか?
Jukkaが拡張回答で指摘しているように、これは(まれな) 'real xhtml'でのみ機能します。
script-tag(script-tag内にそのようなCDATAラッパーを含む、または含まない)を生のスニペットをラップする複数行コメント/* */とともに使用することを考えました(script-tagにはidとカウントでアクセスできます)。しかし、これは明らかに生のスニペットの*/]]>、および</scriptのエスケープの問題を引き起こすため、これも解決策のようには見えません

この回答へのコメントに他の実行可能な「コンテナ」を投稿してください。

ちなみに、-文字の数をエンコードまたはカウントし、コメントタグ<!-- -->内でバランスをとるのは、この目的では非常に狂っています(ルール1を除く)。


Jukka K. Korpelaの優れた答え が残ります:<xmp>タグが最適なオプションのようです!

「忘れられた」<xmp>CDATAを保持し、この目的のためのものであり、実際にはまだ currentHTML 5仕様で (そして少なくともHTML3.2以降);まさに必要なもの! IE6でも(つまり、スクロールテーブル本体と同じリグレッションが発生するまで)広くサポートされています。
注:Jukkaが指摘したように、これは真のxhtmlまたはポリグロット(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>

上記のcodeblokは、<xmp id="snippet-container">が(ほとんど生の)コードスニペット(div>div>xmp>html-documentを含む)を含む生のマークアップを示しています。
このマークアップでエンコードされた終了タグに注意してください。ルール1に準拠するために、これはエンコード/エスケープされました)。

そのため、(ほとんどの場合)生コードの埋め込み/トランスポートは解決されたようです。

スニペット(およびエンコードされた&lt;/xmp>)の表示/レンダリングについてはどうですか?

ブラウザはスニペット(snippet-container内のコンテンツ)exactlyを上記のコードブロックで表示する方法(またはブラウザ間で多少の矛盾を伴う)をレンダリングします(またはする必要があります)スニペットは空白行で始まります)。
そのincludes書式設定/インデント、エンティティ(文字列&amp;など)、完全なタグ、コメントANDエンコード終了タグ&lt;/xmp>(マークアップでエンコードされたように)。また、ブラウザ(バージョン)によっては、プロパティcontenteditable="true"を使用して、このスニペット(javascriptが有効になっていないものすべて)を編集することもできます。 textarea.value=xmp.innerHTMLのようなことも簡単です。

So you can ...ifスニペットには、コンテナを閉じる文字シーケンスが含まれていません。

ただしshould生のスニペットには、終了文字シーケンス</xmpが含まれます(xmp自体の例であるか、正規表現などが含まれているため) )、生のスニペットでそのシーケンスをエンコード/エスケープする必要があり、そのエンコードを変換し、エンコードされた&lt;/xmp>textarea内の</xmp>のように表示/レンダリングする必要があることを受け入れる必要があります単にスニペットのコードを正しくレンダリングするためのpre(またはそう思われます)。

非常に初歩的な これのjsfiddleの例 。 IE6でもテキストエリアへの取得/埋め込み/表示/取得が完璧に機能したことに注意してください。しかし、xmpinnerHTMLを設定すると、IE側で興味深い「インテリジェントになる」動作が明らかになりました。フィドルでは、より広範なメモと回避策があります。

しかし、今では重要なキッカー非常に近くなるだけの別の理由):単純化した例として、これを想像してくださいウサギの巣穴

生のコードスニペット:

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

さて、ルール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>

うーん..クリスタルボールを手に入れるか、コインを投げるのですか?いいえ、コンピュータにシステムクロックを見てもらい、導出された数値が「ランダム」であることを伝えます。はい、それでうまくいくはずです。

正規表現likexmp.innerHTML.replace(/&lt;(?=\/xmp[> \n\r\t\f\/])/gi, '<');を使用すると、 'back'がこれに変換されます。

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

うーん..このランダムなジェネレーターが壊れているようです...ヒューストン..?
ジョーク/問題を見逃してしまった場合は、「意図した生のコードスニペット」から読み直してください。

待って、私たちは(...)エンコードする必要があります。
OK、「意図した生のコードスニペット」に巻き戻して、もう一度読んでください。
どういうわけか、これはすべて SOの有名な陽気なが本当のrexgex-answer のような匂いがし始めます。

たぶん誰かがこの問題を解決する賢いアルゴリズムや解決策を知っているかもしれませんが、埋め込まれた生のコードは、あなたの<&(および>)だけを適切にエスケープ/エンコードした方が良いところまでますます曖昧になると思います、他の世界と同じように。

結論:xmpタグを使用)

  • コンテナの終了文字シーケンスを含まない既知のスニペットで実行できます。
  • 「基本的な第1レベル」のエスケープ/エンコードのみを使用する既知のスニペットで元の目標に非常に近づけることができるので、rabbit穴に陥ることはありません。
  • しかし、ultimately「プロダクション環境」でこれを確実に行うことはできないようです。「プロダクション環境」では、意味/ルール/ウサギの穴を知らない/理解しない(ルール1とウサギの穴の処理/翻訳の実装に依存)。

お役に立てれば!

PS:この説明が役に立つと思うなら、賛成票に感謝しますが、Jukkaの答えは受け入れられた答えだと思います(より良いオプション/答えは出てこないはずです)、彼はxmpタグを覚えていたからです長年にわたって忘れていて、pretextareaなどの一般的に支持されているPCDATA要素に「気を取られ」ました。
この回答は、それができない理由(不明な未加工のスニペット)を説明することに由来し、他の(現在は削除された)回答が埋め込み/トランスポートのテキストエリアにアドバイスするときに見落としている明らかな落とし穴を説明します。既存の説明を拡張して、Jukkaの答えもサポートし、さらに説明します(そのすべてのエンティティと* CDATAのものはコードページよりもほとんど難しいため)。

22
GitaarLAB

安くて陽気な答え:

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

このソリューションは、おそらく意味的に正しくありません。したがって、それが必要な場合は、より洗練された答えを選択するのが最善かもしれません。

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

それがあなたが探しているものだと思いますか?

つまり、PHPでhtmlspecialchars()を使用します

3
tribulant

@GitaarLABと@Jukkaは、<xmp>タグは廃止されましたが、それでも最高であると説明しています。このように使うと

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

次に、最初のEOLがコードに挿入され、それは ひどいように見えます です。

その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; }

これ 見栄えが良い

3
Jan Turoň

xmpは進むべき道、つまり:

<xmp>
  # your code...
</xmp>
2
Pedro Lobito

JQueryを有効にしている場合は、escapeXml関数を使用でき、矢印や特殊文字のエスケープを心配する必要がありません。

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