Skip to content

Commit 4121d52

Browse files
committed
Include language to remove common indentation from multi-line strings
1 parent 3bad767 commit 4121d52

File tree

2 files changed

+77
-17
lines changed

2 files changed

+77
-17
lines changed

spec/Appendix B -- Grammar Summary.md

+3
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ EscapedUnicode :: /[0-9A-Fa-f]{4}/
8585

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

88+
Note: Multi-line string values are interpretted to exclude empty lines and
89+
uniform indentation with {MultilineStringValue()}.
90+
8891

8992
## Query Document
9093

spec/Section 2 -- Language.md

+74-17
Original file line numberDiff line numberDiff line change
@@ -715,37 +715,51 @@ Strings are sequences of characters wrapped in double-quotes (`"`). (ex.
715715
significant within a string value.
716716

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

721721
**Multi-line Strings**
722722

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

730-
**Semantics**
728+
Since multi-line strings represent freeform text often used in indented
729+
positions, the string value semantics of a multi-line string excludes uniform indentation and empty initial and trailing lines via {MultilineStringValue()}.
731730

732-
StringValue :: `"` StringCharacter* `"`
731+
For example, the following operation containing a multi-line string:
733732

734-
* Return the Unicode character sequence of all {StringCharacter}
735-
Unicode character values (which may be empty).
733+
```graphql
734+
mutation {
735+
sendEmail(message: """
736+
Hello,
737+
World!
736738
737-
StringValue :: `"""` MultiLineStringCharacter* `"""`
739+
Yours,
740+
GraphQL.
741+
""")
742+
}
743+
```
738744

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

742-
MultiLineStringCharacter :: SourceCharacter but not `"""` or `\"""`
747+
```graphql
748+
mutation {
749+
sendEmail(message: "Hello,\n World!\n\nYours,\n GraphQL.")
750+
}
751+
```
743752

744-
* Return the character value of {SourceCharacter}.
753+
Note: If non-printable ASCII characters are needed in a string value, a standard
754+
quoted string with appropriate escape sequences must be used instead of a
755+
multi-line string.
745756

746-
MultiLineStringCharacter :: `\"""`
757+
**Semantics**
747758

748-
* Return the character sequence `"""`.
759+
StringValue :: `"` StringCharacter* `"`
760+
761+
* Return the Unicode character sequence of all {StringCharacter}
762+
Unicode character values (which may be empty).
749763

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

@@ -771,6 +785,49 @@ StringCharacter :: \ EscapedCharacter
771785
| `r` | U+000D | carriage return |
772786
| `t` | U+0009 | horizontal tab |
773787

788+
StringValue :: `"""` MultiLineStringCharacter* `"""`
789+
790+
* Let {rawValue} be the Unicode character sequence of all
791+
{MultiLineStringCharacter} Unicode character values (which may be empty).
792+
* Return the result of {MultilineStringValue(rawValue)}.
793+
794+
MultiLineStringCharacter :: SourceCharacter but not `"""` or `\"""`
795+
796+
* Return the character value of {SourceCharacter}.
797+
798+
MultiLineStringCharacter :: `\"""`
799+
800+
* Return the character sequence `"""`.
801+
802+
MultilineStringValue(rawValue):
803+
804+
* Let {lines} be the result of splitting {rawValue} by {LineTerminator}.
805+
* Let {minIndent} be {null}.
806+
* For each {line} in {lines}:
807+
* If {line} is the first item in {lines}, continue to the next line.
808+
* Let {length} be the number of characters in {line}.
809+
* Let {indent} be the number of leading consecutive {WhiteSpace} characters
810+
in {line}.
811+
* If {indent} is less than {length}:
812+
* If {indent} is less than {minIndent} or {minIndent} is {null}:
813+
* Let {minIndent} be {indent}.
814+
* If {minIndent} is not {null}:
815+
* For each {line} in {lines}:
816+
* If {line} is the first item in {lines}, continue to the next line.
817+
* Remove {minIndent} characters from the beginning of {line}.
818+
* While the first {line} in {lines} contains no characters:
819+
* Remove the first {line} from {lines}.
820+
* While the last {line} in {lines} contains no characters:
821+
* Remove the last {line} from {lines}.
822+
* Let {formatted} be the empty character sequence.
823+
* For each {line} in {lines}:
824+
* If {line} is the first item in {lines}:
825+
* Append {formatted} with {line}.
826+
* Otherwise:
827+
* Append {formatted} with a line feed character (U+000A).
828+
* Append {formatted} with {line}.
829+
* Return {formatted}.
830+
774831

775832
### Null Value
776833

0 commit comments

Comments
 (0)