Как отобразить необработанный html-код в PRE или что-то вроде этого, но не избегая его

Я хочу отобразить необработанный HTML. Мы все знаем, что нужно избегать каждого "<" и " > ", как этот

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

Однако я не хочу этого делать. Я бы хотел, чтобы HTML-код был как есть (поскольку его легче читать (внутри редактора), и я, возможно, захочу его скопировать и снова использовать в качестве фактического HTML-кода, и не хочу, чтобы измените его снова или у вас есть 2 версии одного и того же кода, один из которых не экранирован).

Есть ли какая-либо другая среда, более "сырая", чем PRE, которая может это позволить? Так что вам не нужно постоянно редактировать HTML и менять все, когда захотите показать какой-то необработанный HTML-код, может быть в HTML5?

Что-то вроде <REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>

Снимок экрана

Решение javascript не работает на FF 21, вот скриншот enter image description here

Снимок экрана 2

Первое решение по-прежнему не работает на firefox, вот скриншот enter image description here

Ответ 1

Вы можете использовать элемент 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>

Я не вижу, как вы могли бы объединить xmp и раздел CDATA для достижения так называемой разметки polyglot

Ответ 2

По существу исходный вопрос может быть разбит на две части:

  • Основная цель/задача: внедрение (/транспортировка) необработанного отформатированного кода (любой код) в разметке веб-страницы (для простой копирования/вставки/редактирования из-за отсутствия кодирования/побега)
  • правильное отображение/рендеринг этого фрагмента кода (возможно, его редактирование) в браузер

Короткий (но) двусмысленный ответ: вы не можете, но можете (очень близко). (Я знаю, это три противоречивых ответа, поэтому читайте дальше...)

(polyglot) (x) (ht) ml Markup-языки полагаются на обертывание (почти) все между началом/открытием и закрытием/закрытием тегов/символов (последовательностей).
Таким образом, чтобы внедрить любой необработанный код/​​фрагмент внутри вашего языка разметки, всегда нужно будет вывести/закодировать каждый экземпляр (внутри этого фрагмента), который будет похож на символ (-последовательность), который закроет элемент контейнера "контейнер" в разметки. (Во время этого сообщения я буду называть это как правило № 1.)
Подумайте о "some "data" here" или <i>..close italics with '</i>'-tag</i>, где очевидно, что нужно вывести/закодировать (что-то в) </i и " (или изменить кавычек контейнера от " до ').

Итак, из-за правила №1, вы не можете 'просто "вставлять" любой "неизвестный фрагмент кода" внутри разметки.
Поскольку, если вам нужно избежать/кодировать даже один символ внутри исходного фрагмента, то этот фрагмент больше не будет тем же исходным "чистым исходным кодом", который каждый может скопировать/вставить/редактировать в разметке документа без дальнейших размышлений. Это приведет к неправильной/незаконной разметке и Mojibake (главным образом) из-за сущностей.
Кроме того, если этот фрагмент содержит такие символы, вам все равно потребуется некоторый javascript для "перевода" этого символа (последовательности) из (и в) его экранированного/кодированного представления, чтобы правильно отобразить фрагмент на "веб-странице" (для копирования/вставки/редактировать).

Это приводит нас к (некоторым) типам данных, которые указывают языки-метки. Эти типы данных по существу определяют то, что считается "допустимыми символами" и их значением (за тег, свойство и т.д.):

  • PCDATA (Parsed Character DATA): будет расширять объекты, а escape <, &> в зависимости от языка разметки/версии).
    Большинство тегов, таких как body, div, pre и т.д., Но также textarea (до HTML5) попадают под этот тип.
    Таким образом, вы не только должны кодировать все последовательности символов закрытия контейнера внутри фрагмента вы также должны кодировать все символы <, & (, >) (как минимум).
    Излишне говорить, что кодирование/экранирование этого множества символов выходит за рамки этого объективный объем вложения исходного фрагмента в разметку.
    '.. Но текстовое поле, похоже, работает...', да, либо из-за браузеров error-engine, пытающийся сделать что-то из этого, или потому, что HTML5:

  • RCDATA (Сменные символы символов): не будет обрабатывать теги внутри текст как разметка (но по-прежнему регулируется правилом 1), поэтому не нужно encode < (>). НО сущности все еще расширяются, поэтому они и "двусмысленные амперсанды '(&) нуждаются в особой заботе.
    Текущая спецификация HTML5 говорит, что textarea теперь является полем RCDATA и (цитата):

    Текст в raw text и RCDATA элементах не должен содержать. вхождения строки "</" (U + 003C LESS-THAN SIGN, U + 002F SOLIDUS) за которыми следуют символы, которые нечувствительно к регистру соответствуют имени тега элемент, за которым следует один из U + 0009 ТАБЛИЦЫ ХАРАКТЕР (вкладка), U + 000A LINE FEED (LF), U + 000C FEED FEED (FF), U + 000D ВОЗВРАТ КАРЬЕРА (CR), U + 0020 SPACE, U + 003E БОЛЬШЕ, ЧЕМ ЗНАК ( > ), или U + 002F SOLIDUS (/).

    Таким образом, несмотря ни на что, textarea нуждается в обработчике перевода сущ. объекта или это в конечном итоге Mojibake на сущности!

  • CDATA (данные символа) не будет обрабатывать теги внутри текста как разметки и не будет расширять объекты.
    До тех пор, пока код исходного кода не нарушает правило 1 (это невозможно имеют символ закрытия контейнера (последовательность) внутри фрагмента), это не требует другого экранирования/кодирования.

