Environment
- image.nvim:
88351f1 (latest master)
- Neovim:
v0.12.3
- ImageMagick:
7.1.2-26 CLI (magick_cli processor)
- librsvg / rsvg-convert:
2.62.3 (installed, configured as ImageMagick SVG delegate)
- OS: macOS 26.5.1 (Apple Silicon, Darwin 25.5.0)
What happens
Opening a markdown file that embeds mermaid-generated SVGs (produced by @mermaid-js/mermaid-cli) triggers repeated error notifications at convert_to_png:
Lua callback:
...nvim/lazy/image.nvim/lua/image/processors/magick_cli.lua:76: magick: non-conforming drawing primitive definition `stroke-dasharray' @ error/draw.c/RenderMVGContent/4661.
stack traceback:
[C]: in function 'error'
...processors/magick_cli.lua:76: in function <...processors/magick_cli.lua:75>
[C]: in function 'wait'
...processors/magick_cli.lua:85: in function 'convert_to_png'
...lazy/image.nvim/lua/image/image.lua:326: in function <...>
[C]: in function 'pcall'
...image.nvim/lua/image/utils/document.lua:202: in function 'fn'
Different mermaid diagrams surface different symptoms from the same coder:
- Flowchart with any dashed edge →
non-conforming drawing primitive 'stroke-dasharray'
- Diagrams with default text styles →
unable to read font '' @ error/annotate.c/RenderFreetype/1665
Root cause
Default mmdc output contains CSS that ImageMagick's built-in MSVG coder cannot parse:
stroke-dasharray:9,5!important — the MSVG coder does not understand CSS's !important modifier and rejects the whole primitive
font-family: with an empty value — the MSVG coder passes the empty string to FreeType
convert_to_png in magick_cli.lua spawns magick <path> png:<out> unconditionally. Even when the ImageMagick SVG delegate points at rsvg-convert, ImageMagick 7 (at least the Homebrew build without pango/wmf) still selects its internal MSVG coder for these SVGs, so the delegate never runs.
rsvg-convert handles the exact same SVGs without any problem.
Reproduce without Neovim
mkdir -p /tmp/msvg-repro && cd /tmp/msvg-repro
cat > flow.mmd <<'MMD'
flowchart LR
A -.-> B
B --> C
MMD
npx --yes @mermaid-js/mermaid-cli -i flow.mmd -o flow.svg
magick flow.svg /tmp/out.png
# → magick: non-conforming drawing primitive definition `stroke-dasharray' @ error/draw.c/RenderMVGContent/4661.
rsvg-convert flow.svg -o /tmp/out.png # ← works, produces a valid PNG
Proposal
For SVG inputs, prefer rsvg-convert (when available) over magick <svg> png:<out>. This is symmetrical to the fix suggested in #370 for identify — same underlying issue (ImageMagick's internal SVG coder is unreliable), different call site.
A user-side workaround that avoids any upstream change is possible today via the existing integrations.markdown.resolve_image_path hook — pre-convert SVGs with rsvg-convert into a cached PNG and hand the PNG path to image.nvim:
integrations = {
markdown = {
resolve_image_path = function(document_path, image_url, fallback)
if image_url:sub(1, 10) == 'data:image' then
-- (reproduce the base64 branch that resolve_image_path bypasses)
...
end
local path = fallback(document_path, image_url)
if type(path) ~= 'string' then return path end
if path:lower():match('%.svg$') and vim.fn.executable('rsvg-convert') == 1 then
local stat = vim.uv.fs_stat(path)
if not stat then return path end
local cache_dir = vim.fn.stdpath('cache') .. '/image_nvim_svg'
vim.fn.mkdir(cache_dir, 'p')
local key = vim.fn.sha256(path .. ':' .. tostring(stat.mtime.sec))
local png = cache_dir .. '/' .. key .. '.png'
if vim.uv.fs_stat(png) == nil then
vim.fn.system({ 'rsvg-convert', path, '-o', png })
if vim.v.shell_error ~= 0 then return path end
end
return png
end
return path
end,
},
},
I confirmed this eliminates the crash on the same mermaid SVGs. A similar branch inside magick_cli.convert_to_png (detect .svg → shell out to rsvg-convert when present, fall back to magick) would fix it for all users without configuration.
Related
Report drafted with Claude Code; issue is real and reproducible with the commands above.
Environment
88351f1(latest master)v0.12.37.1.2-26CLI (magick_cliprocessor)2.62.3(installed, configured as ImageMagick SVG delegate)What happens
Opening a markdown file that embeds mermaid-generated SVGs (produced by
@mermaid-js/mermaid-cli) triggers repeated error notifications atconvert_to_png:Different mermaid diagrams surface different symptoms from the same coder:
non-conforming drawing primitive 'stroke-dasharray'unable to read font '' @ error/annotate.c/RenderFreetype/1665Root cause
Default
mmdcoutput contains CSS that ImageMagick's built-in MSVG coder cannot parse:stroke-dasharray:9,5!important— the MSVG coder does not understand CSS's!importantmodifier and rejects the whole primitivefont-family:with an empty value — the MSVG coder passes the empty string to FreeTypeconvert_to_pnginmagick_cli.luaspawnsmagick <path> png:<out>unconditionally. Even when the ImageMagick SVG delegate points atrsvg-convert, ImageMagick 7 (at least the Homebrew build without pango/wmf) still selects its internal MSVG coder for these SVGs, so the delegate never runs.rsvg-converthandles the exact same SVGs without any problem.Reproduce without Neovim
Proposal
For SVG inputs, prefer
rsvg-convert(when available) overmagick <svg> png:<out>. This is symmetrical to the fix suggested in #370 foridentify— same underlying issue (ImageMagick's internal SVG coder is unreliable), different call site.A user-side workaround that avoids any upstream change is possible today via the existing
integrations.markdown.resolve_image_pathhook — pre-convert SVGs withrsvg-convertinto a cached PNG and hand the PNG path to image.nvim:I confirmed this eliminates the crash on the same mermaid SVGs. A similar branch inside
magick_cli.convert_to_png(detect.svg→ shell out torsvg-convertwhen present, fall back tomagick) would fix it for all users without configuration.Related
convert_to_pngvsidentify).Report drafted with Claude Code; issue is real and reproducible with the commands above.