badness 0.5.0

A language server, formatter, and linter for LaTeX
version: "3"

tasks:
  default:
    deps: [build]

  build:
    desc: Dev build
    cmds:
      - cargo build

  build-release:
    desc: Build release version
    cmds:
      - cargo build --release

  test:
    desc: Run all tests
    cmds:
      - cargo test

  fmt:
    desc: Format the code
    cmds:
      - cargo fmt

  fmt-check:
    desc: Check formatting (CI)
    cmds:
      - cargo fmt -- --check

  lint:
    desc: Clippy with warnings as errors
    cmds:
      - cargo clippy --all-targets --all-features -- -D warnings

  snapshots:
    desc: Regenerate / accept insta snapshots
    cmds:
      - INSTA_UPDATE=always cargo test

  parse-compat:
    desc: Soft differential parse-concordance report vs texlab (writes PARSE_COMPAT.md)
    cmds:
      - cargo test --test parse_compat -- --ignored --nocapture

  bib-parse-compat:
    desc: Soft differential BibTeX parse-concordance report vs texlab (writes BIB_PARSE_COMPAT.md)
    cmds:
      - cargo test --test bib_parse_compat -- --ignored --nocapture

  bib-fields:check:
    desc: Check data/bib_fields.json is in sync with biblatex's data model (blx-dm.def)
    cmds:
      - python3 scripts/gen_bib_fields.py

  bib-fields:sync:
    desc: Re-sync data/bib_fields.json's mechanical facts from biblatex's data model
    cmds:
      - python3 scripts/gen_bib_fields.py --write

  cwl:check:
    desc: Check data/cwl_signatures.json is in sync with the pinned TeXstudio CWL corpus
    cmds:
      - python3 scripts/gen_cwl_signatures.py

  cwl:sync:
    desc: Re-generate data/cwl_signatures.json from the pinned TeXstudio CWL corpus
    cmds:
      - python3 scripts/gen_cwl_signatures.py --write

  check:
    desc: Everything CI runs
    deps: [fmt-check, lint, test]

  bench:
    desc: Benchmark formatter speed vs tex-fmt & latexindent (writes benches/benchmark_results.json for the docs page)
    cmds:
      - ./benches/compare_format.sh --out benches/benchmark_results.json

  bench:download:
    desc: Fetch the real-world LaTeX corpus for the formatter benchmark
    cmds:
      - ./benches/documents/download.sh

  bench:micro:
    desc: In-process formatter micro-bench (parse vs format vs full, no startup floor)
    cmds:
      - cargo bench --bench formatting

  bench:profile:
    desc: Flamegraph the masters_dissertation per-byte hot paths (writes benches/flamegraph_masters.svg)
    env:
      BADNESS_BENCH_DOC: masters_dissertation.tex
      BADNESS_BENCH_ITERATIONS: 60
    cmds:
      - cargo flamegraph --bench formatting -o benches/flamegraph_masters.svg

  docs:
    desc: Build the documentation book
    deps: [docs:build]

  docs:build:
    desc: Build the mdBook docs into docs/book
    dir: docs
    cmds:
      - mdbook build
      - task: docs:canonical
      - task: docs:sitemap

  docs:canonical:
    desc: Inject <link rel="canonical"> into each rendered page
    dir: docs
    cmds:
      - >-
        cargo run --quiet --manifest-path doc-utils/Cargo.toml --bin canonical --
        book https://badness.dev/

  docs:sitemap:
    desc: Generate docs/book/sitemap.xml from the rendered book
    dir: docs
    cmds:
      - >-
        cargo run --quiet --manifest-path doc-utils/Cargo.toml --bin sitemap --
        book https://badness.dev/

  docs:serve:
    desc: Serve the docs locally with live reload
    dir: docs
    cmds:
      - mdbook serve --open

  docs:clean:
    desc: Remove built docs
    dir: docs
    cmds:
      - mdbook clean

  brand:
    desc: Build all brand artifacts (logo, wordmark, OG card) — PDF + PNG
    deps: [brand:logo, brand:wordmark, brand:og]

  brand:logo:
    desc: Build logo.pdf + logo.png + logo.svg
    dir: branding
    cmds:
      - pdflatex -interaction=nonstopmode -halt-on-error logo.tex >/dev/null
      - magick -density 600 logo.pdf -background none -strip logo.png
      # Vector logo for the README and as the docs favicon/header.
      - dvisvgm --pdf logo.pdf -o logo.svg >/dev/null
    sources:
      - logo.tex
      - _common.tex
    generates:
      - logo.pdf
      - logo.png
      - logo.svg

  brand:wordmark:
    desc: Build wordmark.pdf + wordmark.png
    dir: branding
    cmds:
      - pdflatex -interaction=nonstopmode -halt-on-error wordmark.tex >/dev/null
      - magick -density 600 wordmark.pdf -background none -strip wordmark.png
    sources:
      - wordmark.tex
      - _common.tex
    generates:
      - wordmark.pdf
      - wordmark.png

  brand:og:
    desc: Build og.pdf + og.png (1200x630)
    dir: branding
    cmds:
      - pdflatex -interaction=nonstopmode -halt-on-error og.tex >/dev/null
      # 1200pt @ 72dpi base, scale 2x to 144dpi for crisp social preview.
      - magick -density 144 og.pdf -strip og.png
    sources:
      - og.tex
      - _common.tex
    generates:
      - og.pdf
      - og.png

  brand:clean:
    desc: Remove built brand artifacts and LaTeX scratch files
    dir: branding
    cmds:
      - rm -f *.pdf *.png *.svg *.aux *.log *.out