* Parse DTD declaration content with whitespace validation. * Validates that quoted strings and parenthesized groups have proper whitespace.
()
| 544 | * Validates that quoted strings and parenthesized groups have proper whitespace. |
| 545 | */ |
| 546 | function parseDTDDeclarationContent(): void { |
| 547 | let sawWhitespace = true; // Start true since we just saw whitespace after keyword |
| 548 | let parenDepth = 0; |
| 549 | |
| 550 | while (pos < len) { |
| 551 | const code = input.charCodeAt(pos); |
| 552 | |
| 553 | if (code === CC_GT && parenDepth === 0) { |
| 554 | pos++; |
| 555 | return; // End of declaration |
| 556 | } |
| 557 | |
| 558 | if (isWhitespace(code)) { |
| 559 | sawWhitespace = true; |
| 560 | pos++; |
| 561 | continue; |
| 562 | } |
| 563 | |
| 564 | if (code === CC_DQUOTE || code === CC_SQUOTE) { |
| 565 | // Quoted string - must have whitespace before (unless inside parens) |
| 566 | if (!sawWhitespace && parenDepth === 0) { |
| 567 | error("Missing whitespace before quoted string in DTD declaration"); |
| 568 | } |
| 569 | const quote = code; |
| 570 | pos++; |
| 571 | while (pos < len && input.charCodeAt(pos) !== quote) { |
| 572 | pos++; |
| 573 | } |
| 574 | if (pos >= len) { |
| 575 | error("Unterminated string in DTD declaration"); |
| 576 | } |
| 577 | pos++; |
| 578 | sawWhitespace = false; |
| 579 | continue; |
| 580 | } |
| 581 | |
| 582 | // Opening paren - must have whitespace before FIRST paren only |
| 583 | // Nested parens like ((a|b)) are valid without whitespace between them |
| 584 | if (code === CC_LPAREN) { |
| 585 | if (!sawWhitespace && parenDepth === 0) { |
| 586 | error("Missing whitespace before '(' in DTD declaration"); |
| 587 | } |
| 588 | parenDepth++; |
| 589 | sawWhitespace = false; |
| 590 | pos++; |
| 591 | continue; |
| 592 | } |
| 593 | |
| 594 | if (code === CC_RPAREN) { |
| 595 | if (parenDepth === 0) { |
| 596 | error("Unexpected ')' in DTD declaration"); |
| 597 | } |
| 598 | parenDepth--; |
| 599 | sawWhitespace = false; |
| 600 | pos++; |
| 601 | continue; |
| 602 | } |
| 603 |
no test coverage detected