Skip to content

Commit 5aac2d8

Browse files
fix(tostring): add footnote pattern to LPeg parser for correct table column widths
The tostring module (used for table column width calculation) had no pattern for footnote references like [^1] or [^label]. These were falling through to hyperlink_no_src, which strips [ and ] but keeps the ^ character, producing a width 1 character too wide. Add a dedicated footnote LPeg pattern that: - Matches [^label] syntax (placed before hyperlink in token priority) - Strips [^ and ] delimiters (matching actual renderer behavior) - Looks up footnote config for icon/corner/padding decorations - Returns the correct visual string for width measurement This fixes misaligned table columns for rows containing footnote references.
1 parent ed989a2 commit 5aac2d8

1 file changed

Lines changed: 45 additions & 1 deletion

File tree

lua/markview/renderers/markdown/tostring.lua

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ md_str.update_cache = function ()
6262
hyperlinks = spec.get({ "markdown_inline", "hyperlinks" }, { fallback = nil }),
6363
images = spec.get({ "markdown_inline", "images" }, { fallback = nil }),
6464
inline_codes = spec.get({ "markdown_inline", "inline_codes"}, { fallback = nil }),
65+
footnotes = spec.get({ "markdown_inline", "footnotes" }, { fallback = nil }),
6566
internal_links = spec.get({ "markdown_inline", "internal_links" }, { fallback = nil }),
6667
uri_autolinks = spec.get({ "markdown_inline", "uri_autolinks" }, { fallback = nil }),
6768
};
@@ -305,6 +306,46 @@ md_str.internal = function (match)
305306
---|fE
306307
end
307308

309+
---@param match string
310+
---@return string
311+
md_str.footnote = function (match)
312+
---|fS
313+
314+
local label = string.gsub(match, "^%[%^", ""):gsub("%]$", "");
315+
316+
if md_str.cached_config and md_str.cached_config.footnotes then
317+
---@type markview.config.__inline?
318+
local config = require("markview.utils").match(md_str.cached_config.footnotes, label, {
319+
eval_args = {
320+
md_str.buffer,
321+
{
322+
class = "inline_footnote",
323+
text = { match },
324+
325+
label = label,
326+
}
327+
}
328+
});
329+
330+
if config then
331+
return table.concat({
332+
config.corner_left or "",
333+
config.padding_left or "",
334+
335+
config.icon or "",
336+
label,
337+
338+
config.padding_right or "",
339+
config.corner_right or "",
340+
}, "");
341+
end
342+
end
343+
344+
return label;
345+
346+
---|fE
347+
end
348+
308349
---@param match string
309350
---@return string
310351
md_str.escape = function (match)
@@ -629,6 +670,9 @@ local bold_italic = s_bold_italic + u_bold_italic;
629670
local code_content = lpeg.P("\\`") + ( 1 - lpeg.P("`") );
630671
local code = lpeg.C( at_valid * lpeg.P("`")^1 * code_content^1 * lpeg.P("`")^1 ) / md_str.code;
631672

673+
local footnote_label_char = lpeg.R("09", "az", "AZ") + lpeg.S("-_.");
674+
local footnote = lpeg.C( lpeg.P("[^") * footnote_label_char^1 * lpeg.P("]") ) / md_str.footnote;
675+
632676
local hyperlink_content = lpeg.P("\\]") + ( 1 - lpeg.P("]") );
633677
local hyperlink_no_src = lpeg.C( lpeg.P("[") * hyperlink_content^0 * lpeg.P("]") ) / md_str.hyperlink_no_src;
634678
-- Supports balanced parentheses in URLs per CommonMark spec §6.7:
@@ -678,7 +722,7 @@ local token = escape +
678722
emoji + entity +
679723
hl + block_ref + embed + internal +
680724
email + auto +
681-
img + hyperlink +
725+
footnote + img + hyperlink +
682726
code +
683727
bold_italic + bold + italic +
684728
any;

0 commit comments

Comments
 (0)