reptile7's JavaScript blog
Friday, February 05, 2010
Let's Get Out While We Can
Blog Entry #170

So, what's on tap today? In this post we'll check over HTML Goodies' "Escape Characters" tutorial. "Escape Characters" briefly discusses the following JavaScript special characters:
(1-2) \' and \", towards the end of respectively placing single-quote/apostrophe and double-quote characters in dialog box messages and in document.write( ) strings; and
(3-4) \r and \t, towards the end of respectively inserting line breaks and tabs in dialog box messages.

Backslash it

Joe's description of the role of the backslash (\) character in a JavaScript special character is a bit hazy:
The backslash is the key. If you plop that in front of the quotes or the letter "r" you escape the coding long enough for the script to understand you want the character to represent text rather than a command to be used in the coding. That's why we call it an escape character. Get it?
I myself don't like the use of the word "escape" in this context. The backslash in a JavaScript special character is in essence an operator that transforms certain literal characters to metacharacters - characters that have a special function and consequently are not meant to be interpreted literally - and certain metacharacters to literal characters. (Joe's above quote addresses the metacharacter ("command") to literal character ("text") operation but not the literal character to metacharacter operation.)

For example, in JavaScript the single-quote (') and double-quote (") characters are metacharacters whose special function is to delimit string literals. If you want these characters to appear as literal characters in a string, you can if necessary convert them to literal characters by preceding them with a backslash, as detailed below. The backslash itself is a metacharacter that signals the beginning of a JavaScript special character, and must be prepended with another backslash to be rendered literally in a string.

Complementarily, preceding a lowercase n with a backslash transforms it from a literal character to a \n metacharacter signifying a newline; prefacing a literal t with a backslash creates a \t metacharacter signifying a horizontal tab; and so on. For most literal characters, however, a preceding backslash has no effect and is ignored by the JavaScript engine, e.g., window.alert("Hello \World"); will simply display Hello World on the alert( ) box.

Alternatively, there are ways to reference a literal character in JavaScript that involve a backslash, e.g., a lowercase a can be encoded by
(1) \141 (using its octal ASCII code position),
(2) \x61 (using its hexadecimal ASCII code position), and
(3) \u0061 (using its Unicode code position);
however, such formulations are not discussed in "Escape Characters".

Quote formatting, revisited

In the tutorial, Joe seems to have a fundamental misunderstanding of JavaScript quote formatting as he implies that single-quote and double-quote characters appearing in strings are necessarily escaped, which is not true. Here is his sample code for putting single-quote/apostrophe and double-quote characters in a document.write( ) string:

document.write('We\'re going to \"need\" to know where you\'re going tonight, young man!');

To review, it is necessary to
(a) escape single-quote/apostrophe characters in a string delimited by single quotes and
(b) escape double-quote characters in a string delimited by double quotes, but
(c) double-quote characters can appear literally ("unescaped") in a string delimited by single quotes and
(d) single-quote/apostrophe characters can appear literally in a string delimited by double quotes.
This all holds regardless of the extent of quote nesting:

document.write('Alice said, "Bob said, \'Carol said, "Dave said, \'...\' " \' " ');

It follows that, whereas the apostrophes in Joe's write( ) string, which he chose to delimit with single quotes, must indeed be escaped, there's no need whatsoever to escape the double quotes surrounding the word need, and the command can be written as:

document.write('We\'re going to "need" to know where you\'re going tonight, young man!');

Per the discussion of the previous section, there are several other ways to encode an apostrophe in JavaScript: \047, \x27, and \u0027 will all do the trick. In addition, for a document.write( ) command executed by a Web browser, apostrophes can also be coded by ' or ' HTML character references because the write( ) string constitutes HTML element #PCDATA content - even if you don't specify any markup, the string is still part of the body element. But obviously, the easiest way to code an apostrophe in this case is to just precede it with a backslash.

Had Joe delimited the write( ) string with double quotes, the apostrophes could have appeared literally but then the double quotes around need would need to be escaped or referenced as described above.

For Netscape's own discussion of JavaScript quote formatting (which could be more complete than it is, but I guess you could say that about pretty much all coding instructional material), see the "String Literals" and "Using Quotation Marks" sections in the JavaScript 1.3 Client-Side Guide.

Break my lines

Joe rolls out prompt( ) and alert( ) box examples in which the \r escape sequence is used to induce line breaks in the messages on the boxes. Here's his prompt( ) box code:

var name = prompt("Please write your \'name\' in the box\rWrite it with \"quotes\" like this.","");
// Again, the single quotes surrounding the word name do not need to be escaped.

The \r sequence signifies a carriage return, which does not correspond to a move-to-the-first-character-position-of-the-next-line effect in all situations but does so in HTML and in JavaScript as well, at least with most browsers. (This doesn't mean that a carriage return will necessarily generate a line break in practice, as explained below.) However, two "Escape Characters" commenters report that they're having a problem with Joe's \r examples when using Firefox; sure enough, Firefox ignores the \r sequence altogether (both characters, not just the backslash) on a prompt( ) or alert( ) or confirm( ) box:

Joe's 'Prompt Example' when using Firefox

All of the other OS X GUI browsers on my computer - Camino, Chrome, MSIE, Opera, and Safari - force a line break after the word box in the prompt( ) text. (Firefox automatically wraps the prompt( ) text after the nested "quotes" string; Joe does not force a line break at this point in the text.) Another commenter points out that the correct escape sequence for a newline is \n, and replacing \r with \n does indeed give the expected effect with Firefox:

A Firefox prompt( ) box featuring a newline

Unlike the window dialog methods, which are at least for now purely scriptic methods, document.write( ) has long had one foot in the HTML world (as implied above), and neither \r nor \n in a document.write( ) string will normally force a line break because, per the W3C's recommendation, Web browsers generally render carriage returns and newlines as ASCII spaces, i.e., space characters as generated by the space bar at the bottom of the keyboard. (This is also the reason why the document.writeln( ) method does not normally induce line breaks.) There is an important exception to this: wrapping a write( ) string in a pre element will enable you to force line breaks with \r or \n sequences, e.g.,

document.write("<pre>The backslash\ris the key.</pre>"

The backslash
is the key.
But as Joe notes in the tutorial's "document.write Example" section, document.write( ) line breaks are more straightforwardly effected via the br element.

Keeping tabs on tabs

Finally, Joe offers the following code for an alert( ) box whose message comprises nine text lines and contains a three-line section formatted with \t tabs:

alert('OK Then!\r\rYou want a neat box like \"this\" one?\r\rWell!\r\rYou\'ll need:\rBrains\tBeauty\t\tTalent\rMoney\tDog food\t\tLuck\rA Cat\tEye of Newt\tA Shrubbery!\r\rAnd the ability to \'read\' this tutorial.\r\rOK?');
// The tabbed section is in purple.

Most of the OS X browsers on my computer (including Lynx!) render a tab as eight ASCII spaces in a monospace font. To the extent that this is a 'normal' rendering, here's what Joe's alert( ) box should look like:
Joe's 'Alert Example' when using Chrome
On the other hand, dialog box text is generally rendered in a sans-serif font - this is why it is necessary to put two tabs between Dog food, which contains eight characters but does not quite reach the second tab stop, and Luck in order to get Luck to line up with Talent and A Shrubbery! in the third column of the tabbed section of the alert( ) box.
Brains	Beauty		Talent
Money	Dog food		Luck
A Cat	Eye of Newt	A Shrubbery!
Browser notes

• For Firefox, change each \r to a \n and the alert( ) box will look as it should.

• Camino cuts off the OK? at the bottom of the box although the rest of the box looks OK.

Joe's 'Alert Example' when using Camino

• MSIE 5.2.3 won't render tabs at all. :-(
Joe's 'Alert Example' when using MSIE 5.2.3
As for a \r carriage return and a \n newline, a \t tab in a document.write( ) string will translate to an ASCII space unless the write( ) string is wrapped in a pre element, speaking of which...

Tabs - HTML Goodies

Near the end of the "Prompt Example" section, Joe links to a sister tutorial, "Tabs - HTML Goodies", which according to the top of its page should be located in HTML Goodies' /beyond/javascript/ directory although there's no link to it on the "Beyond HTML : JavaScript" portal page. "Tabs - HTML Goodies" discusses the creation of a tabbed layout via placing \t sequences in document.write( ) strings and then wrapping the write( ) text in a pre or xmp element. Don't use the xmp element: it's obsolete. Use the pre element if you're going to do this.

Moreover, in "Tabs - HTML Goodies" Joe notes, Others told me they created a tabbed layout*, copied and pasted it into their HTML document and then surround[ed] it with the <pre> or <xmp> tags, which IMO is a better approach to HTML tabbing than the document.write( ) and \t approach, notwithstanding Joe's later, somewhat-at-variance comment that I know I said earlier in the tutorial that using the pre or xmp tag didn't work [in a non-script HTML context] because the tabs often didn't transfer correctly - especially if you're using a non-block font. (I'm not quite sure what Joe means by "non-block [sans-serif?] font", as "block" is not one of the W3C's generic font families.)

*Perhaps the most reliable way to generate tabs in HTML is to hard-code them with &#9; character references (which will still need to appear in a pre element) - it was necessary for me to do this for my Dog food-to-Luck graphic above because, even as pre element content, my keyboard-tab-key-generated tabs are converted to ASCII spaces in the Blogger post textarea field.

Pre element text is typically rendered in a monospace font, and if you were to override this - with, say, a font-family:Arial,sans-serif; CSS declaration - then I can see how it might cause problems with your tabbing. If you're serious about using tabs, keep everything in a monospace font and you should be able to work it out.

Next up on the "Beyond HTML : JavaScript" menu is a "JavaScript Date/Time Methods" series of four tutorials that we'll dispatch collectively in the following entry.


Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)