Skip to content

Commit 979a1f2

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

File tree

2 files changed

+91
-29
lines changed

2 files changed

+91
-29
lines changed

spec/Appendix B -- Grammar Summary.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,24 @@ Sign :: one of + -
7070

7171
StringValue ::
7272
- `"` StringCharacter* `"`
73-
- `"""` MultiLineStringCharacter* `"""`
73+
- `"""` BlockStringCharacter* `"""`
7474

7575
StringCharacter ::
7676
- SourceCharacter but not `"` or \ or LineTerminator
7777
- \u EscapedUnicode
7878
- \ EscapedCharacter
7979

80-
MultiLineStringCharacter ::
81-
- SourceCharacter but not `"""` or `\"""`
82-
- `\"""`
83-
8480
EscapedUnicode :: /[0-9A-Fa-f]{4}/
8581

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

84+
BlockStringCharacter ::
85+
- SourceCharacter but not `"""` or `\"""`
86+
- `\"""`
87+
88+
Note: Block string values are interpretted to exclude blank initial and trailing
89+
lines and uniform indentation with {BlockStringValue()}.
90+
8891

8992
## Query Document
9093

spec/Section 2 -- Language.md

+83-24
Original file line numberDiff line numberDiff line change
@@ -695,57 +695,72 @@ The two keywords `true` and `false` represent the two boolean values.
695695

696696
StringValue ::
697697
- `"` StringCharacter* `"`
698-
- `"""` MultiLineStringCharacter* `"""`
698+
- `"""` BlockStringCharacter* `"""`
699699

700700
StringCharacter ::
701701
- SourceCharacter but not `"` or \ or LineTerminator
702702
- \u EscapedUnicode
703703
- \ EscapedCharacter
704704

705-
MultiLineStringCharacter ::
706-
- SourceCharacter but not `"""` or `\"""`
707-
- `\"""`
708-
709705
EscapedUnicode :: /[0-9A-Fa-f]{4}/
710706

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

709+
BlockStringCharacter ::
710+
- SourceCharacter but not `"""` or `\"""`
711+
- `\"""`
712+
713713
Strings are sequences of characters wrapped in double-quotes (`"`). (ex.
714714
`"Hello World"`). White space and other otherwise-ignored characters are
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

721-
**Multi-line Strings**
721+
**Block Strings**
722722

723-
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.
723+
Block strings are sequences of characters wrapped in triple-quotes (`"""`).
724+
White space, line terminators, quote, and backslash characters may all be
725+
used unescaped to enable verbatim text. Characters must all be valid
726+
{SourceCharacter}.
729727

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

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

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

739-
* Return the Unicode character sequence of all {MultiLineStringCharacter}
740-
Unicode character values (which may be empty).
746+
Is identical to the standard quoted string:
747+
748+
```graphql
749+
mutation {
750+
sendEmail(message: "Hello,\n World!\n\nYours,\n GraphQL.")
751+
}
752+
```
741753

742-
MultiLineStringCharacter :: SourceCharacter but not `"""` or `\"""`
754+
Note: If non-printable ASCII characters are needed in a string value, a standard
755+
quoted string with appropriate escape sequences must be used instead of a
756+
block string.
743757

744-
* Return the character value of {SourceCharacter}.
758+
**Semantics**
745759

746-
MultiLineStringCharacter :: `\"""`
760+
StringValue :: `"` StringCharacter* `"`
747761

748-
* Return the character sequence `"""`.
762+
* Return the Unicode character sequence of all {StringCharacter}
763+
Unicode character values (which may be an empty sequence).
749764

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

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

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

775834
### Null Value
776835

0 commit comments

Comments
 (0)