Skip to content

Instantly share code, notes, and snippets.

@johnno1962
Last active May 9, 2016 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnno1962/5c325a16838ad3c73e0f109a514298bf to your computer and use it in GitHub Desktop.
Save johnno1962/5c325a16838ad3c73e0f109a514298bf to your computer and use it in GitHub Desktop.
Multi-line String Zoo
// 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