Incorrect line length calculation in formatter
The formatter's MAX_TAG_OPENING_WIDTH check incorrectly calculates the rendered width of tag openings, causing it to underestimate line length by 2 characters. This results in tags being kept inline when they actually exceed the configured maximum width.
Location
File: src/formatter.ts
Line: ~230 (in the 'tag' case of formatNode)
Current Behavior
const isLongTagOpening =
inlineTag.length + open.length * 2 >
(o.maxTagOpeningWidth || MAX_TAG_OPENING_WIDTH);This calculation adds open.length * 2 (which equals 4 for open = "{%"), accounting only for the opening and closing delimiters without spaces.
The Problem
A rendered tag actually looks like this:
{% tagname attr="value" %}The overhead consists of:
- Opening:
"{% "= 3 characters - Closing:
" %}"= 3 characters - Total overhead: 6 characters
The current calculation only accounts for 4 characters, missing the two spaces.
Impact
With MAX_TAG_OPENING_WIDTH = 80:
- Current behavior: Splits when
inlineTag.length + 4 > 80, meaning inline tags up to 76 chars - Actual rendered width: Up to 82 characters (76 + 6 overhead)
- Result: Tags that render as 81-82 characters wide are kept inline, exceeding the intended 80-character limit
Example
A tag with inlineTag.length = 77:
{% if condition="some-long-value" attr="another-value" extra="more-stuff" %}- Current calculation:
77 + 4 = 81(doesn't trigger split at 80) - Actual rendered width:
77 + 6 = 83characters (exceeds 80)
Proposed Fix
Option 1: Correct the calculation
const isLongTagOpening =
inlineTag.length + open.length * 2 + 2 >
(o.maxTagOpeningWidth || MAX_TAG_OPENING_WIDTH);Option 2: More explicit (recommended)
const openTag = open + ' ';
const closeTag = ' ' + close;
const isLongTagOpening =
openTag.length + inlineTag.length + closeTag.length >
(o.maxTagOpeningWidth || MAX_TAG_OPENING_WIDTH);Backward Compatibility Note
This fix will cause some tags to split across lines that previously stayed inline (specifically tags between 75-76 characters in content length). This is technically a breaking change in formatting output, though it makes the formatter behave correctly according to the documented maxTagOpeningWidth limit.
If maintaining exact backward compatibility is required, consider changing MAX_TAG_OPENING_WIDTH to 82 instead of fixing the calculation.
Source: markdoc/markdoc