Ясно, что это сводится к: как мы можем минимизироватьколичество символов/последовательностей символов, которые все еще должны быть закодированы в исходном исходном тексте фрагмента, и количество раз, которое символ (последовательность) может отображаться в среднем фрагменте; что также важно для javascript, который обрабатывает перевод этих символов (если они возникают).

Итак, какие "контейнеры" имеют этот контекст CDATA?

Большинство значений свойств тегов являются CDATA, поэтому можно (ab) использовать свойство скрытого входного значения (доказательство концепции jsfiddle здесь).
Однако (правило соответствия 1) это создает проблему кодирования/эвакуации с вложенными кавычками (" и ') в исходном фрагменте, а для получения/перевода требуется некоторый javascript, а набор фрагментов - в другом (видимом) элементе (или просто устанавливая его как значение текстовой области). Так или иначе это дало мне проблемы с объектами в FF (как в текстовом поле). Но это не имеет особого значения, поскольку "цена" на то, чтобы убегать/кодировать вложенные кавычки выше, чем текстовое поле (HTML5) (кавычки довольно распространены в исходном коде..).

Как насчет того, чтобы пытаться (ab) использовать <![CDATA[<tag>bla & bla</tag>]]>?
Как указывает Юкка в своем расширенном ответе, это будет работать только в (редком) "реальном xhtml".
Я думал об использовании script -tag (с такой оболочкой CDATA внутри или без нее внутри script -tag) вместе с многострочным комментарием /* */, который обертывает исходный фрагмент (script -tags может иметь id, и вы можете получить к ним доступ по счету). Но так как это явно вводит проблему экранирования с */, ]]> и </script в исходном фрагменте, это тоже не похоже на решение.

Пожалуйста, размещайте другие жизнеспособные "контейнеры" в комментариях к этому ответу.

Кстати, кодирование или подсчет количества символов - и их балансировка внутри тега комментариев <!-- --> для этой цели просто безумны (кроме правила 1).


Это оставляет нам Jukka K. Korpela отличный ответ: тег <xmp> кажется лучшим вариантом!

"Забытый" <xmp> имеет значение CDATA, предназначен для этой цели И действительно является в текущей спецификации HTML 5 ( и был, по крайней мере, с HTML3.2); именно то, что нам нужно! Он также широко поддерживается даже в IE6 (то есть.. до тех пор, пока он не пострадает от той же регрессии, что и прокручиваемое стол-тело).
Примечание: как указал Юкка, это не будет работать в истинном xhtml или polyglot (который будет рассматривать его как 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>

Вышеупомянутый блок кода иллюстрирует необработанную часть разметки, где <xmp id="snippet-container"> содержит (почти сырой) фрагмент кода (содержащий div>div>xmp>html-document).
Обратите внимание на закодированный закрывающий тег в этой разметке? Чтобы соответствовать правилу № 1, это было закодировано/экранировано).

Так что вложение/транспортировка (иногда почти) необработанного кода будет/кажется решенным.

Как насчет отображения/рендеринга фрагмента (и закодированного &lt;/xmp>)?

Браузер будет (или должен) отобразить фрагмент (содержимое внутри snippet-container) точно так, как вы видите его в кодовом блоке выше (с некоторым расхождением между браузерами, начинается ли фрагмент с пустой строкой).
Это включает в себя форматирование/отступы, сущности (например, строку &amp;), полные теги, комментарии И закодированный закрывающий тег &lt;/xmp> (точно так же, как он был закодирован в разметке). И в зависимости от браузера (версии) можно даже попробовать использовать свойство contenteditable="true" для редактирования этого фрагмента (все, что без javascript включено). Выполнение чего-то вроде textarea.value=xmp.innerHTML - тоже легкий ветерок.

