Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ build/
cmake-build-*/
.clangd
CMakeUserPresets.json
# machine-specific Conan cache paths, generated by scripts/gen-vscode-env.py
.vscode/.env

offline/
## PDF CJK CMap input data (fetched by tools/pdf/generate_cid_data.py)
Expand Down
11 changes: 11 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"recommendations": [
"ms-vscode.cmake-tools",
"llvm-vs-code-extensions.vscode-clangd",
"vadimcn.vscode-lldb",
"twxs.cmake"
],
"unwantedRecommendations": [
"ms-vscode.cpptools"
]
}
69 changes: 69 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"version": "0.2.0",
"inputs": [
{
"id": "gtestFilter",
"type": "promptString",
"description": "GoogleTest --gtest_filter",
"default": "*"
},
{
"id": "translateInput",
"type": "promptString",
"description": "Input document to translate (absolute path)"
},
{
"id": "translateOutput",
"type": "promptString",
"description": "Output directory for HTML",
"default": "${workspaceFolder}/cmake-build-relwithdebinfo/output"
},
{
"id": "metaInput",
"type": "promptString",
"description": "Input document for meta"
}
],
"configurations": [
{
"name": "Debug odr_test (filtered)",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/cmake-build-relwithdebinfo/test/odr_test",
"args": ["--gtest_filter=${input:gtestFilter}"],
"cwd": "${workspaceFolder}/cmake-build-relwithdebinfo",
"envFile": "${workspaceFolder}/.vscode/.env",
"preLaunchTask": "build: odr_test"
},
{
"name": "Debug translate <input> <output>",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/cmake-build-relwithdebinfo/cli/translate",
"args": ["${input:translateInput}", "${input:translateOutput}"],
"cwd": "${workspaceFolder}",
"envFile": "${workspaceFolder}/.vscode/.env",
"preLaunchTask": "build: translate"
},
{
"name": "Debug meta <input>",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/cmake-build-relwithdebinfo/cli/meta",
"args": ["${input:metaInput}"],
"cwd": "${workspaceFolder}",
"envFile": "${workspaceFolder}/.vscode/.env",
"preLaunchTask": "build: all CLI tools"
},
{
"name": "Debug server",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/cmake-build-relwithdebinfo/cli/server",
"args": [],
"cwd": "${workspaceFolder}",
"envFile": "${workspaceFolder}/.vscode/.env",
"preLaunchTask": "build: all CLI tools"
}
]
}
32 changes: 32 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
// ---- Build: CMake Tools drives the Conan-generated presets ----
// Presets come from CMakeUserPresets.json -> cmake-build-*/CMakePresets.json,
// written by `conan install`. Pick the active one from the status bar.
"cmake.useCMakePresets": "always",
"cmake.options.statusBarVisibility": "visible",

// ---- IntelliSense: clangd (matches the repo's .clangd / .clang-tidy) ----
// Disable the built-in cpptools engine so it doesn't fight clangd.
"C_Cpp.intelliSenseEngine": "disabled",
"clangd.arguments": [
"--compile-commands-dir=${workspaceFolder}/cmake-build-relwithdebinfo",
"--background-index",
"--clang-tidy",
"--header-insertion=never",
"--pretty"
],

// ---- Formatting: clang-format (.clang-format at repo root) ----
"editor.formatOnSave": false,
"[cpp]": {
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
},
"[c]": {
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
},

"files.associations": {
"*.hpp": "cpp",
"*.ipp": "cpp"
}
}
120 changes: 120 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"version": "2.0.0",
"options": {
"cwd": "${workspaceFolder}"
},
"inputs": [
{
"id": "gtestFilter",
"type": "promptString",
"description": "GoogleTest --gtest_filter",
"default": "*"
},
{
"id": "translateInput",
"type": "promptString",
"description": "Input document to translate (absolute path)"
},
{
"id": "translateOutput",
"type": "promptString",
"description": "Output directory for HTML (absolute path)",
"default": "${workspaceFolder}/cmake-build-relwithdebinfo/output"
}
],
"tasks": [
{
"label": "build: odr (library)",
"type": "shell",
"command": "cmake --build cmake-build-relwithdebinfo --target odr",
"group": "build",
"problemMatcher": ["$gcc"]
},
{
"label": "build: odr_test",
"type": "shell",
"command": "cmake --build cmake-build-relwithdebinfo --target odr_test",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"]
},
{
"label": "build: translate",
"type": "shell",
"command": "cmake --build cmake-build-relwithdebinfo --target translate",
"group": "build",
"problemMatcher": ["$gcc"]
},
{
"label": "build: all CLI tools",
"type": "shell",
"command": "cmake --build cmake-build-relwithdebinfo --target translate back_translate meta server",
"group": "build",
"problemMatcher": ["$gcc"]
},
{
"label": "test: run odr_test (filtered)",
"type": "shell",
"command": "${workspaceFolder}/scripts/run-with-env.sh ./test/odr_test --gtest_filter='${input:gtestFilter}'",
"options": {
"cwd": "${workspaceFolder}/cmake-build-relwithdebinfo"
},
"dependsOn": ["build: odr_test"],
"group": {
"kind": "test",
"isDefault": true
},
"problemMatcher": []
},
{
"label": "cli: translate <input> <output>",
"type": "shell",
"command": "scripts/run-with-env.sh ./cmake-build-relwithdebinfo/cli/translate '${input:translateInput}' '${input:translateOutput}'",
"dependsOn": ["build: translate"],
"problemMatcher": []
},
{
"label": "compare: reference output (headless)",
"detail": "Runs compare-html in Docker (Firefox headless) against test/data/reference-output. Build + run odr_test first to populate output.",
"type": "shell",
"command": "test/scripts/compare_output.sh",
"problemMatcher": []
},
{
"label": "compare: reference output (server on :8000)",
"detail": "Runs compare-html-server in Docker; open http://localhost:8000 to inspect diffs interactively. Ctrl-C in the terminal to stop.",
"type": "shell",
"command": "test/scripts/compare_output_server.sh",
"isBackground": true,
"problemMatcher": []
},
{
"label": "env: regenerate .vscode/.env",
"detail": "Re-run after every `conan install` to refresh Conan cache paths.",
"type": "shell",
"command": "python3 scripts/gen-vscode-env.py",
"problemMatcher": []
},
{
"label": "profile: Instruments Time Profiler (odr_test, filtered)",
"detail": "Records a .trace with Instruments; opens in Instruments.app when done.",
"type": "shell",
"command": "rm -rf profile.trace && ${workspaceFolder}/scripts/run-with-env.sh xctrace record --template 'Time Profiler' --output profile.trace --launch -- ./test/odr_test --gtest_filter='${input:gtestFilter}' && open profile.trace",
"options": {
"cwd": "${workspaceFolder}/cmake-build-relwithdebinfo"
},
"dependsOn": ["build: odr_test"],
"problemMatcher": []
},
{
"label": "profile: Instruments Time Profiler (translate)",
"detail": "Records a .trace of the translate CLI on one file.",
"type": "shell",
"command": "rm -rf profile.trace && scripts/run-with-env.sh xctrace record --template 'Time Profiler' --output profile.trace --launch -- ./cmake-build-relwithdebinfo/cli/translate '${input:translateInput}' '${input:translateOutput}' && open profile.trace",
"dependsOn": ["build: translate"],
"problemMatcher": []
}
]
}
43 changes: 43 additions & 0 deletions scripts/gen-vscode-env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
"""Extract the runtime environment from the Conan-generated CMake test preset
into a plain KEY=VALUE file that VS Code launch configs (CodeLLDB `envFile`) and
tasks can consume.

The paths point into the Conan cache and change whenever dependencies are
re-installed, so re-run this after every `conan install` (there is a VS Code task
"env: regenerate .vscode/.env" that does exactly this).

Usage: scripts/gen-vscode-env.py [BUILD_DIR]
BUILD_DIR defaults to cmake-build-relwithdebinfo.
"""
import json
import os
import re
import sys
from pathlib import Path

repo = Path(__file__).resolve().parent.parent
build_dir = Path(sys.argv[1]) if len(sys.argv) > 1 else repo / "cmake-build-relwithdebinfo"
preset = build_dir / "CMakePresets.json"

if not preset.is_file():
sys.exit(f"no CMakePresets.json in {build_dir} β€” run `conan install` first")

data = json.loads(preset.read_text())
test_presets = data.get("testPresets") or [{}]
env = test_presets[0].get("environment", {})


def resolve(value: str) -> str:
# Resolve `$penv{VAR}` (parent/current environment) references to the value
# present when this script runs; CodeLLDB envFile has no variable expansion.
return re.sub(r"\$penv\{(\w+)\}", lambda m: os.environ.get(m.group(1), ""), value)


out = repo / ".vscode" / ".env"
out.parent.mkdir(exist_ok=True)
lines = [f"{k}={resolve(v)}" for k, v in env.items()]
out.write_text("\n".join(lines) + "\n")
print(f"wrote {len(lines)} vars to {out}")
for line in lines:
print(" " + line.split("=", 1)[0])
21 changes: 21 additions & 0 deletions scripts/run-with-env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Load the Conan runtime env from .vscode/.env (see gen-vscode-env.py) and exec
# the given command with it. Used by VS Code tasks so the test binary and CLI
# tools can find pdf2htmlEX / poppler / fontconfig / wvWare / libmagic data.
#
# Usage: scripts/run-with-env.sh <command> [args...]
set -euo pipefail

repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
env_file="$repo/.vscode/.env"

if [[ -f "$env_file" ]]; then
set -a
# shellcheck disable=SC1090
source "$env_file"
set +a
else
echo "warning: $env_file missing β€” run scripts/gen-vscode-env.py" >&2
fi

exec "$@"
Loading