Skip to content

fix: code-fence balancing and depth tracking in chunked translation validation#1175

Open
lin-bot23 wants to merge 1 commit into
Comfy-Org:mainfrom
lin-bot23:fix-translate-i18n-script
Open

fix: code-fence balancing and depth tracking in chunked translation validation#1175
lin-bot23 wants to merge 1 commit into
Comfy-Org:mainfrom
lin-bot23:fix-translate-i18n-script

Conversation

@lin-bot23

Copy link
Copy Markdown
Contributor

Summary

Fix a long-standing issue in chunked-translate.ts where the toggleFence function used a boolean toggle, causing incorrect fence tracking when code blocks are nested inside lists or when multiple fence markers appear within the same section. This led to truncated translations where sections inside code blocks were misidentified as heading boundaries.

Changes

  1. toggleFence → depth counter — Instead of toggling true/false, now tracks fence depth as an integer. Every ``` or ~~~ marker increments depth. A section is "inside a fence" when depth % 2 !== 0.

  2. fencesAreBalanced() — New helper that verifies all code fences in a translated block are properly closed (even count of markers). Blocks with unbalanced fences are rejected, preventing downstream parse errors.

  3. isClosingFence() — New helper for cleaner semantics.

  4. validateTranslatedBlock() — Now performs fence-balance validation. Blocks with unclosed fences log a warning and return false, preserving the existing content as a fallback.

  5. Applied to parseHeadingSections, parseTargetSectionsByIndex, and countH2Sections for consistency.

Background

During i18n translation, long MDX pages are split into heading-based chunks and translated individually. When a code block spanning multiple chunks had an unclosed fence in the middle, downstream parsing would swallow subsequent sections. This fix ensures fence boundaries are respected during chunk parsing and validation.

…ation

- Migrate toggleFence from bool toggle to depth counting to handle
  nested/multiple code blocks correctly.
- Add fencesAreBalanced() helper to detect unclosed code fences
  in translated blocks.
- validateTranslatedBlock rejects blocks with unbalanced fences.
- Apply to all fence-aware functions for consistency.
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

In .github/scripts/i18n/chunked-translate.ts, boolean "in-fence" flags across parseHeadingSections, parseTargetSectionsByIndex, and countH2Sections are replaced with fenceDepth counters and parity checks. Three new helpers (toggleFence, isClosingFence, fencesAreBalanced) support this. validateTranslatedBlock gains a fence-balance check.

Changes

Fence-depth Markdown parsing and validation

Layer / File(s) Summary
Fence-depth utility helpers
.github/scripts/i18n/chunked-translate.ts
Adds toggleFence, isClosingFence, and fencesAreBalanced as shared utilities for counting and checking code-fence depth — the foundation for everything else (no more fencing with booleans)!
Parsing and counting updated to depth tracking
.github/scripts/i18n/chunked-translate.ts
parseHeadingSections, parseTargetSectionsByIndex, and countH2Sections replace boolean in-fence toggles with fenceDepth counters and parity-based inFence() helpers; ## headings inside fenced blocks are no longer treated as section boundaries.
Translated block fence-balance validation
.github/scripts/i18n/chunked-translate.ts
validateTranslatedBlock now additionally rejects translated blocks with unbalanced code fences via fencesAreBalanced, logging a warning with the fence-marker count on mismatch.

Possibly related PRs

  • Comfy-Org/docs#1159: Introduced the initial heading_sections chunking implementation with code-fence handling that this PR directly extends with depth-based tracking and balance validation.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/scripts/i18n/chunked-translate.ts (1)

698-700: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Intro blocks currently hop the fence-balance gate (Line 698).

_intro returns true before the new balance check runs, so unclosed fences in intro content are still accepted. That can still swallow subsequent sections when content is re-parsed downstream.

Suggested fix
-  if (enBlock.label === "_intro") {
-    return true;
-  }
-
-  // Must start with a level-2 heading.
-  if (!/^## (?![#])/.test(translated.trimStart())) {
-    return false;
-  }
-
   // Validate code fence balance: every open fence must have a matching close.
   // Unmatched fences cause subsequent sections to be swallowed during re-parsing.
   if (!fencesAreBalanced(translated)) {
     const fenceLines = (translated.match(/^(```|~~~)/gm) || []).length;
@@
     return false;
   }
 
+  if (enBlock.label === "_intro") {
+    return true;
+  }
+
+  // Must start with a level-2 heading.
+  if (!/^## (?![#])/.test(translated.trimStart())) {
+    return false;
+  }
+
   return true;

Also applies to: 707-715

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/i18n/chunked-translate.ts around lines 698 - 700, The intro
block validation check (enBlock.label === "_intro" returning true) is executing
before the fence-balance validation runs, allowing unclosed fences to pass
validation in intro blocks. Reorder the validation logic so that the
fence-balance check and the level-2 heading validation (checking for /^##
(?![#])/.test(translated.trimStart())) both execute before the _intro block
check is evaluated. Move the _intro block check to come after these other
validation checks so that intro blocks are still subject to proper fence balance
and heading structure requirements.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/scripts/i18n/chunked-translate.ts:
- Around line 698-700: The intro block validation check (enBlock.label ===
"_intro" returning true) is executing before the fence-balance validation runs,
allowing unclosed fences to pass validation in intro blocks. Reorder the
validation logic so that the fence-balance check and the level-2 heading
validation (checking for /^## (?![#])/.test(translated.trimStart())) both
execute before the _intro block check is evaluated. Move the _intro block check
to come after these other validation checks so that intro blocks are still
subject to proper fence balance and heading structure requirements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 286ab9c2-4874-4a5c-926f-9aedd022ea57

📥 Commits

Reviewing files that changed from the base of the PR and between 1156622 and d971a6e.

📒 Files selected for processing (1)
  • .github/scripts/i18n/chunked-translate.ts

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.

1 participant