[{"data":1,"prerenderedAt":31},["ShallowReactive",2],{"i-lucide:grip":3,"i-lucide:chevron-right":8,"i-lucide:moon":10,"i-lucide:sun":12,"i-lucide:languages":14,"i-lucide:chevron-down":16,"i-lucide:shield-check":18,"i-lucide:mail":20,"blog-body-latex-rerun-cross-references-en":22,"i-lucide:lightbulb":23,"i-lucide:graduation-cap":25,"i-lucide:pen-line":27,"i-lucide:star":29},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"5\" r=\"1\"\u002F>\u003Ccircle cx=\"19\" cy=\"5\" r=\"1\"\u002F>\u003Ccircle cx=\"5\" cy=\"5\" r=\"1\"\u002F>\u003Ccircle cx=\"12\" cy=\"12\" r=\"1\"\u002F>\u003Ccircle cx=\"19\" cy=\"12\" r=\"1\"\u002F>\u003Ccircle cx=\"5\" cy=\"12\" r=\"1\"\u002F>\u003Ccircle cx=\"12\" cy=\"19\" r=\"1\"\u002F>\u003Ccircle cx=\"19\" cy=\"19\" r=\"1\"\u002F>\u003Ccircle cx=\"5\" cy=\"19\" r=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m5 8l6 6m-7 0l6-6l2-3M2 5h12M7 2h1m14 20l-5-10l-5 10m2-4h6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\"\u002F>\u003Cpath d=\"m9 12l2 2l4-4\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>","\u003Cblockquote>\n\u003Cp>The \u003Ccode>??\u003C\u002Fcode> in your PDF and the table of contents that's off by a page are almost never a syntax mistake. They mean the document \u003Cstrong>hasn't been compiled enough times\u003C\u002Fstrong>. LaTeX needs the auxiliary files left behind by the previous run to work out the right numbers, so a single pass is always missing half the information.\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Cp>\u003Cimg src=\"\u002Fblog\u002Flatex-rerun-cross-references\u002Fcover.webp\" alt=\"The first pass leaves an auxiliary file behind; only the second pass can turn ?? into the right number\">\u003C\u002Fp>\n\u003Ch2>Why does \\ref print ??\u003C\u002Fh2>\n\u003Cp>Because the label doesn't exist yet on the first pass. LaTeX processes a document in \u003Cstrong>one forward sweep\u003C\u002Fstrong>: when it hits \u003Ccode>\\ref{fig:result}\u003C\u002Fcode> on page 3, the \u003Ccode>\\label{fig:result}\u003C\u002Fcode> on page 12 hasn't been read, so there is no way to know which figure that will be or where it lands. LaTeX prints \u003Ccode>??\u003C\u002Fcode> as a placeholder and writes everything it learned along the way into an \u003Ccode>.aux\u003C\u002Fcode> file.\u003C\u002Fp>\n\u003Cp>On the second pass that \u003Ccode>.aux\u003C\u002Fcode> file is already on disk. LaTeX reads it up front, so every \u003Ccode>\\ref\u003C\u002Fcode> becomes a simple lookup. This &quot;record now, look up next time&quot; cycle is the key to every multi-pass problem in LaTeX.\u003C\u002Fp>\n\u003Cp>The same mechanism drives \u003Ccode>\\pageref\u003C\u002Fcode> page numbers, \u003Ccode>\\cite\u003C\u002Fcode> citation numbers, \u003Ccode>\\tableofcontents\u003C\u002Fcode> (stored in \u003Ccode>.toc\u003C\u002Fcode>), lists of figures and tables (\u003Ccode>.lof\u003C\u002Fcode> \u002F \u003Ccode>.lot\u003C\u002Fcode>), and the PDF bookmarks hyperref generates (\u003Ccode>.out\u003C\u002Fcode>). What they share: \u003Cstrong>the answer is only known after the whole document has been processed, yet it must be printed somewhere in the middle.\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Ch2>Why is the table of contents off by a page\u003C\u002Fh2>\n\u003Cp>Because the contents page takes up space itself. Say the body is 30 pages; the second pass inserts a one-page table of contents and pushes everything after it down by one. But the page numbers printed \u003Cem>in\u003C\u002Fem> that contents were computed on the first pass, before it existed — so every entry is off by one. A third pass typesets the contents again with correct numbers.\u003C\u002Fp>\n\u003Cp>The pathological case is \u003Cstrong>oscillation\u003C\u002Fstrong>: a section heading sits exactly on a page boundary, so one extra contents line pushes it to the next page; the next pass the line disappears and it moves back. Such a document may never converge and needs a manual nudge, such as a bit of flexible spacing at the trouble spot. It's rare, but it exists.\u003C\u002Fp>\n\u003Ch2>So how many passes do you need\u003C\u002Fh2>\n\u003Cp>It depends on what the document uses. Minimum passes for common combinations:\u003C\u002Fp>\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>What the document contains\u003C\u002Fth>\n\u003Cth>Minimum passes\u003C\u002Fth>\n\u003Cth>Why\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Body text only, no refs or contents\u003C\u002Ftd>\n\u003Ctd>1\u003C\u002Ftd>\n\u003Ctd>Nothing has to be filled in retroactively\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\\ref\u003C\u002Fcode> \u002F \u003Ccode>\\pageref\u003C\u002Fcode> cross-references\u003C\u002Ftd>\n\u003Ctd>2\u003C\u002Ftd>\n\u003Ctd>First writes .aux, second reads it\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\\tableofcontents\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>2–3\u003C\u002Ftd>\n\u003Ctd>The contents shifts page numbers and may need to settle\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>\\cite\u003C\u002Fcode> with BibTeX\u003C\u002Ftd>\n\u003Ctd>4 steps (see below)\u003C\u002Ftd>\n\u003Ctd>A BibTeX run goes in the middle\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>hyperref bookmarks\u003C\u002Ftd>\n\u003Ctd>+1\u003C\u002Ftd>\n\u003Ctd>A changed \u003Ccode>.out\u003C\u002Fcode> triggers a rerunfilecheck warning\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>That column is the \u003Cem>minimum\u003C\u002Fem>. Running an extra pass is harmless — once the document has converged the output is byte-identical — while running one too few leaves \u003Ccode>??\u003C\u002Fcode> behind. Hence the traditional advice to just run it three times.\u003C\u002Fp>\n\u003Ch2>Why a bibliography takes four steps\u003C\u002Fh2>\n\u003Cp>Because BibTeX is a separate program that has to sit between two LaTeX runs. The full sequence is \u003Ccode>xelatex → bibtex → xelatex → xelatex\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>First xelatex\u003C\u002Fstrong>: records the keys used by \u003Ccode>\\cite{knuth1984}\u003C\u002Fcode> into \u003Ccode>.aux\u003C\u002Fcode>. No bibliography exists yet.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>bibtex\u003C\u002Fstrong>: reads those keys from \u003Ccode>.aux\u003C\u002Fcode>, looks them up in your \u003Ccode>.bib\u003C\u002Fcode>, formats them according to \u003Ccode>\\bibliographystyle\u003C\u002Fcode>, and writes a \u003Ccode>.bbl\u003C\u002Fcode> file.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Second xelatex\u003C\u002Fstrong>: pulls \u003Ccode>.bbl\u003C\u002Fcode> in at the end of the document, so the reference list appears, and writes &quot;which entry is number what&quot; into \u003Ccode>.aux\u003C\u002Fcode> — but the \u003Ccode>\\cite\u003C\u002Fcode> commands in the body read the \u003Cem>previous\u003C\u002Fem> \u003Ccode>.aux\u003C\u002Fcode> during this same pass, so they still show \u003Ccode>[?]\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Third xelatex\u003C\u002Fstrong>: the numbers are in \u003Ccode>.aux\u003C\u002Fcode> now, so \u003Ccode>[?]\u003C\u002Fcode> finally becomes \u003Ccode>[1]\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>Plenty of people stop at step three: the bibliography is visible, so it looks finished, yet the body is full of \u003Ccode>[?]\u003C\u002Fcode>. One more pass fixes it.\u003C\u002Fp>\n\u003Cp>With biblatex the middle command changes — you run \u003Ccode>biber\u003C\u002Fcode> instead of \u003Ccode>bibtex\u003C\u002Fcode> — but the pass logic is identical.\u003C\u002Fp>\n\u003Ch2>Reading the log to know you're done\u003C\u002Fh2>\n\u003Cp>Search the log for rerun notices. When LaTeX or a package detects that this pass disagrees with the last one, it says so explicitly. These are the messages you'll see verbatim:\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark mac-code-block\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Cspan class=\"mac-lang-badge\">text\u003C\u002Fspan>\u003Ccode class=\"language-text\">\u003Cspan class=\"line\">\u003Cspan>LaTeX Warning: There were undefined references.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>LaTeX Warning: Label(s) may have changed. Rerun to get cross-references right.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>Package rerunfilecheck Warning: File `main.out' has changed.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>(rerunfilecheck)                Rerun to get outlines right\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>Package hyperref Warning: Rerun to get \u002FPageLabels entry.\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>While any of those are present, \u003Cstrong>run it again\u003C\u002Fstrong>. Convergence looks like their absence, plus rerunfilecheck switching to an Info line:\u003C\u002Fp>\n\u003Cpre class=\"shiki shiki-themes github-light github-dark mac-code-block\" style=\"background-color:#fff;--shiki-dark-bg:#24292e;color:#24292e;--shiki-dark:#e1e4e8\" tabindex=\"0\">\u003Cspan class=\"mac-lang-badge\">text\u003C\u002Fspan>\u003Ccode class=\"language-text\">\u003Cspan class=\"line\">\u003Cspan>Package rerunfilecheck Info: File `main.out' has not changed.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan>(rerunfilecheck)             Checksum: 53F1C61ABCC06CF9FD3B6F1940CE0C3D;330.\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>That checksum is how rerunfilecheck decides: it stores the MD5 of the previous \u003Ccode>.out\u003C\u002Fcode>, recomputes it, and compares. Deciding whether the table of contents has settled works the same way — compare the \u003Ccode>.toc\u003C\u002Fcode> written this pass against the one from last pass, byte for byte.\u003C\u002Fp>\n\u003Cp>You don't have to count passes by hand. Locally, \u003Ccode>latexmk -xelatex main.tex\u003C\u002Fcode> loops until no rerun signal remains, with an internal cap so an oscillating document can't spin forever. The default recipe in VS Code's LaTeX Workshop is latexmk for exactly this reason.\u003C\u002Fp>\n\u003Cp>The same logic applies in the browser: the advanced mode of the \u003Ca href=\"\u002Flatex\u002Fedit\u002F\">online LaTeX editor\u003C\u002Fa> runs a WebAssembly build of XeLaTeX that scans the log for those signals after each pass and compares \u003Ccode>.toc\u003C\u002Fcode> \u002F \u003Ccode>.lof\u003C\u002Fcode> \u002F \u003Ccode>.lot\u003C\u002Fcode> between passes, running as many as the document needs without you clicking compile a second time.\u003C\u002Fp>\n\u003Ch2>When to delete .aux and start over\u003C\u002Fh2>\n\u003Cp>After renaming a label or switching document classes. \u003Ccode>.aux\u003C\u002Fcode> is a cache, and caches go stale: if you change \u003Ccode>\\label{fig:old}\u003C\u002Fcode> to \u003Ccode>\\label{fig:new}\u003C\u002Fcode>, the old \u003Ccode>fig:old\u003C\u002Fcode> entry is still sitting in \u003Ccode>.aux\u003C\u002Fcode> and can mask a genuine error, leaving you convinced the reference still works.\u003C\u002Fp>\n\u003Cp>Likewise, switching document class — from \u003Ccode>article\u003C\u002Fcode> to a journal template, say — can leave counter definitions in the old \u003Ccode>.aux\u003C\u002Fcode> that don't match the new class, producing errors that make no sense against your source. Whenever you hit &quot;the code looks fine but the error is nonsense,&quot; deleting \u003Ccode>.aux\u003C\u002Fcode>, \u003Ccode>.toc\u003C\u002Fcode>, \u003Ccode>.out\u003C\u002Fcode>, and \u003Ccode>.bbl\u003C\u002Fcode> before recompiling is the highest-yield thing to try.\u003C\u002Fp>\n\u003Ch2>Summary\u003C\u002Fh2>\n\u003Cp>\u003Ccode>??\u003C\u002Fcode> isn't an error; it's LaTeX telling you it doesn't know that number yet. Three things are enough to remember: cross-references and tables of contents need at least two passes, a bibliography needs four steps, and the log tells you whether to keep going by whether \u003Ccode>Rerun to get\u003C\u002Fcode> still appears. Automate it with latexmk locally, and clear the intermediate files first whenever an error looks absurd — between them, that covers nearly every &quot;the output looks wrong&quot; situation.\u003C\u002Fp>\n",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":24},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 14c.2-1 .7-1.7 1.5-2.5c1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5c.7.7 1.3 1.5 1.5 2.5m0 4h6m-5 4h4\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":26},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M21.42 10.922a1 1 0 0 0-.019-1.838L12.83 5.18a2 2 0 0 0-1.66 0L2.6 9.08a1 1 0 0 0 0 1.832l8.57 3.908a2 2 0 0 0 1.66 0zM22 10v6\"\u002F>\u003Cpath d=\"M6 12.5V16a6 3 0 0 0 12 0v-3.5\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":28},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 21h8m.174-14.188a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":30},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.12 2.12 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.12 2.12 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.12 2.12 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.12 2.12 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.12 2.12 0 0 0 1.597-1.16z\"\u002F>",1786455162146]