inlineCodeRanges returns half-open `[start, end)` byte ranges that cover every inline-code span in `content`, skipping over the fenced regions caller has already identified. CommonMark §6.1: an inline-code span is opened by a run of N consecutive backticks and CLOSED by the next run of EXACTLY N co
(content string, fenced [][2]int)
| 338 | // is treated as literal text, not the start of a multi-line span. |
| 339 | // Matches CommonMark behavior closely enough for our use. |
| 340 | func inlineCodeRanges(content string, fenced [][2]int) [][2]int { |
| 341 | var ranges [][2]int |
| 342 | i := 0 |
| 343 | n := len(content) |
| 344 | fi := 0 // cursor into fenced ranges |
| 345 | for i < n { |
| 346 | // Skip ahead past any fenced range that contains or |
| 347 | // precedes our cursor. |
| 348 | for fi < len(fenced) && fenced[fi][1] <= i { |
| 349 | fi++ |
| 350 | } |
| 351 | if fi < len(fenced) && fenced[fi][0] <= i { |
| 352 | i = fenced[fi][1] |
| 353 | fi++ |
| 354 | continue |
| 355 | } |
| 356 | // Look for the next backtick. |
| 357 | b := strings.IndexByte(content[i:], '`') |
| 358 | if b < 0 { |
| 359 | return ranges |
| 360 | } |
| 361 | openStart := i + b |
| 362 | // If the backtick is inside a fenced range, skip past it. |
| 363 | if fi < len(fenced) && fenced[fi][0] <= openStart && openStart < fenced[fi][1] { |
| 364 | i = fenced[fi][1] |
| 365 | fi++ |
| 366 | continue |
| 367 | } |
| 368 | // Count the opener's backtick run. |
| 369 | j := openStart + 1 |
| 370 | for j < n && content[j] == '`' { |
| 371 | j++ |
| 372 | } |
| 373 | openLen := j - openStart |
| 374 | // Scan for a closing backtick RUN of EXACTLY `openLen` |
| 375 | // backticks. CommonMark §6.1 allows code spans to cross |
| 376 | // single newlines BUT a blank line (a line containing only |
| 377 | // whitespace) ends the enclosing paragraph and therefore |
| 378 | // terminates the span. We allow single-line wraps but break |
| 379 | // on blank lines — Codex round-9 P1. |
| 380 | closerStart := -1 |
| 381 | closerEnd := -1 |
| 382 | k := j |
| 383 | for k < n { |
| 384 | if content[k] == '\n' { |
| 385 | // Look at the next line: if it's blank |
| 386 | // (only whitespace before the next newline |
| 387 | // or EOF), the span ends here unmatched. |
| 388 | if isBlankLineAt(content, k+1, n) { |
| 389 | break |
| 390 | } |
| 391 | k++ |
| 392 | continue |
| 393 | } |
| 394 | if content[k] != '`' { |
| 395 | k++ |
| 396 | continue |
| 397 | } |
no test coverage detected