Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Swift) Support raw strings #2820

Closed
wants to merge 3 commits into from
Closed

(Swift) Support raw strings #2820

wants to merge 3 commits into from

Conversation

svanimpe
Copy link
Contributor

@svanimpe svanimpe commented Nov 2, 2020

Resolves #2819

Changes

Add support for raw strings with up to three leading/trailing hashes. In theory, raw strings can have any number of hashes, as long as they’re balanced, but more than one is rarely used.

Checklist

  • Added markup tests, or they don't apply here because...
  • Updated the changelog at CHANGES.md
  • Added myself to AUTHORS.txt, under Contributors

@@ -67,6 +67,9 @@ export default function(hljs) {
variants: [
{begin: /"""/, end: /"""/},
{begin: /"/, end: /"/},
{begin: /#"/, end: /"#/},
{begin: /##"/, end: /"##/},
{begin: /###"/, end: /"###/},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can such strings contain unescaped newlines?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same subst and backlash escape rules apply to raw strings as regular strings or is that different?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but you can have raw multiline strings (wrapped in #""" and """#). I also tried those and they highlight correct for me, with the rules above. Same goes for strings with interpolation or escaped characters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused what makes them "raw"... if this has no bearing on the escaping, etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, here are all the code examples in my document that use raw strings:

print(#"Use \t to insert a tab."#)

print(#"""
Use \t to insert a tab. The following example:

print("\tHello")

prints:

    Hello
"""#)

print(##"Use #" and "# to delimit a raw string."##)

print(#"""
Use \t to insert a tab. The following example:

print("\tHello")

prints:

\#tHello
"""#)

print(#"Hi \#(player), your score is: \#(score)."#)

These all highlight correctly with the new rules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes them raw is that they interpret "special characters" (such as \t) as normal character sequences (backslash and t) instead of their special meaning (tab). However, you can still use escape sequences and string interpolation by adding the same number of hashes after the backslash.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need more markup tests... sounds like there is more to be done here... at the very least we don't match normal escapes (as with every other string)... so we should have a negative test case for that... (showing that it workes properly, NOT highlighting what would be an escape)

And we should have some test cases of this new variant of escaping (and then decide whether to handle it or not)... if not then a comment in the test would explain, etc.

@joshgoebel
Copy link
Member

joshgoebel commented Nov 2, 2020

https://www.hackingwithswift.com/articles/162/how-to-use-raw-strings-in-swift

That same # symbol can now be used inside strings, to mark special characters. For example, if you want to use string interpolation, you should now use #(variableName) rather than just (variableName), like this:

I wonder if we should highlight such things?

@joshgoebel
Copy link
Member

When you use # with a string it affects the way Swift understands special characters in the string: \ no longer acts as an escape character, so \n literally means a backslash then an “n” rather than a line break

So it sounds like the contains needs to be changed for raw strings to not include escapes...

var a = not actually code
"""

print(##"Use #" and "# to delimit a raw string."##)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we handle three variants (#, ##, ###) in the language then we'd optimally want all 3 listed here in markup tests also.

@svanimpe
Copy link
Contributor Author

svanimpe commented Nov 2, 2020

I'm afraid this is about as much as I can contribute in the short term, so I'm hoping you can take that up.

I even had to install NPM specifically for this, which should tell you how familiar I am with JS codebases 😅

@svanimpe
Copy link
Contributor Author

svanimpe commented Nov 2, 2020

But even if you don't, I'm hoping this small fix can at least make it in. At the moment, raw strings are highlighted wrong. This would at least highlight them as a string, even if it's not perfect.

I also don't see any difference with normal Swift strings. They also highlight as one big hljs-string, even when they contain escapes or interpolated values. For example:

"1.\tACE\t976\n2.\tBOB\t952\n3.\tCU2\t897"

becomes:

<span class="hljs-string">"1.\tACE\t976\n2.\tBOB\t952\n3.\tCU2\t897"</span>

and

"Hi \(player), your score is: \(score)."

becomes:

<span class="hljs-string">"Hi \(player), your score is: \(score)."</span>

@joshgoebel
Copy link
Member

joshgoebel commented Nov 2, 2020

I also don't see any difference with normal Swift strings.

It's not visual (though it well could be in the future - we highlight these in some languages). Right now an extra escape would throw everything off:

#" \"#

This sting never ends because \" is an escape sequence... so your rule will never find the "# terminating sequence it's looking for, etc...

@joshgoebel
Copy link
Member

joshgoebel commented Nov 2, 2020

And you also found a bug, subst should indeed be highlighted:

Screen Shot 2020-11-02 at 3 10 42 PM

\( was being seen as an escape because the order was wrong. :-) These details matter. :)

@joshgoebel
Copy link
Member

I'm afraid this is about as much as I can contribute in the short term, so I'm hoping you can take that up.

If not I, someone else. Thanks for the effort! :)

@svanimpe
Copy link
Contributor Author

svanimpe commented Nov 2, 2020

Thanks for having Swift support in the first place 😅

@joshgoebel joshgoebel added help welcome Could use help from community WIP labels Nov 3, 2020
@joshgoebel
Copy link
Member

Closing this for now until someone has time to circle back to it and complete it fully. The issue remains open of course (with link to this PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help welcome Could use help from community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(Swift) Incorrect highlighting of raw strings
2 participants