Skip to content

Commit

Permalink
Include language to remove common indentation from multi-line strings
Browse files Browse the repository at this point in the history
  • Loading branch information
leebyron committed Nov 30, 2017
1 parent 3bad767 commit 17db7e9
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 23 deletions.
7 changes: 5 additions & 2 deletions spec/Appendix B -- Grammar Summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,24 @@ Sign :: one of + -

StringValue ::
- `"` StringCharacter* `"`
- `"""` MultiLineStringCharacter* `"""`
- `"""` BlockStringCharacter* `"""`

StringCharacter ::
- SourceCharacter but not `"` or \ or LineTerminator
- \u EscapedUnicode
- \ EscapedCharacter

MultiLineStringCharacter ::
BlockStringCharacter ::
- SourceCharacter but not `"""` or `\"""`
- `\"""`

EscapedUnicode :: /[0-9A-Fa-f]{4}/

EscapedCharacter :: one of `"` \ `/` b f n r t

Note: Block string values are interpretted to exclude blank initial and trailing
lines and uniform indentation with {BlockStringValue()}.


## Query Document

Expand Down
101 changes: 80 additions & 21 deletions spec/Section 2 -- Language.md
Original file line number Diff line number Diff line change
Expand Up @@ -695,14 +695,14 @@ The two keywords `true` and `false` represent the two boolean values.

StringValue ::
- `"` StringCharacter* `"`
- `"""` MultiLineStringCharacter* `"""`
- `"""` BlockStringCharacter* `"""`

StringCharacter ::
- SourceCharacter but not `"` or \ or LineTerminator
- \u EscapedUnicode
- \ EscapedCharacter

MultiLineStringCharacter ::
BlockStringCharacter ::
- SourceCharacter but not `"""` or `\"""`
- `\"""`

Expand All @@ -715,37 +715,52 @@ Strings are sequences of characters wrapped in double-quotes (`"`). (ex.
significant within a string value.

Note: Unicode characters are allowed within String value literals, however
GraphQL source must not contain some ASCII control characters so escape
{SourceCharacter} must not contain some ASCII control characters so escape
sequences must be used to represent these characters.

**Multi-line Strings**
**Block Strings**

Multi-line strings are sequences of characters wrapped in triple-quotes (`"""`).
White space, line terminators, and quote and backslash characters may all be
used unescaped, enabling freeform text. Characters must all be valid
{SourceCharacter} to ensure printable source text. If non-printable ASCII
characters need to be used, escape sequences must be used within standard
double-quote strings.
Block strings are sequences of characters wrapped in triple-quotes (`"""`).
White space, line terminators, quote, and backslash characters may all be
used unescaped to enable verbatim text. Characters must all be valid
{SourceCharacter}.

**Semantics**
Since block strings represent freeform text often used in indented
positions, the string value semantics of a block string excludes uniform
indentation and blank initial and trailing lines via {BlockStringValue()}.

StringValue :: `"` StringCharacter* `"`
For example, the following operation containing a block string:

* Return the Unicode character sequence of all {StringCharacter}
Unicode character values (which may be empty).
```graphql
mutation {
sendEmail(message: """
Hello,
World!
StringValue :: `"""` MultiLineStringCharacter* `"""`
Yours,
GraphQL.
""")
}
```

* Return the Unicode character sequence of all {MultiLineStringCharacter}
Unicode character values (which may be empty).
Is identical to the standard quoted string:

MultiLineStringCharacter :: SourceCharacter but not `"""` or `\"""`
```graphql
mutation {
sendEmail(message: "Hello,\n World!\n\nYours,\n GraphQL.")
}
```

* Return the character value of {SourceCharacter}.
Note: If non-printable ASCII characters are needed in a string value, a standard
quoted string with appropriate escape sequences must be used instead of a
block string.

MultiLineStringCharacter :: `\"""`
**Semantics**

* Return the character sequence `"""`.
StringValue :: `"` StringCharacter* `"`

* Return the Unicode character sequence of all {StringCharacter}
Unicode character values (which may be an empty sequence).

StringCharacter :: SourceCharacter but not `"` or \ or LineTerminator

Expand All @@ -771,6 +786,50 @@ StringCharacter :: \ EscapedCharacter
| `r` | U+000D | carriage return |
| `t` | U+0009 | horizontal tab |

StringValue :: `"""` BlockStringCharacter* `"""`

* Let {rawValue} be the Unicode character sequence of all
{BlockStringCharacter} Unicode character values (which may be an empty
sequence).
* Return the result of {BlockStringValue(rawValue)}.

BlockStringCharacter :: SourceCharacter but not `"""` or `\"""`

* Return the character value of {SourceCharacter}.

BlockStringCharacter :: `\"""`

* Return the character sequence `"""`.

BlockStringValue(rawValue):

* Let {lines} be the result of splitting {rawValue} by {LineTerminator}.
* Let {commonIndent} be {null}.
* For each {line} in {lines}:
* If {line} is the first item in {lines}, continue to the next line.
* Let {length} be the number of characters in {line}.
* Let {indent} be the number of leading consecutive {WhiteSpace} characters
in {line}.
* If {indent} is less than {length}:
* If {commonIndent} is {null} or {indent} is less than {commonIndent}:
* Let {commonIndent} be {indent}.
* If {commonIndent} is not {null}:
* For each {line} in {lines}:
* If {line} is the first item in {lines}, continue to the next line.
* Remove {commonIndent} characters from the beginning of {line}.
* While the first item {line} in {lines} contains only {WhiteSpace}:
* Remove the first item from {lines}.
* While the last item {line} in {lines} contains only {WhiteSpace}:
* Remove the last item from {lines}.
* Let {formatted} be the empty character sequence.
* For each {line} in {lines}:
* If {line} is the first item in {lines}:
* Append {formatted} with {line}.
* Otherwise:
* Append {formatted} with a line feed character (U+000A).
* Append {formatted} with {line}.
* Return {formatted}.


### Null Value

Expand Down

0 comments on commit 17db7e9

Please sign in to comment.