Skip to content

Harden LaTeX entrypoint and \input{} resolution in parser#2

Draft
Copilot wants to merge 5 commits into
mainfrom
copilot/audit-code-improve-robustness
Draft

Harden LaTeX entrypoint and \input{} resolution in parser#2
Copilot wants to merge 5 commits into
mainfrom
copilot/audit-code-improve-robustness

Conversation

Copilot AI commented May 28, 2026

Copy link
Copy Markdown
Contributor

This change improves parser robustness in LaTeX projects where file layout is non-trivial. It eliminates fragile entrypoint selection and makes \input{} expansion resilient to nested includes and cyclic/self references.

  • Entrypoint correctness

    • Parsing a specific .tex file now uses that file as the project entrypoint.
    • Previously, file parsing could be redirected by directory-level main-file detection, producing inconsistent results.
  • Deterministic nested \input{} expansion

    • \input{} resolution is now recursive across subdirectories.
    • Substitutions are handled through regex replacement callbacks, avoiding global str.replace() side effects when the same directive appears multiple times.
  • Cycle-safe include handling

    • Added path-tracking during recursion to detect include cycles.
    • Cyclic includes are cut off safely (replaced with empty expansion) instead of re-entering recursion.
  • I/O fault tolerance

    • Main-file detection and include expansion now tolerate unreadable files without crashing.
    • On read failure, unresolved include directives are preserved unless the path is part of an active cycle.
def _resolve_inputs(self, directory: Path, tex_content: str, visited_paths: Optional[Set[Path]] = None) -> str:
    if visited_paths is None:
        visited_paths = set()

    pattern = re.compile(r"\\input\{([^}]+)\}")

    def _replace(match: re.Match) -> str:
        input_path = (directory / match.group(1)).with_suffix(".tex") if not (directory / match.group(1)).suffix else (directory / match.group(1))
        input_path = input_path.resolve()

        if input_path in visited_paths:
            return ""  # cycle protection

        ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants