A line-by-line indentation formatter is conceptually simple: track a indentLevel counter, increment it when you see an opening bracket or block start, decrement it when you see a closing bracket or block end, and prefix each line with indentLevel × indentSize spaces.

The first edge case that breaks this simple model: block comments.

The problem

Consider this CSS:

.container {
  display: flex;
  /*
   * This is a multi-line
   * block comment
   */
  flex-direction: column;
}

On the line .container {, indent level goes from 0 to 1. Every subsequent line should be at indent level 1. But the comment lines don't contain brackets — they should just be printed at the current indent level without being processed for bracket changes.

If your formatter processes * at the start of a line as a closing bracket candidate (some grammars use * in patterns), or if the closing */ is accidentally counted as two characters that change indent — you get misformatted output.

The solution: stateful tracking

mkhCodeFormatter maintains two variables across the entire forEach line loop:

  • inBlockComment: boolean — whether the current line is inside an open block comment
  • blockCommentType: 'css' | 'html' | null — to know which closing delimiter to watch for

For each line, before any bracket or directive logic runs:

if (inBlockComment) {
  isThisLineAComment = true;
  if (blockCommentType === 'html' && trimmedLine.includes('-->')) {
    inBlockComment = false;
  } else if (blockCommentType === 'css' && trimmedLine.includes('*/')) {
    inBlockComment = false;
  }
} else {
  if (trimmedLine.startsWith('/*') || trimmedLine.startsWith('/**')) {
    isThisLineAComment = true;
    if (!trimmedLine.includes('*/')) {  // multi-line block, not self-closing
      inBlockComment = true;
      blockCommentType = 'css';
    }
  } else if (trimmedLine.startsWith('<!--')) {
    isThisLineAComment = true;
    if (!trimmedLine.includes('-->')) {
      inBlockComment = true;
      blockCommentType = 'html';
    }
  } else if (trimmedLine.startsWith('//') || trimmedLine.startsWith('#') || trimmedLine.startsWith('*')) {
    isThisLineAComment = true;
  }
}

If isThisLineAComment is true, the line is indented at the current level (with a special +1 space offset for JSDoc * continuation lines) and the loop continues to the next line — no bracket counting, no directive detection.

The JSDoc +1 offset

JSDoc * continuation lines inside a /** */ block conventionally align with the * of the opening /** — which is one character after the indent:

/**        ← indent level 1 (2 spaces)
 * text    ← indent level 1 + 1 space = 3 spaces
 */        ← indent level 1 + 1 space = 3 spaces

This is handled by adding 1 to the space count when the trimmed line starts with * but not with /*:

if (trimmedLine.startsWith('*') && !trimmedLine.startsWith('/*')) {
  indentSpaceCount += 1;
}

---

Mustafa Kamal Hossain

Mustafa Kamal Hossain

Founder & Principal Engineer at Manfi. Passionate about Laravel, SaaS architecture, and high-performance engineering.