This question already has an answer here:
How to add a newline (line break) in XML file?
(1 answer)
Closed 4 years ago.
I'm a beginner in web development, and I'm trying to insert line breaks in my XML file.
This is what my XML looks like:
<musicpage>
<song>
<title>Song Title</title>
<lyric>Lyrics</lyric>
</song>
<song>
<title>Song Title</title>
<lyric>Lyrics</lyric>
</song>
<song>
<title>Song Title</title>
<lyric>Lyrics</lyric>
</song>
<song>
<title>Song Title</title>
<lyric>Lyrics</lyric>
</song>
</musicpage>
I want to have line breaks in between the sentences for the lyrics. I tried everything from /n,
and other codes similar to it, PHP parsing, etc., and nothing works! Have been googling online for hours and can't seem to find the answer. I'm using the XML to insert data to an HTML page using Javascript.
Does anyone know how to solve this problem?
And this is the JS code I used to insert the XML data to the HTML page:
<script type="text/javascript">
if (window.XMLHttpRequest) {
xhttp=new XMLHttpRequest();
} else {
xhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET","xml/musicpage_lyrics.xml",false);
xhttp.send("");
xmlDoc=xhttp.responseXML;
var x=xmlDoc.getElementsByTagName("songs");
for (i=0;i<x.length;i++) {
document.write("<p class='msg_head'>");
document.write(x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue);
document.write("</p><p class='msg_body'>");
document.write(x[i].getElementsByTagName("lyric")[0].childNodes[0].nodeValue);
document.write("</p>");
}
</script>
#icktoofay was close with the CData
<myxml>
<record>
<![CDATA[
Line 1 <br />
Line 2 <br />
Line 3 <br />
]]>
</record>
</myxml>
In XML a line break is a normal character. You can do this:
<xml>
<text>some text
with
three lines</text>
</xml>
and the contents of <text> will be
some text
with
three lines
If this does not work for you, you are doing something wrong. Special "workarounds" like encoding the line break are unnecessary. Stuff like \n won't work, on the other hand, because XML has no escape sequences*.
* Note that
is the character entity that represents a line break in serialized XML. "XML has no escape sequences" means the situation when you interact with a DOM document, setting node values through the DOM API.
This is where neither
nor things like \n will work, but an actual newline character will. How this character ends up in the serialized document (i.e. "file") is up to the API and should not concern you.
Since you seem to wonder where your line breaks go in HTML: Take a look into your source code, there they are. HTML ignores line breaks in source code. Use <br> tags to force line breaks on screen.
Here is a JavaScript function that inserts <br> into a multi-line string:
function nl2br(s) { return s.split(/\r?\n/).join("<br>"); }
Alternatively you can force line breaks at new line characters with CSS:
div.lines {
white-space: pre-line;
}
just use <br> at the end of your lines.
At the end of your lines, simply add the following special character:
That special character defines the carriage-return character.
In the XML: use literal line-breaks, nothing else needed there.
The newlines will be preserved for Javascript to read them [1]. Note that any indentation-spaces and preceding or trailing line-breaks are preserved too (the reason you weren't seeing them is that HTML/CSS collapses whitespace into single space-characters by default).
Then the easiest way is: In the HTML: do nothing, just use CSS to preserve the line-breaks
.msg_body {
white-space: pre-line;
}
But this also preserves your extra lines from the XML document, and doesn't work in IE 6 or 7 [2].
So clean up the whitespace yourself; this is one way to do it (linebreaks for clarity - Javascript is happy with or without them [3]) [4]
[get lyric...].nodeValue
.replace(/^[\r\n\t ]+|[\r\n\t ]+$/g, '')
.replace(/[ \t]+/g, ' ')
.replace(/ ?([\r\n]) ?/g, '$1')
and then preserve those line-breaks with
.msg_body {
white-space: pre; // for IE 6 and 7
white-space: pre-wrap; // or pre-line
}
or, instead of that CSS, add a .replace(/\r?\n/g, '<br />') after the other JavaScript .replaces.
(Side note: Using document.write() like that is also not ideal and sometimes vulnerable to cross-site scripting attacks, but that's another subject. In relation to this answer, if you wanted to use the variation that replaces with <br>, you'd have to escape <,&(,>,",') before generating the <br>s.)
--
[1] reference: sections "Element White Space Handling" and "XML Schema White Space Control" http://www.usingxml.com/Basics/XmlSpace#ElementWhiteSpaceHandling
[2] http://www.quirksmode.org/css/whitespace.html
[3] except for a few places in Javascript's syntax where its semicolon insertion is particularly annoying.
[4] I wrote it and tested these regexps in Linux Node.js (which uses the same Javascript engine as Chrome, "V8"). There's a small risk some browser executes regexps differently. (My test string (in javascript syntax) "\n\nfoo bar baz\n\n\tmore lyrics \nare good\n\n")
<song>
<title>Song Tigle</title>
<lyrics>
<line>The is the very first line</line>
<line>Number two and I'm still feeling fine</line>
<line>Number three and a pattern begins</line>
<line>Add lines like this and everyone wins!</line>
</lyrics>
</song>
(Sung to the tune of Home on the Range)
If it was mine I'd wrap the choruses and verses in XML elements as well.
If you use CDATA, you could embed the line breaks directly into the XML I think. Example:
<song>
<title>Song Title</title>
<lyric><![CDATA[Line 1
Line 2
Line 3]]></lyric>
</song>
<description><![CDATA[first line<br/>second line<br/>]]></description>
If you are using CSS to style (Not recommended.) you can use display:block;, however, this will only give you line breaks before and after the styled element.
Related
I'd like to display raw HTML. We all know one has to escape each "<" and ">" like this:
<PRE> this is a test <DIV> </PRE>
However, I do not want to do this. I'd like a way to keep the HTML code as is (since it is easier to read, (inside the editor) and I might want to copy it and use it again myself as actual HTML code, and do not want to have to change it again or have two versions of the same code, one escaped and one not escaped.
Is there any other environment that is more "raw" than PRE that might allow this? So one does not have to keep editing HTML and changing everything each time they want to show some raw HTML code, maybe in HTML5?
Something like <REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>
The JavaScript solution does not work on Firefox 21, here is a screenshot:
The first solution still does not work on Firefox, here is a screenshot:
You can use the xmp element, see What was the <XMP> tag used for?. It has been in HTML since the beginning and is supported by all browsers. Specifications frown upon it, but HTML5 CR still describes it and requires browsers to support it (though it also tells authors not to use it, but it cannot really prevent you).
Everything inside xmp is taken as such, no markup (tags or character references) is recognized there, except, for apparent reason, the end tag of the element itself, </xmp>.
Otherwise xmp is rendered like pre.
When using “real XHTML”, i.e. XHTML served with an XML media type (which is rare), the special parsing rules do not apply, so xmp is treated like pre. But in “real XHTML”, you can use a CDATA section, which implies similar parsing rules. It has no special formatting, so you would probably want to wrap it inside a pre element:
<pre><![CDATA[
This is a demo, tags like <p> will
appear literally.
]]></pre>
I don’t see how you could combine xmp and CDATA section to achieve so-called polyglot markup
Essentially the original question can be broken down in 2 parts:
Main objective/challenge: embedding(/transporting) a raw formatted code-snippet
(any kind of code) in a web-page's markup (for simple copy/paste/edit due to no
encoding/escaping)
correctly displaying/rendering that code-snippet (possibly edit it) in the
browser
The short (but) ambiguous answer is: you can't, ...but you can (get very close).
(I know, that are 3 contradicting answers, so read on...)
(polyglot)(x)(ht)ml Markup-languages rely on wrapping (almost) everything between begin/opening and end/closing tags/character(sequences).
So, to embed any kind of raw code/snippet inside your markup-language, one will always have to escape/encode every instance (inside that snippet) that resembles the character(-sequence) that would close the wrapping 'container' element in the markup. (During this post I'll refer to this as rule no 1.)
Think of "some "data" here" or <i>..close italics with '</i>'-tag</i>, where it is obvious one should escape/encode (something in) </i and " (or change container's quote-character from " to ').
So, because of rule no 1, you can't 'just' embed 'any' unknown raw code-snippet inside markup.
Because, if one has to escape/encode even one character inside the raw snippet, then that snippet would no longer be the same original 'pure raw code' that anyone can copy/paste/edit in the document's markup without further thought. It would lead to malformed/illegal markup and Mojibake (mainly) because of entities.
Also, should that snippet contain such characters, you'd still need some javascript to 'translate' that character(sequence) from (and to) it's escaped/encoded representation to display the snippet correctly in the 'webpage' (for copy/paste/edit).
That brings us to (some of) the datatypes that markup-languages specify. These datatypes essentially define what are considered 'valid characters' and their meaning (per tag, property, etc.):
PCDATA (Parsed Character DATA): will expand entities and one must
escape <, & (and > depending on markup language/version).
Most tags like body, div, pre, etc, but also textarea (until
HTML5) fall under this type.
So not only do you need to encode all the container's closing character-sequences
inside the snippet, you also have to encode all <, & (,>) characters
(at minimum).
Needless to say, encoding/escaping this many characters falls outside this
objective's scope of embedding a raw snippet in the markup.
'..But a textarea seems to work...', yes, either because of the browsers
error-engine trying to make something out of it, or because HTML5:
RCDATA (Replaceable Character DATA): will not not treat tags inside the
text as markup (but are still governed by rule 1), so one doesn't need to
encode < (>). BUT entities are still expanded, so they and 'ambiguous
ampersands' (&) need special care.
The current HTML5 spec says the textarea is now a RCDATA field and (quote):
The text in raw text and RCDATA elements must not contain any
occurrences of the string "</" (U+003C LESS-THAN SIGN, U+002F SOLIDUS)
followed by characters that case-insensitively match the tag name of
the element followed by one of 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 (>), or U+002F SOLIDUS (/).
Thus no matter what, textarea needs a hefty entity translation handler or
it will eventually Mojibake on entities!
CDATA (Character Data) will not treat tags inside the text as
markup and will not expand entities.
So as long as the raw snippet code does not violate rule 1 (that one can't
have the containers closing character(sequence) inside the snippet), this
requires no other escaping/encoding.
Clearly this boils down to: how can we minimize the number of characters/character-sequences that still need to be encoded in the snippet's raw source and the number of times that character(sequence) might appear in an average snippet; something that is also of importance for the javascript that handles the translation of these characters (if they occur).
So what 'containers' have this CDATA context?
Most value properties of tags are CDATA, so one could (ab)use a hidden input's value property (proof of concept jsfiddle here).
However (conform rule 1) this creates an encoding/escape problem with nested quotes (" and ') in the raw snippet and one needs some javascript to get/translate and set the snippet in another (visible) element (or simply setting it as a text-area's value). Somehow this gave me problems with entities in FF (just like in a textarea). But it doesn't really matter, since the 'price' of having to escape/encode nested quotes is higher then a (HTML5) textarea (quotes are quite common in source code..).
What about trying to (ab)use <![CDATA[<tag>bla & bla</tag>]]>?
As Jukka points out in his extended answer, this would only work in (rare) 'real xhtml'.
I thought of using a script-tag (with or without such a CDATA wrapper inside the script-tag) together with a multi-line comment /* */ that wraps the raw snippet (script-tags can have an id and you can access them by count). But since this obviously introduces a escaping problem with */, ]]> and </script in the raw snippet, this doesn't seem like a solution either.
Please post other viable 'containers' in the comments to this answer.
By the way, encoding or counting the number of - characters and balancing them out inside a comment tag <!-- --> is just insane for this purpose (apart from rule 1).
That leaves us with Jukka K. Korpela's excellent answer: the <xmp> tag seems the best option!
The 'forgotten' <xmp> holds CDATA, is intended for this purpose AND is indeed still in the current HTML 5 spec (and has been at least since HTML3.2); exactly what we need! It's also widely supported, even in IE6 (that is.. until it suffers from the same regression as the scrolling table-body).
Note: as Jukka pointed out, this will not work in true xhtml or polyglot (that will treat it as a pre) and the xmp tag must still adhere to rule no 1. But that's the 'only' rule.
Consider the following markup:
<!-- 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>
The above codeblok illustrates a raw piece of markup where <xmp id="snippet-container"> contains an (almost raw) code-snippet (containing div>div>xmp>html-document).
Notice the encoded closing tag in this markup? To comply with rule no 1, this was encoded/escaped).
So embedding/transporting the (sometimes almost) raw code is/seems solved.
What about displaying/rendering the snippet (and that encoded </xmp>)?
The browser will (or it should) render the snippet (the contents inside snippet-container) exactly the way you see it in the codeblock above (with some discrepancy amongst browsers whether or not the snippet starts with a blank line).
That includes the formatting/indentation, entities (like the string &), full tags, comments AND the encoded closing tag </xmp> (just like it was encoded in the markup). And depending on browser(version) one could even try use the property contenteditable="true" to edit this snippet (all that without javascript enabled). Doing something like textarea.value=xmp.innerHTML is also a breeze.
So you can... if the snippet doesn't contain the containers closing character-sequence.
However, should a raw snippet contain the closing character-sequence </xmp (because it is an example of xmp itself or it contains some regex, etc), you must accept that you have to encode/escape that sequence in the raw snippet AND need a javascript handler to translate that encoding to display/render the encoded </xmp> like </xmp> inside a textarea (for editing/posting) or (for example) a pre just to correctly render the snippet's code (or so it seems).
A very rudimentary jsfiddle example of this here. Note that getting/embedding/displaying/retrieving-to-textarea worked perfect even in IE6. But setting the xmp's innerHTML revealed some interesting 'would-be-intelligent' behavior on IE's part. There is a more extensive note and workaround on that in the fiddle.
But now comes the important kicker (another reason why you only get very close):
Just as an over-simplified example, imagine this rabbit-hole:
Intended raw code-snippet:
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Well, to comply with rule 1, we 'only' need to encode those </xmp[> \n\r\t\f\/] sequences, right?
So that gives us the following markup (using just a possible encoding):
<xmp id="container">
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
</xmp>
Hmm.. shalt I get my crystal ball or flip a coin? No, let the computer look at its system-clock and state that a derived number is 'random'. Yes, that should do it..
Using a regex like: xmp.innerHTML.replace(/<(?=\/xmp[> \n\r\t\f\/])/gi, '<');, would translate 'back' to this:
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Hmm.. seems this random generator is broken... Houston..?
Should you have missed the joke/problem, read again starting at the 'intended raw code-snippet'.
Wait, I know, we (also) need to encode .... to ....
Ok, rewind to 'intended raw code-snippet' and read again.
Somehow this all begins to smell like the famous hilarious-but-true rexgex-answer on SO, a good read for people fluent in mojibake.
Maybe someone knows a clever algorithm or solution to fix this problem, but I assume that the embedded raw code will get more and more obscure to the point where you'd be better of properly escaping/encoding just your <, & (and >), just like the rest of the world.
Conclusion: (using the xmp tag)
it can be done with known snippets that do not contain the container's closing character-sequence,
we can get very close to the original objective with known snippets that only use 'basic first-level' escaping/encoding so we don't fall in the rabbithole,
but ultimately it seems that one can't do this reliably in a 'production-environment' where people can/should copy/paste/edit 'any unknown' raw snippets while not knowing/understanding the implications/rules/rabbithole (depending on your implementation of handling/translating for rule 1 and the rabbit-hole).
Hope this helps!
PS:
Whilst I would appreciate an upvote if you find this explanation useful, I kind of think Jukka's answer should be the accepted answer (should no better option/answer come along), since he was the one who remembered the xmp tag (that I forgot about over the years and got 'distracted' by the commonly advocated PCDATA elements like pre, textarea, etc.).
This answer originated in explaining why you can't do it (with any unknown raw snippet) and explain some obvious pitfalls that some other (now deleted) answers overlooked when advising a textarea for embedding/transport. I've expanded my existing explanation to also support and further explain Jukka's answer (since all that entity and *CDATA stuff is almost harder than code-pages).
Cheap and cheerful answer:
<textarea>Some raw content</textarea>
The textarea will handle tabs, multiple spaces, newlines, line wrapping all verbatim.
It copies and pastes nicely and its valid HTML all the way. It also allows the user to resize the code box.
You don't need any CSS, JS, escaping, encoding.
You can alter the appearance and behaviour as well.
Here's a monospace font, editing disabled, smaller font, no border:
<textarea
style="width:100%; font-family: Monospace; font-size:10px; border:0;"
rows="30" disabled
>Some raw content</textarea>
This solution is probably not semantically correct. So if you need that, it might be best to choose a more sophisticated answer.
xmp is the way to go, i.e.:
<xmp>
# your code...
</xmp>
echo '<pre>' . htmlspecialchars("<div><b>raw HTML</b></div>") . '</pre>';
I think that's what you're looking for?
In other words, use htmlspecialchars() in PHP
#GitaarLAB and #Jukka elaborate that <xmp> tag is obsolete, but still the best. When I use it like this
<xmp>
<div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
then the first EOL is inserted in the code, and it looks awful.
It can be solved by removing that EOL
<xmp><div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
but then it looks bad in the source. I used to solve it with wrapping <div>, but recently I figured out a nice CSS3 rule, I hope it also helps somebody:
xmp { margin: 5px 0; padding: 0 5px 5px 5px; background: #CCC; }
xmp:before { content: ""; display: block; height: 1em; margin: 0 -5px -2em -5px; }
This looks better.
If you have jQuery enabled you can use an escapeXml function and not have to worry about escaping arrows or special characters.
<pre>
${fn:escapeXml('
<!-- all your code -->
')};
</pre>
<code> tag is the good way because <xmp> and <pre> tags not support line wrapping
echo '<code>' . htmlspecialchars("<div><b>hello world</b></div>") . '</code>';
I'd like to display raw HTML. We all know one has to escape each "<" and ">" like this:
<PRE> this is a test <DIV> </PRE>
However, I do not want to do this. I'd like a way to keep the HTML code as is (since it is easier to read, (inside the editor) and I might want to copy it and use it again myself as actual HTML code, and do not want to have to change it again or have two versions of the same code, one escaped and one not escaped.
Is there any other environment that is more "raw" than PRE that might allow this? So one does not have to keep editing HTML and changing everything each time they want to show some raw HTML code, maybe in HTML5?
Something like <REALLY_REALLY_VERBATIM> ...... </<REALLY_REALLY_VERBATIM>
The JavaScript solution does not work on Firefox 21, here is a screenshot:
The first solution still does not work on Firefox, here is a screenshot:
You can use the xmp element, see What was the <XMP> tag used for?. It has been in HTML since the beginning and is supported by all browsers. Specifications frown upon it, but HTML5 CR still describes it and requires browsers to support it (though it also tells authors not to use it, but it cannot really prevent you).
Everything inside xmp is taken as such, no markup (tags or character references) is recognized there, except, for apparent reason, the end tag of the element itself, </xmp>.
Otherwise xmp is rendered like pre.
When using “real XHTML”, i.e. XHTML served with an XML media type (which is rare), the special parsing rules do not apply, so xmp is treated like pre. But in “real XHTML”, you can use a CDATA section, which implies similar parsing rules. It has no special formatting, so you would probably want to wrap it inside a pre element:
<pre><![CDATA[
This is a demo, tags like <p> will
appear literally.
]]></pre>
I don’t see how you could combine xmp and CDATA section to achieve so-called polyglot markup
Essentially the original question can be broken down in 2 parts:
Main objective/challenge: embedding(/transporting) a raw formatted code-snippet
(any kind of code) in a web-page's markup (for simple copy/paste/edit due to no
encoding/escaping)
correctly displaying/rendering that code-snippet (possibly edit it) in the
browser
The short (but) ambiguous answer is: you can't, ...but you can (get very close).
(I know, that are 3 contradicting answers, so read on...)
(polyglot)(x)(ht)ml Markup-languages rely on wrapping (almost) everything between begin/opening and end/closing tags/character(sequences).
So, to embed any kind of raw code/snippet inside your markup-language, one will always have to escape/encode every instance (inside that snippet) that resembles the character(-sequence) that would close the wrapping 'container' element in the markup. (During this post I'll refer to this as rule no 1.)
Think of "some "data" here" or <i>..close italics with '</i>'-tag</i>, where it is obvious one should escape/encode (something in) </i and " (or change container's quote-character from " to ').
So, because of rule no 1, you can't 'just' embed 'any' unknown raw code-snippet inside markup.
Because, if one has to escape/encode even one character inside the raw snippet, then that snippet would no longer be the same original 'pure raw code' that anyone can copy/paste/edit in the document's markup without further thought. It would lead to malformed/illegal markup and Mojibake (mainly) because of entities.
Also, should that snippet contain such characters, you'd still need some javascript to 'translate' that character(sequence) from (and to) it's escaped/encoded representation to display the snippet correctly in the 'webpage' (for copy/paste/edit).
That brings us to (some of) the datatypes that markup-languages specify. These datatypes essentially define what are considered 'valid characters' and their meaning (per tag, property, etc.):
PCDATA (Parsed Character DATA): will expand entities and one must
escape <, & (and > depending on markup language/version).
Most tags like body, div, pre, etc, but also textarea (until
HTML5) fall under this type.
So not only do you need to encode all the container's closing character-sequences
inside the snippet, you also have to encode all <, & (,>) characters
(at minimum).
Needless to say, encoding/escaping this many characters falls outside this
objective's scope of embedding a raw snippet in the markup.
'..But a textarea seems to work...', yes, either because of the browsers
error-engine trying to make something out of it, or because HTML5:
RCDATA (Replaceable Character DATA): will not not treat tags inside the
text as markup (but are still governed by rule 1), so one doesn't need to
encode < (>). BUT entities are still expanded, so they and 'ambiguous
ampersands' (&) need special care.
The current HTML5 spec says the textarea is now a RCDATA field and (quote):
The text in raw text and RCDATA elements must not contain any
occurrences of the string "</" (U+003C LESS-THAN SIGN, U+002F SOLIDUS)
followed by characters that case-insensitively match the tag name of
the element followed by one of 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 (>), or U+002F SOLIDUS (/).
Thus no matter what, textarea needs a hefty entity translation handler or
it will eventually Mojibake on entities!
CDATA (Character Data) will not treat tags inside the text as
markup and will not expand entities.
So as long as the raw snippet code does not violate rule 1 (that one can't
have the containers closing character(sequence) inside the snippet), this
requires no other escaping/encoding.
Clearly this boils down to: how can we minimize the number of characters/character-sequences that still need to be encoded in the snippet's raw source and the number of times that character(sequence) might appear in an average snippet; something that is also of importance for the javascript that handles the translation of these characters (if they occur).
So what 'containers' have this CDATA context?
Most value properties of tags are CDATA, so one could (ab)use a hidden input's value property (proof of concept jsfiddle here).
However (conform rule 1) this creates an encoding/escape problem with nested quotes (" and ') in the raw snippet and one needs some javascript to get/translate and set the snippet in another (visible) element (or simply setting it as a text-area's value). Somehow this gave me problems with entities in FF (just like in a textarea). But it doesn't really matter, since the 'price' of having to escape/encode nested quotes is higher then a (HTML5) textarea (quotes are quite common in source code..).
What about trying to (ab)use <![CDATA[<tag>bla & bla</tag>]]>?
As Jukka points out in his extended answer, this would only work in (rare) 'real xhtml'.
I thought of using a script-tag (with or without such a CDATA wrapper inside the script-tag) together with a multi-line comment /* */ that wraps the raw snippet (script-tags can have an id and you can access them by count). But since this obviously introduces a escaping problem with */, ]]> and </script in the raw snippet, this doesn't seem like a solution either.
Please post other viable 'containers' in the comments to this answer.
By the way, encoding or counting the number of - characters and balancing them out inside a comment tag <!-- --> is just insane for this purpose (apart from rule 1).
That leaves us with Jukka K. Korpela's excellent answer: the <xmp> tag seems the best option!
The 'forgotten' <xmp> holds CDATA, is intended for this purpose AND is indeed still in the current HTML 5 spec (and has been at least since HTML3.2); exactly what we need! It's also widely supported, even in IE6 (that is.. until it suffers from the same regression as the scrolling table-body).
Note: as Jukka pointed out, this will not work in true xhtml or polyglot (that will treat it as a pre) and the xmp tag must still adhere to rule no 1. But that's the 'only' rule.
Consider the following markup:
<!-- 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>
The above codeblok illustrates a raw piece of markup where <xmp id="snippet-container"> contains an (almost raw) code-snippet (containing div>div>xmp>html-document).
Notice the encoded closing tag in this markup? To comply with rule no 1, this was encoded/escaped).
So embedding/transporting the (sometimes almost) raw code is/seems solved.
What about displaying/rendering the snippet (and that encoded </xmp>)?
The browser will (or it should) render the snippet (the contents inside snippet-container) exactly the way you see it in the codeblock above (with some discrepancy amongst browsers whether or not the snippet starts with a blank line).
That includes the formatting/indentation, entities (like the string &), full tags, comments AND the encoded closing tag </xmp> (just like it was encoded in the markup). And depending on browser(version) one could even try use the property contenteditable="true" to edit this snippet (all that without javascript enabled). Doing something like textarea.value=xmp.innerHTML is also a breeze.
So you can... if the snippet doesn't contain the containers closing character-sequence.
However, should a raw snippet contain the closing character-sequence </xmp (because it is an example of xmp itself or it contains some regex, etc), you must accept that you have to encode/escape that sequence in the raw snippet AND need a javascript handler to translate that encoding to display/render the encoded </xmp> like </xmp> inside a textarea (for editing/posting) or (for example) a pre just to correctly render the snippet's code (or so it seems).
A very rudimentary jsfiddle example of this here. Note that getting/embedding/displaying/retrieving-to-textarea worked perfect even in IE6. But setting the xmp's innerHTML revealed some interesting 'would-be-intelligent' behavior on IE's part. There is a more extensive note and workaround on that in the fiddle.
But now comes the important kicker (another reason why you only get very close):
Just as an over-simplified example, imagine this rabbit-hole:
Intended raw code-snippet:
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Well, to comply with rule 1, we 'only' need to encode those </xmp[> \n\r\t\f\/] sequences, right?
So that gives us the following markup (using just a possible encoding):
<xmp id="container">
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
</xmp>
Hmm.. shalt I get my crystal ball or flip a coin? No, let the computer look at its system-clock and state that a derived number is 'random'. Yes, that should do it..
Using a regex like: xmp.innerHTML.replace(/<(?=\/xmp[> \n\r\t\f\/])/gi, '<');, would translate 'back' to this:
<!-- remember to translate between </xmp> and </xmp> -->
<xmp>
<p>a paragraph</p>
</xmp>
Hmm.. seems this random generator is broken... Houston..?
Should you have missed the joke/problem, read again starting at the 'intended raw code-snippet'.
Wait, I know, we (also) need to encode .... to ....
Ok, rewind to 'intended raw code-snippet' and read again.
Somehow this all begins to smell like the famous hilarious-but-true rexgex-answer on SO, a good read for people fluent in mojibake.
Maybe someone knows a clever algorithm or solution to fix this problem, but I assume that the embedded raw code will get more and more obscure to the point where you'd be better of properly escaping/encoding just your <, & (and >), just like the rest of the world.
Conclusion: (using the xmp tag)
it can be done with known snippets that do not contain the container's closing character-sequence,
we can get very close to the original objective with known snippets that only use 'basic first-level' escaping/encoding so we don't fall in the rabbithole,
but ultimately it seems that one can't do this reliably in a 'production-environment' where people can/should copy/paste/edit 'any unknown' raw snippets while not knowing/understanding the implications/rules/rabbithole (depending on your implementation of handling/translating for rule 1 and the rabbit-hole).
Hope this helps!
PS:
Whilst I would appreciate an upvote if you find this explanation useful, I kind of think Jukka's answer should be the accepted answer (should no better option/answer come along), since he was the one who remembered the xmp tag (that I forgot about over the years and got 'distracted' by the commonly advocated PCDATA elements like pre, textarea, etc.).
This answer originated in explaining why you can't do it (with any unknown raw snippet) and explain some obvious pitfalls that some other (now deleted) answers overlooked when advising a textarea for embedding/transport. I've expanded my existing explanation to also support and further explain Jukka's answer (since all that entity and *CDATA stuff is almost harder than code-pages).
Cheap and cheerful answer:
<textarea>Some raw content</textarea>
The textarea will handle tabs, multiple spaces, newlines, line wrapping all verbatim.
It copies and pastes nicely and its valid HTML all the way. It also allows the user to resize the code box.
You don't need any CSS, JS, escaping, encoding.
You can alter the appearance and behaviour as well.
Here's a monospace font, editing disabled, smaller font, no border:
<textarea
style="width:100%; font-family: Monospace; font-size:10px; border:0;"
rows="30" disabled
>Some raw content</textarea>
This solution is probably not semantically correct. So if you need that, it might be best to choose a more sophisticated answer.
xmp is the way to go, i.e.:
<xmp>
# your code...
</xmp>
echo '<pre>' . htmlspecialchars("<div><b>raw HTML</b></div>") . '</pre>';
I think that's what you're looking for?
In other words, use htmlspecialchars() in PHP
#GitaarLAB and #Jukka elaborate that <xmp> tag is obsolete, but still the best. When I use it like this
<xmp>
<div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
then the first EOL is inserted in the code, and it looks awful.
It can be solved by removing that EOL
<xmp><div>Lorem ipsum</div>
<p>Hello</p>
</xmp>
but then it looks bad in the source. I used to solve it with wrapping <div>, but recently I figured out a nice CSS3 rule, I hope it also helps somebody:
xmp { margin: 5px 0; padding: 0 5px 5px 5px; background: #CCC; }
xmp:before { content: ""; display: block; height: 1em; margin: 0 -5px -2em -5px; }
This looks better.
If you have jQuery enabled you can use an escapeXml function and not have to worry about escaping arrows or special characters.
<pre>
${fn:escapeXml('
<!-- all your code -->
')};
</pre>
<code> tag is the good way because <xmp> and <pre> tags not support line wrapping
echo '<code>' . htmlspecialchars("<div><b>hello world</b></div>") . '</code>';
I am working with bidirectional text (mixed English and Hebrew) for a project. The text is displayed in HTML, so sometimes a LTR or RTL mark ( or ) is required to make 'weak characters' like punctuation display properly. These marks are not present in the source text due to technical limitations, so we need to add them in order for the final displayed text to appear correct.
For instance, the following text: (example: מדגם) sample renders as sample (מדגם :example) in right-to-left mode. The corrected string would look like (example: מדגם) sample and would render as sample (מדגם (example:.
We'd like to do on-the-fly insertion of these marks rather than re-authoring all the text. At first this seems simple: just append an to each instance of punctuation. However, some of the text that needs to get modified on-the-fly contains HTML and CSS. The reasons for this are unfortunate and unavoidable.
Short of parsing HTML/CSS, is there a known algorithm for on-the-fly insertion of Unicode directional marks (pseudo-strong characters)?
I don't know of an algorithm to insert directional marks into an HTML string safely without parsing it. Parsing the HTML into a DOM and manipulating the text nodes is the safest way of ensuring you don't accidentally add directional marks to text inside <script> and <style> tags.
Here is a short Python script which might help you transform your files automatically. The logic should be easy to translate into other languages if necessary. I'm not familiar enough with the RTL rules you're trying to encode, but you can tweak the regexp '(\W([^\W]+)(\W)' and substituion pattern ur"\u200e\1\2\3\u200e" to get your expected result:
import re
import lxml.html
_RE_REPLACE = re.compile('(\W)([^\W]+)(\W)', re.M)
def _replace(text):
if not text:
return text
return _RE_REPLACE.sub(ur'\u200e\1\2\3\u200e', text)
text = u'''
<html><body>
<div>sample (\u05de\u05d3\u05d2\u05dd :example)</div>
<script type="text/javascript">var foo = "ignore this";</script>
<style type="text/css">div { font-size: 18px; }</style>
</body></html>
'''
# convert the text into an html dom
tree = lxml.html.fromstring(text)
body = tree.find('body')
# iterate over all children of <body> tag
for node in body.iterdescendants():
# transform text with trails after the current html tag
node.tail = _replace(node.tail)
# ignore text inside script and style tags
if node.tag in ('script','style'):
continue
# transform text inside the current html tag
node.text = _replace(node.text)
# render the modified tree back to html
print lxml.html.tostring(tree)
Output:
python convert.py
<html><body>
<div>sample (מדגם :example)</div>
<script type="text/javascript">var foo = "ignore this";</script>
<style type="text/css">div { font-size: 18px; }</style>
</body></html>
Certain fields in our mysql db appear to contain newline characters so that if I SELECT on them something like the following will be returned for a single SQL call:
Life to be sure is nothing much to lose
But young men think it is and we were young
If I want to preserve the line breaks when displaying this field on a webpage, is the standard solution to write a script to replace '\n\r' with a br HTML tag or is there a better way?
Thanks!
Assuming PHP here...
nl2br() adds in <br /> for every \n. Don't forget to escape the content first, to prevent XSS attacks. See below:
<?php echo nl2br(htmlspecialchars($content)); ?>
HTML is a markup language. Regardless of how many linebreaks you put in the source code, you won't see anything from it back in the presentation (of course assuming you aren't using <pre> or white-space:pre). HTML uses the <br> element to represent a linebreak. So you basically indeed need to convert the real and invisible linebreaks denoted by the characters xA (newline, linefeed, LF, \n) and/or xD (carriage return, CR, \r) by a HTML <br> element.
In most programming languages you can just do this by a string replace of "\n" by "<br>".
You can wrap it in <pre> .. </pre>.
When working with CSS inside of XML such as
<span class="IwuvAS3"></span>
when parsed in flash, if I don't use CDATA like the following:
<![CDATA[<span class="IwuvAS3"></span>]]>
then the parsed data drops down a line for every "<" character it sees.
When parsing the data into a single-line text field, nothing was shown because it was actually down a line. Soon as I wrap it inside of CDATA it works great. I have played with prettyIndent, and as I understand ignoreWhite is true by default.
Is there a way to parse the data without the use of CDATA and keep the implied line breaks out?
EDIT 1 (10/10/08): Thank you, but I am actually looking for a Function or Method. Escaping each is much more cumbersome than using CDATA. The only reason I don't want to use CDATA is that I was taught to stay clear of it. If ActionScript has a method associated to E4X XML handling that will remove the requirement to wrap my XML in CDATA, I would love to know about it.
EDIT 1 (10/15/08): Thanks Philippe! I never would have thought that HTML formatting in Flash is treated as whitespace. The answer was
textField.condenseWhite = true;
<3AS3
Set the TextField's condenseWhite property to true - so only < br/> tags will generate linebreaks.
You could escape the "<" characters (and &, ", >, ', among others) as entities instead.