Hi. The solutions discussed so far have the following disadvantages: - They need a specific delimiter token, which cannot be used in the text itself. - The data cannot be used as-is, escape \ characters are needed. - Imho, they are somewhat complicated.
In my emails previously submitted I came up with a "data line” concept, a very simple solution, which tackles these disadvantages and is very easy to use and understand! Did you actually read it? I now quote the primary description hereunder again, in case you’ve missed it, imaginable, because there is a lot of text flying around. Additionally, the following improvements have developed in my thinking: In the mean time I consider using two tokens \\ and \@: \\…data…data…data…data………….. accepts data and converts \n \t etc. or data lines starting with: \@…data…data…data…data… .……. accepts data as-is, without conversion and respects the linefeeds of the source-file. the // and /@ tokens do not have to start at the beginning of a line, are allowed further to the right as long as there are only space(s) to the left of it. let music = \\when Doves Cry\nBy Prince and \\ The Revolution\nWhat music \\ can be\t\t\t\tIt is \”Magic\” really. If you do or don’t like this solution -apart from cosmetic viewpoints- please tell me why. so I can improve it, or try to come back with something better if i can. let epilogue = \@Thank you so much for reading my \@ “contribution" Please tell me \@what you think, I \\\\\\\\\\\\\value//////////// your opinion! \@“””””””””””””””””””””” kind Regards! “”””””””””””””””" \@ Ted. (the previous text following \@ data lines are accepted as-is, including the source-file’s linefeeds or crlf and the double quotes) Of course, other tokens are possible as well. Can’t be any simpler than this, I guess. TedvG ===================As Previously Written:================= This could be a simple solution: Starting each line with a special token. In the example here it is the \\ double-backslash . when the \\ appears in the first two columns of a source line, this tells the compiler that it is a data line and that more might follow. the last line starting with \\ completes the data entry. Here is an example of a string declaration with some XML (no escape sequences needed for “) Of course it could be anything other kind of textual data as well. let str = \\<!DOCTYPE html> \\<html> \\<body> \\ \\<h1>W3Schools Internal Note</h1>\n \\<div> \\<b>To:</b> <span id="to"></span><br>\n \\<b>From:</b> <span id="from"></span><br>\n \\<b>Message:</b> <span id="message"></span> \\</div> \\\n \\<script> \\var <smb://var> txt, parser, xmlDoc; \\txt <smb://txt> = "<note>" + \\"<to>Tove</to>" + \\etc <smb://etc>. this is the last data line. Conditions: - Every line starting with \\ in first and second column of the line is treated as a data line. - All characters behind the \\ are regarded as data, thus note that: - the “ is not regarded as a string delimiter - the // chars and whatever follows it are interpreted as data on such a line, not as comment. - \\ within the data itself are treated as data e.g. this line is valid: \\There <smb://There> \\ are three backslashes (as data) in this line \\\\ today. \\ the above data line is empty but is allowed. for \\ - Leading and embedded spaces are respected. - Tabs, Linefeeds etc. can be inserted the usual way using \t \n etc. - trailing spaces and line terminators cr lf are ignored, filtered out. ============================================================ Wed, 27 Apr 2016 16:08:13 +0300"Vladimir.S" <sva...@gmail.com <mailto:sva...@gmail.com>> wrote: > On 27.04.2016 11:52, Brent Royal-Gordon via swift-evolution wrote: >>> If you agree that these are all orthogonal pieces, then treat them as >>> such: I’d suggest that you provide a proposal that just tackles the >>> continuation string literals. This seems simple, and possible to get in >>> for Swift 3. >> >> I've gone ahead and drafted this proposal, with some small extensions and >> adjustments. See the "Draft Notes" section for details of what I've changed >> and what concerns I have. > > I don't feel like this proposal(draft) solves the issue we want(?) to solve > with multi-line feature. > > I expect to be able to have multiline text exactly *"as-is"* in my source > file. No escaping, no interpolation, etc. I believe this should be a target > of the proposal. > Otherwise, I reject to see any reason to introduce anything new at this > area - we already can concatenate strings and place them on next line and > escape special characters. > > In your proposal, you have to escape characters in your text, you need to > carefully modify the copy-pasted text to be allowed as correct multi-line > string. Also, what if I need to have spaces *at the end of string* ? Editor > can just trimmed them, and we can't clearly see them. > > Personally I need to be able to have this(in some way) in my code: > (note this "\tuttorial" and "\(edition" - this is just text, I want to have > inside my xml) > > let xml = ... // some marker to start the multi-line str > <?xml version="1.0"?> > <catalog> > <book id="myid" empty=""> > <author>myAuthor</author> > <title>myTitle \tutorial 1\(edition 2)</title> > </book> > </catalog> > ... // some marker here to stop multi-line str > > It seems like we need some markers for end-of-the-line to be able to keep > spaces/tabs in the end of line. > > What about something like this. Two suported variants : first when we need > to keep spaces in the end of line, and second when we don't need > spaced(will be trimmed by parser) > > #1 (parser should just take the text between first and last quote *as-is*) > > let xml = "\ > "<?xml version="1.0"?> " // yes, *I need* these spaces at the end > "<catalog>" > " <book id="myid" empty="">" > " <author>myAuthor</author>" > " <title>myTitle \tutorial 1\(edition 2)</title>" > " </book>" > "</catalog>" > " > > #2 in this case we don't need any spaces/tabs in the end of lines(don't care): > (parser takes all that is after | as-is but trims any trailing spaces/tabs > in lines to be clear in behaviour) > > let xml = "\ > |<?xml version="1.0"?> > |<catalog> > | <book id="myid" empty=""> > | <author>myAuthor</author> > | <title>myTitle \tutorial 1\(edition 2)</title> > | </book> > |</catalog> > " > > Or these two could be combined in one(as-is between |..|) but I'm not sure: > > let xml = "\ > |<?xml version="1.0"?> | // yes, I need these spaces > |<catalog>| // we have to have closing symbol in this case in other lines > | <book id="myid" empty="">| > | <author>myAuthor</author>| > | <title>myTitle \tutorial 1\(edition 2)</title>| > | </book>| > |</catalog>| > " > > >> >> Gist: <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f>> >> >> >> Multiline string literals >> >> * Proposal: SE-NNNN >> >> <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md >> <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md>> >> * Author(s): Brent Royal-Gordon <https://github.com/brentdax >> <https://github.com/brentdax>> >> * Status: First Draft >> * Review manager: TBD >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction>>Introduction >> >> In Swift 2.2, the only means to insert a newline into a string literal is >> the |\n| escape. String literals specified in this way are generally ugly >> and unreadable. We propose a multiline string feature inspired by English >> punctuation which is a straightforward extension of our existing string >> literals. >> >> Swift-evolution thread: multi-line string literals. >> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html >> >> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html>> >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes>>Draft >> Notes >> >> * >> >> This draft differs from the prototypes being thrown around on the list >> in that it specifies that comments should be treated as whitespace, and >> that whitespace-only lines in the middle of a multiline string should >> be ignored. I'm not sure if this is feasible from a parsing standpoint, >> and I'd like feedback from implementers on this point. >> >> * >> >> This draft also specifies diagnostics which should be included. >> Feedback on whether these are good choices would be welcome. >> >> * >> >> I am considering allowing you to put a backslash before the newline to >> indicate it should /not/ be included in the literal. In other words, >> this code: >> >> print("foo\ >> "bar") >> >> Would print |"foobar"|. However, I think this should probably be >> proposed separately, because there may be a better way to do it. >> >> * >> >> I've listed only myself as an author because I don't want to put anyone >> else's name to a document they haven't seen, but there are others who >> deserve to be listed (John Holdsworth at least). Let me know if you >> think you should be included. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation>>Motivation >> >> As Swift begins to move into roles beyond app development, code which needs >> to generate text becomes a more important use case. Consider, for instance, >> generating even a small XML string: >> >> let xml = "<?xml version=\"1.0\"?>\n<catalog>\n\t<book id=\"bk101\" >> empty=\"\">\n\t\t<author>\(author)</author>\n\t</book>\n</catalog>" >> >> The string is practically unreadable, its structure drowned in escapes and >> run-together characters; it looks like little more than line noise. We can >> improve its readability somewhat by concatenating separate strings for each >> line and using real tabs instead of |\t| escapes: >> >> let xml = "<?xml version=\"1.0\"?>\n" + >> "<catalog>\n" + >> " <book id=\"bk101\" empty=\"\">\n" + >> " <author>\(author)</author>\n" + >> " </book>\n" + >> "</catalog>" >> >> However, this creates a more complex expression for the type checker, and >> there's still far more punctuation than ought to be necessary. If the most >> important goal of Swift is making code readable, this kind of code falls >> far short of that goal. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution>>Proposed >> solution >> >> We propose that, when Swift is parsing a string literal, if it reaches the >> end of the line without encountering an end quote, it should look at the >> next line. If it sees a quote mark there (a "continuation quote"), the >> string literal contains a newline and then continues on that line. >> Otherwise, the string literal is unterminated and syntactically invalid. >> >> Our sample above could thus be written as: >> >> let xml = "<?xml version=\"1.0\"?> >> "<catalog> >> " <book id=\"bk101\" empty=\"\"> >> " <author>\(author)</author> >> " </book> >> "</catalog>" >> >> (Note that GitHub is applying incorrect syntax highlighting to this code >> sample, because it's applying Swift 2 rules.) >> >> This format's unbalanced quotes might strike some programmers as strange, >> but it attempts to mimic the way multiple lines are quoted in English >> prose. As an English Stack Exchange answer illustrates >> <http://english.stackexchange.com/a/96613/64636 >> <http://english.stackexchange.com/a/96613/64636>>: >> >> “That seems like an odd way to use punctuation,” Tom said. “What harm >> would there be in using quotation marks at the end of every paragraph?” >> >> “Oh, that’s not all that complicated,” J.R. answered. “If you closed >> quotes at the end of every paragraph, then you would need to reidentify >> the speaker with every subsequent paragraph. >> >> “Say a narrative was describing two or three people engaged in a >> lengthy conversation. If you closed the quotation marks in the previous >> paragraph, then a reader wouldn’t be able to easily tell if the >> previous speaker was extending his point, or if someone else in the >> room had picked up the conversation. By leaving the previous >> paragraph’s quote unclosed, the reader knows that the previous speaker >> is still the one talking.” >> >> “Oh, that makes sense. Thanks!” >> >> Similarly, omitting the ending quotation mark tells the code's reader (and >> compiler) that the literal continues on the next line, while including the >> continuation quote reminds the reader (and compiler) that this line is part >> of a string literal. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes>>Benefits >> of continuation quotes >> >> It would be simpler to not require continuation quotes, so why are they >> required by this proposal? There are three reasons: >> >> 1. >> >> *They help the compiler pinpoint errors in string literal >> delimiting.* If continuation quotes were not required, then a missing >> end quote would be interpreted as a multiline string literal. This >> string literal would continue until the compiler encountered either >> another quote mark—perhaps at the site of another string literal or in >> a comment—or the end of the file. In either case, the compiler could at >> best only indicate the start of the runaway string literal; in >> pathological cases (for instance, if the next string literal >> was |"+"|), it might not even be able to do that properly. >> >> With continuation quotes required, if you forget to include an end >> quote, the compiler can tell that you did not intend to create a >> multiline string and flag the line that actually has the problem. It >> can also provide immediately actionable fix-it assistance. The fact >> that there is a redundant indication on each line of the programmer's >> intent to include that line in a multiline quote allows the compiler to >> guess the meaning of the code. >> >> 2. >> >> *They separate indentation from the string's contents.* Without >> continuation quotes, there would be no obvious indication of whether >> whitespace at the start of the line was intended to indent the string >> literal so it matched the surrounding code, or whether that whitespace >> was actually meant to be included in the resulting string. Multiline >> string literals would either have to put subsequent lines against the >> left margin, or apply error-prone heuristics to try to guess which >> whitespace was indentation and which was string literal content. >> >> 3. >> >> *They improve the ability to quickly recognize the literal.* The |"| on >> each line serves as an immediately obvious indication that the line is >> part of a string literal, not code, and the row of |"| characters in a >> well-formatted file allows you to quickly scan up and down the file to >> see the extent of the literal. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design>>Detailed >> design >> >> When Swift is parsing a string literal and reaches the end of a line >> without finding a closing quote, it examines the next line, applying the >> following rules: >> >> 1. >> >> If the next line is all whitespace, it is ignored; Swift moves on to >> the line afterward, applying these rules again. >> >> 2. >> >> If the next line begins with whitespace followed by a continuation >> quote, then the string literal contains a newline followed by the >> contents of the string literal starting on that line. (This line may >> itself have no closing quote, in which case the same rules apply to the >> line which follows.) >> >> 3. >> >> If the next line contains anything else, Swift raises a syntax error >> for an unterminated string literal. This syntax error should offer two >> fix-its: one to close the string literal at the end of the current >> line, and one to include the next line in the string literal by >> inserting a continuation quote. >> >> Rules 1 and 2 should treat comments as though they are whitespace; this >> allows you to comment out individual lines in a multiline string literal. >> (However, commenting out the last line of the string literal will still >> make it unterminated, so you don't have a completely free hand in >> commenting.) >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code>>Impact >> on existing code >> >> Failing to close a string literal before the end of the line is currently a >> syntax error, so no valid Swift code should be affected by this change. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered>>Alternatives >> considered >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character>>Requiring >> no continuation character >> >> The main alternative is to not require a continuation quote, and simply >> extend the string literal from the starting quote to the ending quote, >> including all newlines between them. For example: >> >> let xml = "<?xml version=\"1.0\"?> >> <catalog> >> <book id=\"bk101\" empty=\"\"> >> <author>\(author)</author> >> </book> >> </catalog>" >> >> This has several advantages: >> >> 1. >> >> It is simpler. >> >> 2. >> >> It is less offensive to programmers' sensibilities (since there are no >> unmatched |"| characters). >> >> 3. >> >> It does not require that you edit the string literal to insert a >> continuation quote in each line. >> >> Balanced against the advantages, however, is the loss of the improved >> diagnostics, code formatting, and visual affordances mentioned in the >> "Benefits of continuation quotes" section above. >> >> In practice, we believe that editor support (such as "Paste as String >> Literal" or "Convert to String Literal" commands) can make adding >> continuation quotes less burdensome, while also providing other >> conveniences like automatic escaping. We believe the other two factors are >> outweighed by the benefits of continuation quotes. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings>>Use >> a different delimiter for multiline strings >> >> The initial suggestion was that multiline strings should use a different >> delimiter, |"""|, at the beginning and end of the string, with no >> continuation characters between. This solution was rejected because it has >> the same issues as the "no continuation character" solution, and because it >> was mixing two orthogonal issues (multiline strings and alternate >> delimiters). >> >> Another suggestion was to support a heredoc syntax, which would allow you >> to specify a placeholder string literal on one line whose content begins on >> the next line, running until some arbitrary delimiter. For instance, if >> Swift adopted Perl 5's syntax, it might support code like: >> >> connection.sendString(<<"END") >> <?xml version="1.0"?> >> <catalog> >> <book id="bk101" empty=""> >> <author>\(author)</author> >> </book> >> </catalog> >> END >> >> In addition to the issues with the |"""| syntax, heredocs are complicated >> both to explain and to parse, and are not a natural extension of Swift's >> current string syntax. >> >> Both of these suggestions address interesting issues with string literals, >> solving compelling use cases. They're just not that good at fixing the >> specific issue at hand. We might consider them in the future to address >> those problems to which they are better suited. >> >> >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues >> >> <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues>>Fixing >> other string literal readability issues >> >> This proposal is narrowly aimed at multiline strings. It intentionally >> doesn't tackle several other problems with string literals: >> >> * >> >> Reducing the amount of double-backslashing needed when working with >> regular expression libraries, Windows paths, source code generation, >> and other tasks where backslashes are part of the data. >> >> * >> >> Alternate delimiters or other strategies for writing strings >> with |"| characters in them. >> >> * >> >> String literals consisting of very long pieces of text which are best >> represented completely verbatim. >> >> These are likely to be subjects of future proposals, though not necessarily >> during Swift 3. >> >> This proposal also does not attempt to address regular expression literals. >> The members of the core team who are interested in regular expression >> support have ambitions for that feature which put it out of scope for Swift >> 3. >> >> -- >> Brent Royal-Gordon >> Architechies >> >> >> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution