Academic PDF → GitHub GFM Conversion A battle-tested workflow for converting academic/research PDF papers into GitHub-renderable GFM markdown with inline figures, mathematically correct LaTeX, and validated output. Battle-tested on : López de Prado (2026) "How to Use the Sharpe Ratio" — 51 pages, 82 equations, 8 figures. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Quick Start (3 Steps) --- CRITICAL: Detect PDF Type First This…

+ cleaned + '

Academic PDF → GitHub GFM Conversion A battle-tested workflow for converting academic/research PDF papers into GitHub-renderable GFM markdown with inline figures, mathematically correct LaTeX, and validated output. Battle-tested on : López de Prado (2026) "How to Use the Sharpe Ratio" — 51 pages, 82 equations, 8 figures. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Quick Start (3 Steps) --- CRITICAL: Detect PDF Type First This…

; }\n return match;\n });\n\n // Fix E1: Convert standalone $ blocks containing \\\\ to ```math blocks\n fixed = fixed.replace(/\\n\\$\\$\\n([\\s\\S]+?)\\n\\$\\$\\n/g, (match, inner) => {\n if (!inner.includes('\\\\\\\\')) return match;\n fixCount++;\n return '\\n```math\\n' + inner + '\\n```\\n';\n });\n\n // Fix E2: Add blank line between consecutive $ blocks\n // Pattern: closing \\n$\\n immediately followed by opening $\\n\n const beforeE2 = fixed;\n fixed = fixed.replace(/\\n\\$\\$\\n(\\$\\$\\n)/g, '\\n$\\n\\n$1');\n if (fixed !== beforeE2) {\n const n = (beforeE2.match(/\\n\\$\\$\\n\\$\\$\\n/g) || []).length;\n fixCount += n;\n }\n\n // Fix W1: Replace bare ^* with ^{\\ast} in $ display blocks\n fixed = fixed.replace(/(\\n\\$\\$\\n[\\s\\S]+?\\n\\$\\$\\n)/g, (block) => {\n const r = block.replace(/\\^\\*(?!\\{)/g, '^{\\\\ast}');\n if (r !== block) fixCount++;\n return r;\n });\n // And in inline $ blocks\n fixed = fixed.replace(/\\$([^\\$\\n]+?)\\$/g, (match, inner) => {\n const r = inner.replace(/\\^\\*(?!\\{)/g, '^{\\\\ast}');\n if (r !== inner) { fixCount++; return '

Academic PDF → GitHub GFM Conversion A battle-tested workflow for converting academic/research PDF papers into GitHub-renderable GFM markdown with inline figures, mathematically correct LaTeX, and validated output. Battle-tested on : López de Prado (2026) "How to Use the Sharpe Ratio" — 51 pages, 82 equations, 8 figures. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Quick Start (3 Steps) --- CRITICAL: Detect PDF Type First This…

+ r + '

Academic PDF → GitHub GFM Conversion A battle-tested workflow for converting academic/research PDF papers into GitHub-renderable GFM markdown with inline figures, mathematically correct LaTeX, and validated output. Battle-tested on : López de Prado (2026) "How to Use the Sharpe Ratio" — 51 pages, 82 equations, 8 figures. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Quick Start (3 Steps) --- CRITICAL: Detect PDF Type First This…

; }\n return match;\n });\n\n if (fixed !== src) {\n writeFileSync(filePath, fixed, 'utf8');\n console.log(`✓ Applied ${fixCount} auto-fix(es) — file updated`);\n console.log(' Fixed: E1 ($ → ```math for \\\\\\\\ blocks), E2 (blank lines), W1 (^* → ^{\\\\ast})');\n } else {\n console.log(' No auto-fixes needed.');\n }\n}\n\n// ═══════════════════════════════════════════════════════\n// Summary\n// ═══════════════════════════════════════════════════════\nconst totalErrors = katexErrors + gfmErrors;\nconsole.log('\\n── Summary ─────────────────────────────────────────────────');\nconsole.log(` Equations checked : ${checked} (gitlab.com limit: ${GITLAB_COM_LIMIT})`);\nconsole.log(` KaTeX errors : ${katexErrors}`);\nconsole.log(` GFM errors : ${gfmErrors}`);\nconsole.log(` GFM warnings : ${gfmWarnings}`);\nif (autoFix) console.log(' --fix was applied');\nconsole.log('');\nif (totalErrors > 0) {\n console.log('Fix errors before pushing to GitHub.');\n} else if (gfmWarnings > 0) {\n console.log('No blocking errors. Review warnings before pushing.');\n} else {\n console.log('All checks passed — safe to push.');\n}\n\nprocess.exit(totalErrors > 0 ? 1 : 0);\n","content_type":"text/javascript","language":"javascript","size":14455,"content_sha256":"58f5ca7974d250d514900fc004d5d55be6725cbbf3ed732767a9d921a8de0a4e"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Academic PDF → GitHub GFM Conversion","type":"text"}]},{"type":"paragraph","content":[{"text":"A battle-tested workflow for converting academic/research PDF papers into GitHub-renderable GFM markdown with inline figures, mathematically correct LaTeX, and validated output.","type":"text"}]},{"type":"paragraph","content":[{"text":"Battle-tested on","type":"text","marks":[{"type":"strong"}]},{"text":": López de Prado (2026) \"How to Use the Sharpe Ratio\" — 51 pages, 82 equations, 8 figures.","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Self-Evolving Skill","type":"text","marks":[{"type":"strong"}]},{"text":": This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start (3 Steps)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Step 1: Extract prose (best structure preservation)\nuv run --python 3.14 --with pymupdf4llm python3 -c \"\nimport pymupdf4llm\nmd = pymupdf4llm.to_markdown('paper.pdf')\nopen('paper-raw.md', 'w').write(md)\n\"\n\n# Step 2: Extract images\nuv run --python 3.14 --with pymupdf python3 references/extract-images.py paper.pdf\n\n# Step 3: Validate math before pushing\nnode references/validate-math.mjs paper.md","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"CRITICAL: Detect PDF Type First","type":"text"}]},{"type":"paragraph","content":[{"text":"This determines the entire workflow.","type":"text","marks":[{"type":"strong"}]},{"text":" Getting it wrong wastes hours.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Type A — Word-Generated PDF (Most Modern Academic Papers)","type":"text"}]},{"type":"paragraph","content":[{"text":"Signs","type":"text","marks":[{"type":"strong"}]},{"text":": Embedded fonts, copyable text, Unicode math chars when you copy-paste (∑, π, α, β, γ, →)","type":"text"}]},{"type":"paragraph","content":[{"text":"Math encoding","type":"text","marks":[{"type":"strong"}]},{"text":": Math is Unicode text in PDF stream — NOT images, NOT glyph maps","type":"text"}]},{"type":"paragraph","content":[{"text":"Consequence","type":"text","marks":[{"type":"strong"}]},{"text":": OCR tools like ","type":"text"},{"text":"marker-pdf","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"cannot extract LaTeX","type":"text","marks":[{"type":"strong"}]},{"text":" — they see text like \"γ₄\" not ","type":"text"},{"text":"\\gamma_4","type":"text","marks":[{"type":"code_inline"}]},{"text":". They may return empty output or crash silently.","type":"text"}]},{"type":"paragraph","content":[{"text":"Required approach","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"pymupdf4llm","type":"text","marks":[{"type":"code_inline"}]},{"text":" for prose extraction","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Manually transcribe all equations","type":"text","marks":[{"type":"strong"}]},{"text":" from PDF screenshots — there is no shortcut","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Read each formula visually, write LaTeX by hand","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"How to confirm","type":"text","marks":[{"type":"strong"}]},{"text":": Run ","type":"text"},{"text":"marker-pdf","type":"text","marks":[{"type":"code_inline"}]},{"text":" — if output is empty or has zero math content, it's Type A.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Type B — LaTeX-Generated PDF","type":"text"}]},{"type":"paragraph","content":[{"text":"Signs","type":"text","marks":[{"type":"strong"}]},{"text":": Computer Modern fonts, precise mathematical spacing, arxiv.org source available","type":"text"}]},{"type":"paragraph","content":[{"text":"Math encoding","type":"text","marks":[{"type":"strong"}]},{"text":": Glyph-mapped — structure is partially extractable","type":"text"}]},{"type":"paragraph","content":[{"text":"Approach","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"pymupdf4llm","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"pdftotext","type":"text","marks":[{"type":"code_inline"}]},{"text":" for text. If arxiv source exists, extract directly from ","type":"text"},{"text":".tex","type":"text","marks":[{"type":"code_inline"}]},{"text":" (vastly preferred over PDF conversion).","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Type C — Scanned/Image PDF","type":"text"}]},{"type":"paragraph","content":[{"text":"Signs","type":"text","marks":[{"type":"strong"}]},{"text":": All pages are raster images, zero copyable text","type":"text"}]},{"type":"paragraph","content":[{"text":"Approach","type":"text","marks":[{"type":"strong"}]},{"text":": OCR pipeline — ","type":"text"},{"text":"marker-pdf","type":"text","marks":[{"type":"code_inline"}]},{"text":" is best option, or ","type":"text"},{"text":"tesseract","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Tool Comparison","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Tool","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Best For","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Install","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Key Limitation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pymupdf4llm","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type A/B prose (best structure)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"uv run --with pymupdf4llm","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Math as Unicode, not LaTeX","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pdftotext","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Quick plain text","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"brew install poppler","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Loses table structure","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"markitdown","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Alternative prose","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"uv run --with 'markitdown[pdf]'","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Slight over-spacing; same math limit","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"marker-pdf","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type C scanned only","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pip install marker-pdf","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fails silently on Type A","type":"text","marks":[{"type":"strong"}]},{"text":" (Unicode text bug)","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"Never trust ","type":"text","marks":[{"type":"strong"}]},{"text":"marker-pdf","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" output on Type A/B PDFs","type":"text","marks":[{"type":"strong"}]},{"text":" — the apparent \"success\" with empty math sections is the failure mode.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Image Extraction","type":"text"}]},{"type":"paragraph","content":[{"text":"Save ","type":"text"},{"text":"references/extract-images.py","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"python"},"content":[{"text":"import fitz, os, sys\n\ndoc = fitz.open(sys.argv[1])\nos.makedirs(\"references/media\", exist_ok=True)\nsaved = []\nfor page_num in range(len(doc)):\n for img_idx, img in enumerate(doc[page_num].get_images(full=True)):\n xref = img[0]\n base_image = doc.extract_image(xref)\n img_bytes = base_image[\"image\"]\n if len(img_bytes) \u003c 2048: # skip icons/logos/watermarks/rules\n continue\n ext = base_image[\"ext\"]\n fname = f\"fig-p{page_num+1:02d}-{img_idx+1:02d}.{ext}\"\n with open(f\"references/media/{fname}\", \"wb\") as f:\n f.write(img_bytes)\n saved.append((page_num+1, fname, base_image.get(\"width\"), base_image.get(\"height\")))\n print(f\"Saved: {fname} ({len(img_bytes)//1024}KB, {base_image.get('width')}×{base_image.get('height')})\")\ndoc.close()\nprint(f\"\\n{len(saved)} images saved to references/media/\")","type":"text"}]},{"type":"paragraph","content":[{"text":"Naming","type":"text","marks":[{"type":"strong"}]},{"text":": ","type":"text"},{"text":"fig-p{page:02d}-{idx:02d}.{ext}","type":"text","marks":[{"type":"code_inline"}]},{"text":" — page number in name for easy location matching.","type":"text"}]},{"type":"paragraph","content":[{"text":"Size filter","type":"text","marks":[{"type":"strong"}]},{"text":": Skip ","type":"text"},{"text":"\u003c 2 KB","type":"text","marks":[{"type":"code_inline"}]},{"text":" (captures icons, watermarks, horizontal rules). Review everything ≥ 2 KB — some are decorative but most are figures.","type":"text"}]},{"type":"paragraph","content":[{"text":"Insert in markdown","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"![Figure 1: Variance of Sharpe ratio estimates](./media/fig-p12-01.png)","type":"text"}]},{"type":"paragraph","content":[{"text":"Place immediately after the nearest section heading or the paragraph that references the figure.","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"GitHub GFM Math Rendering Rules","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"The ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" vs ","type":"text"},{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]},{"text":" Decision — Root Cause","type":"text"}]},{"type":"paragraph","content":[{"text":"GitHub's Markdown pre-processor runs BEFORE the math renderer.","type":"text","marks":[{"type":"strong"}]},{"text":" It treats ","type":"text"},{"text":"\\\\","type":"text","marks":[{"type":"code_inline"}]},{"text":" as an escaped backslash and collapses it to ","type":"text"},{"text":"\\","type":"text","marks":[{"type":"code_inline"}]},{"text":". This breaks LaTeX line breaks in display math.","type":"text"}]},{"type":"paragraph","content":[{"text":"The rule is simple","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Equation type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Reason","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Single-line display","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"$...$","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"No ","type":"text"},{"text":"\\\\","type":"text","marks":[{"type":"code_inline"}]},{"text":" → pre-processor safe","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Multi-line (contains ","type":"text"},{"text":"\\\\","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\\begin{aligned}","type":"text","marks":[{"type":"code_inline"}]},{"text":", matrices)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Pre-processor does NOT process code fences","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Inline","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"$...$","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Standard","type":"text"}]}]}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"markdown"},"content":[{"text":"# BROKEN on GitHub — \\\\ stripped by pre-processor:\n\n$\n\\begin{aligned}\na &= b + c \\\\\nd &= e + f\n\\end{aligned}\n$\n\n# CORRECT on GitHub:\n\n```math\n\\begin{aligned}\na &= b + c \\\\\nd &= e + f\n\\end{aligned}\n```","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"\n### Display Block Formatting Rules\n\n- `$` must be on its **own line** — not `$formula$` on one line\n- **Blank line required** before AND after every `$` block\n- **Blank line required between consecutive** `$` blocks\n- These rules do NOT apply to `` ```math ``` `` blocks\n\n### Supported/Unsupported LaTeX\n\nSee [references/github-math-support-table.md](./references/github-math-support-table.md) for the full table.\n\n**Key things to avoid**:\n\n| Command | Problem | Fix |\n|---------|---------|-----|\n| `\\begin{align}` | ❌ Not supported by GitHub | Use `\\begin{aligned}` |\n| `\\boxed{}` | ⚠️ Can cause raw LaTeX passthrough | Remove or use bold text |\n| `\\operatorname{}` | ⚠️ Active GitHub bug, inconsistent | Use `\\text{}` or `\\mathrm{}` |\n| `\\newcommand` | ❌ Was briefly available, then pulled | Expand all macros inline |\n| `x^_y` | Superscript immediately before subscript | Write `x^{*}_{i}` with braces |\n\n### Common Gotchas\n\n- `\\\\[8pt]` vertical spacing inside `$` → eaten by pre-processor → move to `` ```math ``` ``\n- `\\frac{1}{T}:\\left(` → spurious colon after fraction → remove colon\n- Pearson vs excess kurtosis: most finance formulas need Pearson (γ₄ = 3 for Gaussian), not excess. **Always document the kurtosis convention in the formula comment.**\n- `\\begin{pmatrix}` with `\\\\` → must use `` ```math ``` ``\n- `\\begin{cases}` with multiple rows → must use `` ```math ``` ``\n\n---\n\n## GitLab: No Workarounds Needed\n\n**Empirically verified 2026-03-15** on GitLab CE 18.9.2. Confirmed by Comrak source code analysis.\n\nGitLab uses the **Comrak** Rust parser with `math_dollars: true`. When Comrak encounters `$`, it calls `handle_dollars` which slices the raw input buffer directly and stores it as a `NodeMath` AST node — CommonMark's backslash handler is never invoked on math content. The raw LaTeX is passed to KaTeX via `\u003cspan data-math-style=\"display/inline\">` unchanged.\n\n**Every GitHub workaround is unnecessary on GitLab:**\n\n| GitHub problem | GitHub fix required | GitLab |\n|----------------|---------------------|--------|\n| `\\\\` in `$` stripped → broken multiline | Use ` ```math ``` ` | `$` works with `\\\\` |\n| `\\left\\{` → `\\left{` (delimiter error) | Use `\\left\\lbrace` | `\\left\\{` works |\n| `\\{...\\}` set notation → invisible braces | Use `\\lbrace...\\rbrace` | `\\{...\\}` works |\n| `\\,` in `$` → literal comma | Remove `\\,` | `\\,` works |\n| `\\,` in inline ` academic-pdf-to-gfm — Skillopedia → literal comma | Remove `\\,` | `\\,` works |\n\nOn GitLab you can write standard LaTeX without any platform-specific workarounds. If you're targeting GitLab (or hosting your own GitLab CE), skip all the `\\lbrace`/`\\rbrace` substitutions and ` ```math ``` ` conversions — plain `$` with standard LaTeX is correct.\n\n### GitLab.com Has a Hard 50-Span Per-Page Limit\n\n**GitLab.com (SaaS) enforces a limit of 50 total math spans per page** (display + inline combined). After the 50th span, all subsequent equations silently fall back to raw LaTeX text. This limit exists to prevent DoS attacks and cannot be overridden on GitLab.com.\n\n| Document math density | gitlab.com | Self-hosted CE |\n|---|---|---|\n| ≤ 50 total spans | ✅ Renders fully | ✅ |\n| 51–100 spans | ⚠️ Partial render | ✅ |\n| 100+ spans (academic papers) | ❌ Most equations raw text | ✅ Disable with `math_rendering_limits_enabled: false` |\n\n**Validated on**: Sharpe ratio paper (341 spans) — breaks at span 51 on gitlab.com, renders fully on local CE.\n\n**The W6 check in `validate-math.mjs`** warns when a file exceeds the limit.\n\n**Summary: which platform to use**:\n- **GitHub.com**: No math span limit. Use `\\lbrace`/`\\rbrace` workarounds (handled by `--fix`).\n- **Self-hosted GitLab CE**: No limit (disable math_rendering_limits_enabled). No workarounds needed.\n- **GitLab.com**: Only suitable for documents with ≤ 50 math spans.\n\n### Self-hosting GitLab CE for Math-Heavy Documents\n\nGitLab CE is free and runs on a single machine. On a 61 GB workstation with slim config:\n- Memory footprint: ~3 GB (`puma['worker_processes'] = 2`, `sidekiq['concurrency'] = 5`, monitoring disabled)\n- Push mirroring to GitHub: free on CE (syncs within 5 min)\n- `glab` CLI: first-party, comparable to `gh`\n\n```yaml\n# docker-compose.yml — slim GitLab CE\nservices:\n gitlab:\n image: gitlab/gitlab-ce:latest\n restart: unless-stopped\n environment:\n GITLAB_OMNIBUS_CONFIG: |\n external_url 'http://YOUR_IP:8929'\n puma['worker_processes'] = 2\n sidekiq['concurrency'] = 5\n prometheus_monitoring['enable'] = false\n alertmanager['enable'] = false\n node_exporter['enable'] = false\n redis_exporter['enable'] = false\n postgres_exporter['enable'] = false\n gitlab_exporter['enable'] = false\n ports: [\"8929:8929\", \"8922:22\"]\n volumes:\n - /srv/gitlab/config:/etc/gitlab\n - /srv/gitlab/logs:/var/log/gitlab\n - /srv/gitlab/data:/var/opt/gitlab\n```\n\n---\n\n## Validation Pipeline\n\n### Step 1: Install KaTeX Validator\n\n```bash\nbun add -g katex # Bun-first per project policy\n# or: npm install -g katex","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Step 2: Run Before Every Push","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Validate only (exit 1 on errors)\nnode references/validate-math.mjs your-file.md\n\n# Validate + auto-fix correctable issues\nnode references/validate-math.mjs your-file.md --fix","type":"text"}]},{"type":"paragraph","content":[{"text":"The script is at ","type":"text"},{"text":"references/validate-math.mjs","type":"text","marks":[{"type":"link","attrs":{"href":"./references/validate-math.mjs","title":null}}]},{"text":". It runs two layers:","type":"text"}]},{"type":"paragraph","content":[{"text":"Layer 1 — KaTeX syntax","type":"text","marks":[{"type":"strong"}]},{"text":": parse errors in ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]},{"text":" blocks ","type":"text"},{"text":"Layer 2 — GFM structural","type":"text","marks":[{"type":"strong"}]},{"text":" (issues KaTeX passes but GitHub breaks):","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Code","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Severity","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Auto-fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"E0","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\!","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\,","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\;","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":" in ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" block — pre-processor strips backslash → parse error cascade","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✅ spacing removed; ","type":"text"},{"text":"\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":"→","type":"text"},{"text":"\\lbrace","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"E0b","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Warning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\,","type":"text","marks":[{"type":"code_inline"}]},{"text":" in inline ","type":"text"},{"text":"$...$","type":"text","marks":[{"type":"code_inline"}]},{"text":" — invisible braces or literal commas in prose","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✅ → ","type":"text"},{"text":"\\lbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"\\rbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":"; ","type":"text"},{"text":"\\,","type":"text","marks":[{"type":"code_inline"}]},{"text":" removed","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"E1","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" block with ","type":"text"},{"text":"\\\\","type":"text","marks":[{"type":"code_inline"}]},{"text":" — GitHub pre-processor strips backslashes","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✅ → ","type":"text"},{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"E2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Consecutive ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" blocks without blank line — orphaned delimiter cascade","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✅ add blank line","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"W1","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Warning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bare ","type":"text"},{"text":"^*","type":"text","marks":[{"type":"code_inline"}]},{"text":" in ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" block — markdown italic pairing eats the ","type":"text"},{"text":"*","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✅ → ","type":"text"},{"text":"^{\\ast}","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"W2","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Warning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\begin{align}","type":"text","marks":[{"type":"code_inline"}]},{"text":" — not supported on GitHub","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✗ manual","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"W3","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Warning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\boxed{}","type":"text","marks":[{"type":"code_inline"}]},{"text":" — can cause raw LaTeX passthrough","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✗ manual","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"W4","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Warning","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\operatorname{}","type":"text","marks":[{"type":"code_inline"}]},{"text":" — inconsistent GitHub support","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"✗ manual","type":"text"}]}]}]}]},{"type":"paragraph","content":[{"text":"E0 is the most dangerous","type":"text","marks":[{"type":"strong"}]},{"text":": a single failing ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" block exposes its ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" delimiters as literal text, creating an orphaned ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" that shifts ALL subsequent inline ","type":"text"},{"text":"$...$","type":"text","marks":[{"type":"code_inline"}]},{"text":" pairings. One broken equation takes down the entire document.","type":"text"}]},{"type":"paragraph","content":[{"text":"\\{","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":"/","type":"text","marks":[{"type":"strong"}]},{"text":"\\}","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" trap","type":"text","marks":[{"type":"strong"}]},{"text":": In ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" blocks, ","type":"text"},{"text":"\\left\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":" becomes ","type":"text"},{"text":"\\left{","type":"text","marks":[{"type":"code_inline"}]},{"text":" (invalid KaTeX delimiter → \"Missing or unrecognized delimiter\") and ","type":"text"},{"text":"\\{...\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":" set notation becomes invisible grouping. Fix: use ","type":"text"},{"text":"\\lbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"\\rbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":" (letter-based, CommonMark-immune). This affects every equation using set notation like ","type":"text"},{"text":"\\{\\hat{SR}_k\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"\\min_T\\left\\{...\\right\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"Exits code 1 on errors (CI-friendly). Warnings do not block CI but should be reviewed.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Local Preview Tools","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# GitHub-accurate hot-reload preview\nbun add -g @hyrious/gfm\ngfm your-file.md --serve\n\n# Offline binary (gh extension)\ngh extension install thiagokokada/gh-gfm-preview\ngh gfm-preview your-file.md","type":"text"}]},{"type":"paragraph","content":[{"text":"VS Code extensions:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"shd101wyy.markdown-preview-enhanced","type":"text","marks":[{"type":"code_inline"}]},{"text":" — closest to GitHub rendering","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"bierner.markdown-preview-github-styles","type":"text","marks":[{"type":"code_inline"}]},{"text":" — GitHub CSS styling","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Multi-Agent Adversarial Equation Validation","type":"text"}]},{"type":"paragraph","content":[{"text":"For papers with 10+ equations, use this multi-agent pattern:","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 1 — Parallel Extraction","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent A","type":"text","marks":[{"type":"strong"}]},{"text":": Extract prose with pymupdf4llm, transcribe math from PDF screenshots","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent B","type":"text","marks":[{"type":"strong"}]},{"text":": Extract and categorize all images","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 2 — Parallel Validation","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent C","type":"text","marks":[{"type":"strong"}]},{"text":": Validate equations against reference implementation (if code/repo exists)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Agent D","type":"text","marks":[{"type":"strong"}]},{"text":": Numerical spot-checks — compute paper's exhibit values, compare","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 3 — Discrepancy Handling","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For each discrepancy: write ","type":"text"},{"text":"/tmp/paper-discrepancy/eq-{N}.md","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Spawn resolver agents to search online for authoritative third-party sources","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Authority rule","type":"text","marks":[{"type":"strong"}]},{"text":": Paper is tentatively more authoritative than code implementation; a third independent source breaks ties","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Phase 4 — Guarded Application","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Apply ","type":"text"},{"text":"only HIGH-confidence fixes","type":"text","marks":[{"type":"strong"}]},{"text":" to the markdown","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"For MEDIUM-confidence: spawn an independent audit agent before touching the file","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Document all discrepancies even if not fixed — future readers need to know","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Anti-Patterns","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Anti-pattern","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Why it fails","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\!\\left(","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"\\,","type":"text","marks":[{"type":"code_inline"}]},{"text":" in ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" blocks","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GH pre-processor strips ","type":"text"},{"text":"\\!","type":"text","marks":[{"type":"code_inline"}]},{"text":"→","type":"text"},{"text":"!","type":"text","marks":[{"type":"code_inline"}]},{"text":" before KaTeX — ","type":"text"},{"text":"!\\left(","type":"text","marks":[{"type":"code_inline"}]},{"text":" crashes KaTeX, cascades all","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Remove ","type":"text"},{"text":"\\!","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\,","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"\\;","type":"text","marks":[{"type":"code_inline"}]},{"text":" (spacing only) — or use ","type":"text"},{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\left\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"\\{...\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":" in ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" blocks","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":"→","type":"text"},{"text":"{","type":"text","marks":[{"type":"code_inline"}]},{"text":" (CommonMark escape), so ","type":"text"},{"text":"\\left\\{","type":"text","marks":[{"type":"code_inline"}]},{"text":"→","type":"text"},{"text":"\\left{","type":"text","marks":[{"type":"code_inline"}]},{"text":" = \"Missing delimiter\" error, and ","type":"text"},{"text":"\\{x\\}","type":"text","marks":[{"type":"code_inline"}]},{"text":" renders without visible braces","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replace with ","type":"text"},{"text":"\\left\\lbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\\right\\rbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\\lbrace","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"\\rbrace","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"$\\begin{aligned}...\\\\...\\end{aligned}$","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\\\","type":"text","marks":[{"type":"code_inline"}]},{"text":" stripped by GH pre-processor","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Trusting ","type":"text"},{"text":"marker-pdf","type":"text","marks":[{"type":"code_inline"}]},{"text":" on Word PDFs","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Returns no output or zero math (Unicode bug)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Read as screenshots, transcribe manually","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\begin{align}","type":"text","marks":[{"type":"code_inline"}]},{"text":" in display math","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Not supported by GitHub","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Replace with ","type":"text"},{"text":"\\begin{aligned}","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\operatorname{Cov}","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Active GH bug — sometimes renders raw","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"\\text{Cov}","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"\\mathrm{Cov}","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"KaTeX validation only, no ","type":"text"},{"text":"```math ```","type":"text","marks":[{"type":"code_inline"}]},{"text":" conversion","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"KaTeX passes but GH pre-processor still breaks ","type":"text"},{"text":"\\\\","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Also convert ALL multi-line blocks","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\\boxed{}","type":"text","marks":[{"type":"code_inline"}]},{"text":" for highlighting","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Can cause raw LaTeX passthrough on GitHub","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use bold text or a blockquote callout","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Excess kurtosis in formulas expecting Pearson","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Silent ~50% underestimate in variance formulas","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Always document convention; use ","type":"text"},{"text":"scipy.stats.kurtosis(fisher=False)","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Consecutive ","type":"text"},{"text":"$","type":"text","marks":[{"type":"code_inline"}]},{"text":" blocks without blank lines","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GitHub collapses them into one broken block","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add blank line between each block","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Running validation AFTER pushing","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Bugs visible in public repo","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Validate locally before every push (","type":"text"},{"text":"--fix","type":"text","marks":[{"type":"code_inline"}]},{"text":" auto-corrects E0/E1/E2)","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"References","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"File","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"validate-math.mjs","type":"text","marks":[{"type":"link","attrs":{"href":"./references/validate-math.mjs","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"KaTeX batch validator for GFM files","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pdf-type-detection.md","type":"text","marks":[{"type":"link","attrs":{"href":"./references/pdf-type-detection.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Detailed guide to detecting PDF type","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"github-math-support-table.md","type":"text","marks":[{"type":"link","attrs":{"href":"./references/github-math-support-table.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Full supported/unsupported LaTeX table","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Related Skills","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Relationship","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pandoc-pdf-generation","type":"text","marks":[{"type":"link","attrs":{"href":"../pandoc-pdf-generation/SKILL.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Opposite direction: markdown → PDF","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"documentation-standards","type":"text","marks":[{"type":"link","attrs":{"href":"../documentation-standards/SKILL.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"GFM formatting standards","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"quant-research:opendeviation-eval-metrics","type":"text","marks":[{"type":"link","attrs":{"href":"../../../quant-research/skills/opendeviation-eval-metrics/SKILL.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Worked example: ","type":"text"},{"text":"references/how-to-use-the-sharpe-ratio-2026.md","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Post-Execution Reflection","type":"text"}]},{"type":"paragraph","content":[{"text":"After this skill completes, reflect before closing the task:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Locate yourself.","type":"text","marks":[{"type":"strong"}]},{"text":" — Find this SKILL.md's canonical path before editing.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What failed?","type":"text","marks":[{"type":"strong"}]},{"text":" — Fix the instruction that caused it.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What worked better than expected?","type":"text","marks":[{"type":"strong"}]},{"text":" — Promote to recommended practice.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"What drifted?","type":"text","marks":[{"type":"strong"}]},{"text":" — Fix any script, reference, or dependency that no longer matches reality.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Log it.","type":"text","marks":[{"type":"strong"}]},{"text":" — Evolution-log entry with trigger, fix, and evidence.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Do NOT defer. The next invocation inherits whatever you leave behind.","type":"text"}]}]},"metadata":{"date":"2026-06-05","name":"academic-pdf-to-gfm","author":"@skillopedia","source":{"stars":49,"repo_name":"cc-skills","origin_url":"https://github.com/terrylica/cc-skills/blob/HEAD/plugins/doc-tools/skills/academic-pdf-to-gfm/SKILL.md","repo_owner":"terrylica","body_sha256":"87796ae92692547b825fb5a4038f6f5149f330fea7592fc9358813d3f5ea618c","cluster_key":"330d09e878e6ec85844e34dd765128ea6e06b5ef5bdf1b5472d5b5d204e0402a","clean_bundle":{"format":"clean-skill-bundle-v1","source":"terrylica/cc-skills/plugins/doc-tools/skills/academic-pdf-to-gfm/SKILL.md","attachments":[{"id":"0fd157aa-3d49-51a6-a4ca-0dc0dc46b99b","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/0fd157aa-3d49-51a6-a4ca-0dc0dc46b99b/attachment.json","path":"evals/evals.json","size":2430,"sha256":"2a1840204005a09789d866d573cb063a27d5b6706bdba7fc969f3603e0d4e567","contentType":"application/json; charset=utf-8"},{"id":"bfd260f8-5610-556f-8526-ed5d77de132c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bfd260f8-5610-556f-8526-ed5d77de132c/attachment.md","path":"references/github-math-support-table.md","size":10648,"sha256":"74c9ab81f6d40c9ef85837ac86bcd7bdc87dd04c1b9652002f204eaa1e8a3bcf","contentType":"text/markdown; charset=utf-8"},{"id":"be1532d6-1e7a-5fb3-a33e-917b7036f352","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/be1532d6-1e7a-5fb3-a33e-917b7036f352/attachment.md","path":"references/pdf-type-detection.md","size":6430,"sha256":"f6b2bc8e7d8f143ed899bb5ea1d2575768952744bd048f5094e90ab28e5cd113","contentType":"text/markdown; charset=utf-8"},{"id":"e5a39d03-0ea4-57ae-aac4-d26fee3f25f4","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e5a39d03-0ea4-57ae-aac4-d26fee3f25f4/attachment.mjs","path":"references/validate-math.mjs","size":14455,"sha256":"58f5ca7974d250d514900fc004d5d55be6725cbbf3ed732767a9d921a8de0a4e","contentType":"text/javascript"}],"bundle_sha256":"4009b4b3e23e69795f19d455acbddc50ba6f150da32a72bc65028675ef89812d","attachment_count":4,"text_attachments":4,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"plugins/doc-tools/skills/academic-pdf-to-gfm/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"documents-office","category_label":"Documents"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"documents-office","import_tag":"clean-skills-v1","description":"Convert academic PDF papers to GitHub-renderable GFM markdown with math equations. TRIGGERS - PDF, GitHub markdown, math","allowed-tools":"Read, Grep, Glob, Bash, Write, Edit"}},"renderedAt":1782981950840}

Academic PDF → GitHub GFM Conversion A battle-tested workflow for converting academic/research PDF papers into GitHub-renderable GFM markdown with inline figures, mathematically correct LaTeX, and validated output. Battle-tested on : López de Prado (2026) "How to Use the Sharpe Ratio" — 51 pages, 82 equations, 8 figures. Self-Evolving Skill : This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues. Quick Start (3 Steps) --- CRITICAL: Detect PDF Type First This…