The .synctex.gz format¶
This page describes the SyncTeX stream go-synctex/synctex consumes — enough to
understand what the parser reads and what it ignores. The authoritative reference
is Jérôme Laurens' SyncTeX documentation and the synctex_parser sources
shipped with TeX Live1; this page is scoped to the subset the parser
actually acts on.
What the engine writes¶
When you compile with SyncTeX enabled (pdflatex -synctex=1 main.tex, the
default in most editors), the TeX engine writes main.synctex.gz next to the
PDF. It is a gzip-compressed, line-oriented text file recording, box by box,
which source line produced which point on which page. A plain (uncompressed)
main.synctex is the same content without the gzip wrapper — Parse handles
both, selecting decompression on the .gz suffix.
Overall shape¶
SyncTeX Version:1
Input:1:/srv/build/thesis/main.tex
Input:2:/srv/build/thesis/chapter1.tex
Magnification:1000
Unit:1
X Offset:0
Y Offset:0
Content:
{1
[1,23:4736286,42152922:...
h 1,23:4736286,42152922:...
x 1,25:4736286,40000000:...
}
{2
[2,7:4736286,42152922:...
}
Postamble:
...
The preamble¶
Before Content:, the file carries header lines. The parser cares about exactly
two of them:
Input:N:/path/to/file.tex— declares that file tagNrefers to the given source path. Every record later refers to a source file by this integer tag; the parser builds the tag → path map from these lines. UnderWithProjectRoota path outside the root is dropped and a path inside is rewritten relative-to-root.Content:— marks the end of the preamble; everything after it is the body of page blocks and records.
The remaining header lines — SyncTeX Version:, Magnification:,
Unit:, X Offset:, Y Offset: — are part of the format but are
not interpreted by this parser: it works directly in scaled points and does
not apply magnification or offset transforms. Callers that need those transforms
apply them at the boundary.
The content body¶
After Content:, the stream is a sequence of page blocks holding record
lines:
{P— opens the block for pageP(1-based). Records that follow belong to this page until it closes.}— closes the current page block.Postamble:— ends the content; the parser stops here.
Record lines¶
Inside a page block, each line begins with a single-character node type followed by the node's tag, line, and coordinate. The parser recognises these leading characters as line-pinning records:
| Leading | Node | Form |
|---|---|---|
[ |
box open (hbox/vbox open) | [N,L:X,Y:W,H,D |
h |
horizontal box | h N,L:X,Y:W,H,D |
v |
vertical box | v N,L:X,Y:W,H,D |
k |
kern | k N,L:X,Y:... |
g |
glue | g N,L:X,Y:... |
x |
rule | x N,L:X,Y:... |
The [ node's fields follow immediately; the h, v, k, g, x nodes carry
a single space before their fields (h 1,23:...). Any other leading character
(for example the box-close ], or void nodes the parser doesn't model) is
skipped.
The N,L:X,Y prefix¶
Every record's payload starts with the same prefix, and that prefix is all the parser needs:
N , L : X , Y : W , H , D
│ │ │ │ └── further box dimensions (width, height, depth) — ignored
│ │ │ └────── Y coordinate, in scaled points (sp)
│ │ └────────── X coordinate, in scaled points (sp)
│ └────────────── source line (1-based)
└────────────────── file tag N — indexes into the Input: map
The parser reads N, L, X, and Y, stopping at the second : (or a comma):
the trailing W,H,D box dimensions — width, height, depth — are not
parsed, because the forward/backward queries only need the anchor coordinate, not
the box extent. Each successfully parsed prefix becomes a
Record {FileTag: N, Line: L, Page: P, X, Y}.
A malformed record line — a missing comma, a non-numeric field — is skipped, not fatal: the parser keeps scanning so one bad line never aborts the whole file.
What the parser produces¶
From this stream the parser builds:
Inputs— the tag → source-path map from theInput:lines;Records— oneRecordper parsed line-pinning node, in stream order;- an internal per-source line index, sorted by line, so
Forwardcan binary-search the nearest line.
See Usage & API for how to query the result.
-
Jérôme Laurens, SyncTeX: introduction to the engine, and the reference
synctex_parser.c/synctex_parser.hin TeX Live. See also https://www.tug.org/TUGboat/tb29-3/tb93laurens.pdf. ↩