@@ -72,14 +72,17 @@ local function create_latex_source(snippet, is_inline)
7272 or (module .config .public .font_size_block or " \\ Large" )
7373
7474 if is_inline then
75- content = string.gsub (content , " ^%$|" , " " )
76- content = string.gsub (content , " |%$$" , " " )
77-
78- -- --- FIX #1: ENSURE PROPER DISPLAY MATH ENVIRONMENT ---
79- -- Wrap content in \[ ... \] to force display math mode, mirroring snacks.nvim's
80- -- robust behavior and preventing typesetting errors.
81- if not content :find (" \\ begin" ) then
82- content = " \\ [" .. content .. " \\ ]"
75+ -- Remove leading $| and trailing |$ exactly
76+ content = content :gsub (" ^%$%|" , " " ) -- strip leading "$|"
77+ content = content :gsub (" %|%$$" , " " ) -- strip trailing "|$"
78+
79+ -- If user wrote plain $ ... $ or left stray $ markers, also strip them
80+ content = content :gsub (" ^%$" , " " ) -- leading single $
81+ content = content :gsub (" %$$" , " " ) -- trailing single $
82+
83+ -- If content doesn't already look like a math environment, wrap it robustly.
84+ if not content :find (" \\ begin" ) and not content :match (" ^\\\\ %(" ) and not content :match (" ^%$" ) then
85+ content = " \\ (" .. content .. " \\ )"
8386 end
8487 end
8588
@@ -98,6 +101,32 @@ local function create_latex_source(snippet, is_inline)
98101 return template :gsub (" ${color}" , fg_hex ):gsub (" ${content}" , content )
99102end
100103
104+ -- --- NEW AND IMPROVED DEBUG WRITER ---
105+ -- This function ALWAYS overwrites the cached .tex file to prevent stale-cache issues.
106+ -- It also includes robust checks for empty content or unbalanced braces.
107+ local function write_tex_file_with_debug (tex_source , snippet , tex_file )
108+ -- If tex_source is empty -> warn and still write for inspection
109+ if not tex_source :find (" %S" ) then
110+ vim .notify (" Neorg LaTeX: EMPTY tex source for snippet: " .. vim .inspect (snippet ), vim .log .levels .WARN )
111+ end
112+
113+ -- Sanity check: balanced braces
114+ local opens = select (2 , tex_source :gsub (" {" , " " ))
115+ local closes = select (2 , tex_source :gsub (" }" , " " ))
116+ if opens ~= closes then
117+ vim .notify (
118+ (" Neorg LaTeX: UNBALANCED braces (%d vs %d). Writing debug tex for inspection." ):format (opens , closes ),
119+ vim .log .levels .WARN
120+ )
121+ local debug_file = module .private .cache_dir .. " debug-" .. (vim .fn .strftime (" %s" )) .. " .tex"
122+ vim .fn .writefile (vim .split (tex_source , " \n " ), debug_file )
123+ vim .notify (" Wrote debug tex: " .. debug_file , vim .log .levels .INFO )
124+ end
125+
126+ -- ALWAYS overwrite so we don't keep stale/malformed files
127+ vim .fn .writefile (vim .split (tex_source , " \n " ), tex_file )
128+ end
129+
101130module .load = function ()
102131 local snacks_ok , snacks_placement = pcall (require , " snacks.image.placement" )
103132 if not snacks_ok then
@@ -106,24 +135,14 @@ module.load = function()
106135 end
107136 placement = snacks_placement
108137
109- -- --- FIX #2: REMOVE THE AGGRESSIVE INLINE COLLAPSE MONKEY-PATCH ---
110- -- The original patch forced multi-line fractions into a single row, causing
111- -- visual distortion. By removing it, we allow snacks.nvim's default, correct
112- -- rendering to take over.
113- -- (The empty `do ... end` block below is intentional; we are no longer patching `placement:state`)
114- do
115- -- No-op: The problematic monkey-patch has been removed.
116- end
117-
118- -- Use snacks.nvim's high-density strategy for crisp, correctly-sized images.
119138 local read_density = 192
120139 local magick_args = {
121140 " -density" ,
122141 read_density ,
123- " {src}[0]" , -- Rasterize first page of PDF
142+ " {src}[0]" ,
124143 " -background" ,
125- " none" , -- Use transparent background for inline math
126- " -trim" , -- Remove whitespace
144+ " none" ,
145+ " -trim" ,
127146 " -alpha" ,
128147 " remove" ,
129148 }
@@ -143,6 +162,7 @@ module.load = function()
143162 module .required [" core.autocommands" ].enable_autocommand (" BufWinEnter" )
144163 module .required [" core.autocommands" ].enable_autocommand (" CursorMoved" )
145164 module .required [" core.autocommands" ].enable_autocommand (" TextChanged" )
165+ module .required [" core.autocommands" ].enable_autocommand (" TextChangedI" )
146166 module .required [" core.autocommands" ].enable_autocommand (" InsertLeave" )
147167 module .required [" core.autocommands" ].enable_autocommand (" Colorscheme" )
148168
@@ -182,11 +202,9 @@ function module.private.update_placements(buf)
182202 local current_placements = module .private .placements [buf ] or {}
183203 module .private .placements [buf ] = current_placements
184204
185- -- First, handle inline math with Treesitter for performance and accuracy
186205 module .required [" core.integrations.treesitter" ].execute_query (
187206 [[
188207 (inline_math) @latex.inline
189- (#offset! @latex.inline 0 1 0 -1)
190208 ]] ,
191209 function (query , id , node )
192210 local node_id = tostring (node :id ())
@@ -196,7 +214,9 @@ function module.private.update_placements(buf)
196214 return
197215 end
198216
199- local snippet = module .required [" core.integrations.treesitter" ].get_node_text (node , buf )
217+ local snippet =
218+ module .required [" core.integrations.treesitter" ].get_node_text (node , buf , { metadata = true })
219+
200220 if # snippet < module .config .public .min_length then
201221 return
202222 end
@@ -205,9 +225,8 @@ function module.private.update_placements(buf)
205225 local source_hash = vim .fn .sha256 (tex_source )
206226 local tex_file = module .private .cache_dir .. source_hash :sub (1 , 12 ) .. " .tex"
207227
208- if vim .fn .filereadable (tex_file ) == 0 then
209- vim .fn .writefile (vim .split (tex_source , " \n " ), tex_file )
210- end
228+ -- Use the new debug-aware writer function that always overwrites
229+ write_tex_file_with_debug (tex_source , snippet , tex_file )
211230
212231 local range = { node :range () }
213232 local pos = { range [1 ] + 1 , range [2 ] }
@@ -230,7 +249,7 @@ function module.private.update_placements(buf)
230249 buf
231250 )
232251
233- -- Second, handle @math blocks by manually parsing lines for robustness.
252+ -- Handle @math blocks
234253 local lines = vim .api .nvim_buf_get_lines (buf , 0 , - 1 , false )
235254 local i = 1
236255 while i <= # lines do
@@ -262,9 +281,8 @@ function module.private.update_placements(buf)
262281 local source_hash = vim .fn .sha256 (tex_source )
263282 local tex_file = module .private .cache_dir .. source_hash :sub (1 , 12 ) .. " .tex"
264283
265- if vim .fn .filereadable (tex_file ) == 0 then
266- vim .fn .writefile (vim .split (tex_source , " \n " ), tex_file )
267- end
284+ -- Use the new debug-aware writer function that always overwrites
285+ write_tex_file_with_debug (tex_source , snippet , tex_file )
268286
269287 local full_range = { start_line + 1 , 0 , end_line + 1 , # lines [end_line ] }
270288
@@ -291,7 +309,7 @@ function module.private.update_placements(buf)
291309 end
292310 end
293311
294- -- Finally, clean up any stale placements
312+ -- Clean up stale placements
295313 for node_id , p in pairs (current_placements ) do
296314 if not active_nodes [node_id ] then
297315 p :close ()
@@ -363,7 +381,9 @@ local function show_all_placements(buf)
363381 p :show ()
364382 end
365383 end
366- module .private .hidden_by_cursor [buf ] = {}
384+ if module .private .hidden_by_cursor [buf ] then
385+ module .private .hidden_by_cursor [buf ] = {}
386+ end
367387end
368388
369389local function disable_rendering ()
@@ -418,6 +438,7 @@ local event_handlers = {
418438 end ,
419439 [" core.autocommands.events.cursormoved" ] = clear_at_cursor ,
420440 [" core.autocommands.events.textchanged" ] = render_latex ,
441+ [" core.autocommands.events.textchangedi" ] = render_latex ,
421442 [" core.autocommands.events.insertleave" ] = render_latex ,
422443 [" core.autocommands.events.colorscheme" ] = colorscheme_change ,
423444}
@@ -444,6 +465,7 @@ module.events.subscribed = {
444465 bufwinenter = true ,
445466 cursormoved = true ,
446467 textchanged = true ,
468+ textchangedi = true ,
447469 insertleave = true ,
448470 colorscheme = true ,
449471 },
0 commit comments