PGN is the text import/export mapping around scid::core::Game. Decoding reads tags, comments, NAGs, SAN moves and Recursive Annotation Variations into the editable game model. Encoding walks the same model in the opposite direction, emitting tag pairs, movetext, comments, annotations, variations and the final result.
The PGN import/export mapping has two public directions. pgn::parseGame() consumes input text and mutates a Game; callers may parse into a fresh game or append movetext at a MovetextLocation. pgn::encode() serialises a Game into an appendable destination and then applies line wrapping.
Parsing is stateful because SAN moves and RAVs are relative to a current position in the game tree. The parser resolves SAN against Position, edits the movetext tree through cursor semantics, records diagnostics in ParseLog, and updates the current MovetextLocation when the location overload is used. Encoding is also position-aware: when a move has no cached SAN text, the encoder replays from the current Position and generates SAN before writing the move.
This diagram expands the PGN import/export mapping into the public API types and the domain objects they read or write. It is intentionally loose: the lexer and visitor are implementation details, while parseGame(), ParseLog, encode(), EncodeOptions, and the PGN traversal helpers are the programmer-facing surface.
ParseLog is cumulative. It records bytes, lines, game count and formatted diagnostics across parse calls, so batch importers can reuse one log while streaming multiple games. EncodeOptions is the export policy: it controls symbolic NAGs, supplemental tags, comments, variations and line width.
parseGame() writes into Game rather than returning a detached parse tree. Tags become header fields or supplemental tags; SAN tokens become MoveSpec values inserted into Movetext; comments and NAGs attach to the current move or variation. encode() reads the same structures, uses Position when SAN must be generated, and uses break_lines() to turn internal token separators into final PGN whitespace.