Таким образом, вы можете... если фрагмент не содержит контейнеров, закрывающих последовательность символов.

Однако, если необработанный фрагмент содержит закрывающую последовательность символов </xmp (поскольку это пример самого xmp или он содержит некоторое регулярное выражение и т.д.), вы должны признать, что вам нужно encode/escape этой последовательности в исходном фрагменте И нужен обработчик javascript для перевода этого кодирования для отображения/отображения закодированного &lt;/xmp> как </xmp> внутри a textarea (для редактирования/публикации) или (например) a pre просто для правильного отображения кода фрагмента (или, как кажется).

Очень рудиментарный пример jsfiddle этого здесь, Обратите внимание, что получение/вложение/отображение/извлечение в textarea работало идеально даже в IE6. Но установка xmp innerHTML показала некоторое интересное "потенциально-разумное" поведение в части 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>

Хмм.. я получу свой хрустальный шар или переворачиваю монету? Нет, пусть компьютер посмотрит на свои системные часы и сообщит, что производное число является "случайным". Да, это должно сделать это.

Используя регулярное выражение, подобное: xmp.innerHTML.replace(/&lt;(?=\/xmp[> \n\r\t\f\/])/gi, '<');, переведет 'назад' на это:

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

Хм.. кажется, этот случайный генератор сломан... Хьюстон..?
Если вы пропустили шутку/проблему, прочитайте снова, начиная с "предназначенного фрагмента кода".

Подождите, я знаю, нам (также) нужно кодировать.... на....
Хорошо, перемотайте "предполагаемый необработанный код-фрагмент" и снова прочитайте.
Каким-то образом все это начинает пахнуть, как знаменитый веселый, но истинный rexgex-ответ на SO, хорошо читаемый для людей, свободно владеющих моджибаке.

Может быть, кто-то знает умный алгоритм или решение, чтобы исправить эту проблему, но я предполагаю, что встроенный необработанный код будет становиться все более и более неясным до такой степени, что вам лучше правильно экранировать/кодировать только ваш <, &>), как и весь остальной мир.

Вывод: (с помощью тега xmp)

  • это можно сделать с помощью известных фрагментов, которые не содержат символьную последовательность закрытия контейнера,
  • мы можем приблизиться к исходной цели с известными фрагментами, которые используют только "базовый первый уровень" для экранирования/кодирования, поэтому мы не попадаем в раввило,
  • но в конечном итоге кажется, что нельзя надежно выполнять это в "производственной среде", где люди могут/должны копировать/вставлять/редактировать "любые неизвестные" необработанные фрагменты, не зная/не понимая значения/правила/раввитолу ( в зависимости от вашей реализации обработки/перевода для правила 1 и кроличьей дыры).

Надеюсь, это поможет!

PS: Хотя я был бы признателен за повышение, если вы найдете это объяснение полезным, я вроде думаю, что ответ Jukka должен быть принятым ответом (если не будет лучшего варианта/ответа), поскольку он был тем, кто помнил тег xmp (что я забыл о на протяжении многих лет и "отвлекался" от широко распространенных элементов PCDATA, таких как pre, textarea и т.д.).
Этот ответ возник из объяснения, почему вы не можете это сделать (с любым неизвестным сырым фрагментом) и объяснить некоторые очевидные ошибки, которые некоторые другие (теперь удаленные) ответы игнорируются при консультировании текстового поля для встраивания/переноса. Я расширил свое существующее объяснение, чтобы также поддержать и объяснить Jukka ответ (поскольку все, что сущность и * CDATA материал почти сложнее, чем кодовые страницы).

Ответ 3

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

Я думаю, что вы ищете?

Другими словами, используйте htmlspecialchars() в PHP

Ответ 4

Дешевый и веселый ответ:

<textarea>Some raw content</textarea>

Текстовое поле будет обрабатывать вкладки, несколько пробелов, новые строки, обертывание строк все дословно. Он копирует и вставляет красиво и его действительный HTML полностью. Он также позволяет пользователю изменять размер окна кода. Вам не нужны CSS, JS, экранирование, кодирование.

Вы также можете изменить внешний вид и поведение. Здесь моноширинный шрифт, редактирование отключено, меньший шрифт, без рамки:

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

Это решение, вероятно, не является семантически правильным. Поэтому, если вам это нужно, лучше всего выбрать более сложный ответ.

Ответ 5

@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; }

Этот выглядит лучше.

Ответ 6

Если у вас включен jQuery, вы можете использовать функцию escapeXml и не беспокоиться об экранировании стрелок или специальных символов.

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

Ответ 7

xmp - путь, например:

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