* Count lines of code in a block's content.
(block: DeepnoteBlock)
| 661 | * Count lines of code in a block's content. |
| 662 | */ |
| 663 | function countLinesOfCode(block: DeepnoteBlock): number { |
| 664 | if (!('content' in block) || typeof block.content !== 'string' || !block.content) { |
| 665 | return 0 |
| 666 | } |
| 667 | |
| 668 | const content = block.content.trim() |
| 669 | if (!content) { |
| 670 | return 0 |
| 671 | } |
| 672 | |
| 673 | // For SQL blocks, only use -- as comment marker |
| 674 | if (block.type === 'sql') { |
| 675 | const lines = content.split('\n') |
| 676 | let loc = 0 |
| 677 | for (const line of lines) { |
| 678 | const trimmed = line.trim() |
| 679 | if (trimmed && !trimmed.startsWith('--')) { |
| 680 | loc++ |
| 681 | } |
| 682 | } |
| 683 | return loc |
| 684 | } |
| 685 | |
| 686 | // For Python code blocks, exclude # comments and triple-quoted strings/docstrings |
| 687 | if (block.type === 'code') { |
| 688 | const lines = content.split('\n') |
| 689 | let loc = 0 |
| 690 | let inMultilineString = false |
| 691 | let multilineDelimiter = '' |
| 692 | |
| 693 | for (const line of lines) { |
| 694 | const trimmed = line.trim() |
| 695 | |
| 696 | if (inMultilineString) { |
| 697 | if (trimmed.includes(multilineDelimiter)) { |
| 698 | inMultilineString = false |
| 699 | multilineDelimiter = '' |
| 700 | } |
| 701 | continue |
| 702 | } |
| 703 | |
| 704 | if (trimmed.startsWith('"""') || trimmed.startsWith("'''")) { |
| 705 | const delimiter = trimmed.startsWith('"""') ? '"""' : "'''" |
| 706 | const afterOpening = trimmed.slice(3) |
| 707 | if (!afterOpening.includes(delimiter)) { |
| 708 | inMultilineString = true |
| 709 | multilineDelimiter = delimiter |
| 710 | } |
| 711 | continue |
| 712 | } |
| 713 | |
| 714 | if (trimmed && !trimmed.startsWith('#')) { |
| 715 | loc++ |
| 716 | } |
| 717 | } |
| 718 | return loc |
| 719 | } |
| 720 |