Last active
May 9, 2016 11:11
-
-
Save johnno1962/5c325a16838ad3c73e0f109a514298bf to your computer and use it in GitHub Desktop.
Multi-line String Zoo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Multi-line string proposals | |
// https://github.com/apple/swift/pull/2275 | |
// swift-evolution thread: | |
// http://thread.gmane.org/gmane.comp.lang.swift.evolution/904/focus=15133 | |
// These examples should load in the prototype toolchain available here: | |
// http://johnholdsworth.com/swift-LOCAL-2016-05-09-a-osx.tar.gz | |
// The prototype currently parses three new forms of quoting | |
// These new types are still string literals for the grammar. | |
"the existing string literal format" | |
_"a format that does not require you to escape " characters"_ // possibly redundant | |
"""a python-style syntax that will accept "'s and newlines in the string""" | |
<<"HEREDOC" | |
A full heredoc implementation (will always end in a newline) | |
HEREDOC | |
// These strings can be modified by prefixing the string by letters | |
// There is currently only one, "e" to disable escape processing. | |
// This is primarily used when specifying regular expressions. | |
let str = "print(\"Hello, world!\\n\")" | |
assert( e"print(\"Hello, world!\n\")" == str ) | |
assert( e_"print("Hello, world!\n")"_ == str ) | |
assert( e"""print("Hello, world!\n")""" == str ) | |
// Continuation quotes allow you to extend a standard string literal | |
// over multiple lines. If a string does not close on a line and the | |
// first non-whitespace character on the next line is " that line | |
// will be a contination of the string including the newline character | |
// (unless it is escaped). Interpolation and escapes process as before | |
// unless the first segment of the string is modified by the "e" prefix. | |
// The advantage of this format allows you to indent while giving | |
// you precise control of exactly what is going into the literal. | |
let author = "Gambardella, Matthew" | |
let xml = "<?xml version=\"1.0\"?> | |
"<catalog> | |
" <book id=\"bk101\" empty=\"\"> | |
" <author>\(author)</author> | |
" <title>XML Developer's Guide</title> | |
" <genre>Computer</genre> | |
" <price>44.95</price> | |
" <publish_date>2000-10-01</publish_date> | |
" <description>An in-depth look at creating applications with XML.</description> | |
" </book> | |
"</catalog> | |
"" | |
print(xml) | |
// Perhaps, to avoid the zera crossing effect in text editors due to | |
// the unbalanced quotes, the continuation character could be "|". | |
// (newlines escaped with \ and blank lines are discarded.) | |
assert( xml == "\ | |
|<?xml version=\"1.0\"?> | |
|<catalog> | |
| <book id=\"bk101\" empty=\"\"> | |
| <author>\(author)</author> | |
| <title>XML Developer's Guide</title> | |
| <genre>Computer</genre> | |
| <price>44.95</price> | |
| <publish_date>2000-10-01</publish_date> | |
| <description>An in-depth look at creating \ | |
|applications with XML.</description> | |
| </book> | |
|</catalog> | |
|" ) | |
// _""_ quoted strings also suppport these behaviours but don't require | |
// escaping of embedded " characters. Think of them as a being modifier | |
// on conventional string literals. They support continuation quotes. | |
assert( xml == _"<?xml version="1.0"?> | |
"<catalog> | |
" <book id="bk101" empty=""> | |
" <author>\(author)</author> | |
" <title>XML Developer's Guide</title> | |
" <genre>Computer</genre> | |
" <price>44.95</price> | |
" <publish_date>2000-10-01</publish_date> | |
" <description>An in-depth look at creating applications with XML.</description> | |
" </book> | |
"</catalog>\n"_ ) | |
// _"strings"_ could allow newlines and replace """strings""" discussed next | |
assert( xml == _"<?xml version="1.0"?> | |
<catalog> | |
<book id="bk101" empty=""> | |
<author>\(author)</author> | |
<title>XML Developer's Guide</title> | |
<genre>Computer</genre> | |
<price>44.95</price> | |
<publish_date>2000-10-01</publish_date> | |
<description>An in-depth look at creating applications with XML.</description> | |
</book> | |
</catalog> | |
"_ ) | |
// The triple quoted strings can contain newlines and, unless modified by "e" | |
// will process interpolations and not require escaping of ". To allow indenting, | |
// any whitespace characters that preceed the closing """ will be removed from | |
// each line of the final literal. A warning is shown if lines do not contain | |
// the exact same indentation characters. Any intial linefeed is also removed. | |
// The advantage of this format is the """ introducer works well when syntax | |
// highlighting in external editors and github as quotes are always balanced. | |
assert( xml == """ | |
<?xml version="1.0"?> | |
<catalog> | |
<book id="bk101" empty=""> | |
<author>\(author)</author> | |
<title>XML Developer's Guide</title> | |
<genre>Computer</genre> | |
<price>44.95</price> | |
<publish_date>2000-10-01</publish_date> | |
<description>An in-depth look at creating applications with XML.</description> | |
</book> | |
</catalog> | |
""" ) | |
assert( xml != e"""<?xml version="1.0"?> | |
<catalog> | |
<book id="bk101" empty=""> | |
<author>\(author)</author> | |
<title>XML Developer's Guide</title> | |
<genre>Computer</genre> | |
<price>44.95</price> | |
<publish_date>2000-10-01</publish_date> | |
<description>An in-depth look at creating applications with XML.</description> | |
</book> | |
</catalog> | |
""" ) | |
// heredoc syntax comes in two variants <<"TAG" and <<'TAG' (non-escaping, "e" prefix) | |
// It applies the same indentation removal rules as does """. This change has wider | |
// ramifications for the toolchain as compiler tokens are no longer in file order | |
// and will take a while for a few problems to be ironed out. The more consistent | |
// <<e"TAG" is a rather clumsy alternative to <<'TAG' for non-escaping strings. | |
// HEREDOC's advantage is that the literal no longer interrupts the flow of your code. | |
assert( (<<"XML" + <<"XML") == xml + xml ) | |
<?xml version="1.0"?> | |
<catalog> | |
<book id="bk101" empty=""> | |
<author>\(author)</author> | |
<title>XML Developer's Guide</title> | |
<genre>Computer</genre> | |
<price>44.95</price> | |
<publish_date>2000-10-01</publish_date> | |
<description>An in-depth look at creating applications with XML.</description> | |
</book> | |
</catalog> | |
XML | |
<?xml version="1.0"?> | |
<catalog> | |
<book id="bk101" empty=""> | |
<author>\(author)</author> | |
<title>XML Developer's Guide</title> | |
<genre>Computer</genre> | |
<price>44.95</price> | |
<publish_date>2000-10-01</publish_date> | |
<description>An in-depth look at creating applications with XML.</description> | |
</book> | |
</catalog> | |
XML | |
// For text you do not want to contain newlines, escape them using \ | |
print( <<"LOREM" ) | |
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt \ | |
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco \ | |
laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in \ | |
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat \ | |
non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.\ | |
LOREM | |
// There is final experimental modifier "r" which allows non-standard escapes | |
// for regexps but still processes the standard ones including interpolation. | |
// HEREDOC this could use <<`TAG` | |
assert( e"\w\d+\(author)\n" == "\\w\\d+\\(author)\\n" ) | |
assert( r"\w\d+\(author)\n" == "\\w\\d+\(author)\n" ) // extra escapes but with interpolation | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment