Practical guide
SGF Comment Escaping: Brackets, Backslashes and Line Breaks
Inside an SGF comment, escape a literal closing bracket as \] and a literal backslash as \\. A backslash before an actual line break removes that break. These rules concern the SGF value, even when the file’s character encoding is already correct.
Find where the comment value ends
An SGF property has an identifier followed by bracketed values. In C[Short note], the first unescaped closing bracket terminates the comment. A bracket that belongs to the note must therefore be escaped. An extra closing bracket is not ordinary prose punctuation to an SGF reader.
The FF4 specification defines C as Text and explains how escaping is processed. A correctly declared UTF-8 file can still have a broken comment value: character decoding and SGF value boundaries are separate checks. [1] [2]
Preserve the original file, then test the smallest comment containing the problem. Do not search-and-replace every bracket in the record; the brackets around property values are structural and must remain.
Write the raw escapes that preserve two literal characters
(;FF[4]GM[1]SZ[9]CA[UTF-8]C[Literal \] bracket; literal \\ backslash.])The decoded comment is Literal ] bracket; literal \ backslash. The backslash before ] prevents it from closing the value. The doubled backslash preserves one literal backslash. Compare the raw SGF file with the displayed comment rather than expecting their character counts to match.
Download the valid bracket-and-backslash example. Keep your own record unchanged; these are original teaching examples.
A semicolon inside this C value is comment text, not a new node. Ordinary parentheses and an opening bracket also do not need the same closing-delimiter escape within a Text value. Escape exactly for the SGF type and boundary, rather than adding backslashes before all punctuation.
FF4 also explains colon escaping for composed values. A plain colon in C text does not by itself form a composed value. A label such as LB has its own point-and-text boundary, covered in the marks and labels guide. [1]
Two failures can look like lost text
On a narrow screen, scroll the comparison sideways. Keyboard users can focus the table and use the arrow keys.
| Raw comment fragment | Outcome | Reason |
|---|---|---|
| C[folder\notes] | foldernotes | The backslash escapes the next character; it is removed |
| C[folder\\notes] | folder\notes | Two raw backslashes preserve one literal backslash |
| A literal ] without an escape | Value ends too early; following text can break the grammar | The delimiter is interpreted structurally |
The intentionally single-backslash sample is grammatically readable, but its comment becomes foldernotes. A parser that opens it has not proved that the intended path was preserved. The unescaped-bracket sample is intentionally malformed and is rejected by the grammar parser used for these examples.
Deliberately faulty diagnostic file: Download the valid grammar with an intentionally lost backslash. Keep your own record unchanged; these are original teaching examples.
Deliberately faulty diagnostic file: Download the intentionally malformed closing-bracket sample. Keep your own record unchanged; these are original teaching examples.
These are teaching failures, not recovered user records. Avoid uploading them as though they were valid game histories. A tolerant viewer might report or handle malformed text differently; no specific viewer behavior is claimed here.
A hard line break and an escaped line break differ
C is Text, so a hard line break can remain a line break after normalization. In the first sample below there is an actual newline between first and second. The decoded result has those two lines. [1]
C[first
second]Download the comment with a hard line break. Keep your own record unchanged; these are original teaching examples.
In the next sample, a backslash immediately precedes the actual newline. That escape removes the line break, giving the single word wonderful. It does not insert a space.
C[wonder\
ful]Download the comment with an escaped soft line break. Keep your own record unchanged; these are original teaching examples.
Typing the two visible characters backslash and n is not the same as inserting a newline. SGF escaping is not a promise that programming-language sequences such as \n become a line break. In a Text value, the escape removes the backslash and retains the following ordinary character.
SimpleText has different whitespace normalization: hard line breaks become spaces, while escaped line breaks are removed. Labels use SimpleText, so a comment and a label cannot be assumed to display multiline text in the same way. [1]
Avoid escaping a value twice
- Locate the C value in a preserved copy and identify the intended plain comment.
- If working directly in raw SGF, escape each intended literal backslash and each literal closing bracket. Preserve the brackets that delimit the property.
- If using an SGF editor’s comment field, enter the intended plain text and let its serializer handle SGF escaping. Do not assume the field expects raw SGF.
- Save a separate copy and inspect both the raw value and its decoded text. Check that line breaks and punctuation survived.
- Confirm that the surrounding nodes, properties and branches are unchanged before replacing a distributed teaching file.
A comment field that already serializes backslashes can double-escape manually prepared input. Conversely, pasting plain prose into a raw file leaves delimiter characters unprotected. Decide which level you are editing before applying the rule.
Two complete comment checks
My comment says “look at ] here,” and the record stops opening after I add it. What should I inspect?
Inspect that literal closing bracket inside C, in a copy of the original.
In raw SGF it needs a preceding escape so it stays inside the value. Retain the final unescaped bracket that closes C. Compare the repaired record with the valid downloadable example, then confirm that the rest of the tree still parses. A broken record elsewhere needs a separate diagnosis.
The file opens, but folder\notes displays as foldernotes. Is CA the first thing to change?
Check the raw backslash count first.
A single raw backslash escapes n and disappears, producing the observed text loss. To retain one literal backslash, the raw value needs two. Encoding changes do not supply that missing SGF escape. If a decoded editor field handles serialization, enter the plain intended path there and verify its saved output.
Check the text and the tree
All five downloadable examples were compared with sgfmill 1.1.1: four have readable grammar, while the unescaped-bracket example has the intended grammar failure. The literal comment, foldernotes result and two line-break outcomes were checked separately. These checks do not establish Go move legality or viewer compatibility.
For garbled Chinese or accented characters, continue with CA and file bytes. For comments accompanying setup diagrams, keep the complete stone list and the explanatory words separate. A correct comment cannot supply stones absent from the record.
Sources and further reading
- SGF FF4: file format specificationText escaping, property scope and compressed point-list rules.
- SGF FF4: C propertyComments use the Text value type.