Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions javascript/packages/formatter/src/format-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface ContentUnit {
type: 'text' | 'inline' | 'erb' | 'block'
isAtomic: boolean
breaksFlow: boolean
isHerbDisable?: boolean
}

/**
Expand Down Expand Up @@ -147,6 +148,34 @@ export function filterEmptyNodes(nodes: Node[]): Node[] {
)
}

/**
* Smart filter that preserves exactly ONE whitespace before herb:disable comments
*/
export function filterEmptyNodesForHerbDisable(nodes: Node[]): Node[] {
const result: Node[] = []
let pendingWhitespace: Node | null = null

for (const node of nodes) {
const isWhitespace = isNode(node, WhitespaceNode) || (isNode(node, HTMLTextNode) && node.content.trim() === "")
const isHerbDisable = isNode(node, ERBContentNode) && isHerbDisableComment(node)

if (isWhitespace) {
if (!pendingWhitespace) {
pendingWhitespace = node
}
} else {
if (isHerbDisable && pendingWhitespace) {
result.push(pendingWhitespace)
}

pendingWhitespace = null
result.push(node)
}
}

return result
}

// --- Punctuation and Word Spacing Functions ---

/**
Expand Down Expand Up @@ -473,3 +502,16 @@ export function endsWithAlphanumeric(text: string): boolean {
export function endsWithWhitespace(text: string): boolean {
return /\s$/.test(text)
}

/**
* Check if an ERB content node is a herb:disable comment
*/
export function isHerbDisableComment(node: Node): boolean {
if (!isNode(node, ERBContentNode)) return false
if (node.tag_opening?.value !== "<%#") return false

const content = node?.content?.value || ""
const trimmed = content.trim()

return trimmed.startsWith("herb:disable")
}
Loading
Loading