Skip to content

Commit 2c6cf12

Browse files
feat: remove delimiters around latex text before converting
## Details Remove non-latex delimiters around latex text to help converters produce more correct outputs. For example in the demo: ``` $$ f(x,y) = x + \sqrt{y} f(x,y) = \sqrt{y} + \frac{x^2}{4y} $$ ``` The difference in the input to the converter is: - before: `$$\nf(x,y) = x + \\sqrt{y}\nf(x,y) = \\sqrt{y} + \\frac{x^2}{4y}\n$$` - after: `f(x,y) = x + \\sqrt{y}\nf(x,y) = \\sqrt{y} + \\frac{x^2}{4y}` Minor other change, move sorting of nodes into row level chunks into the main latex handler rather than being part of the request context.
1 parent b4885a9 commit 2c6cf12

File tree

5 files changed

+52
-43
lines changed

5 files changed

+52
-43
lines changed

doc/render-markdown.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For NVIM v0.11.4 Last change: 2025 September 11
1+
*render-markdown.txt* For NVIM v0.11.4 Last change: 2025 September 14
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*

lua/render-markdown/handler/latex.lua

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,24 @@ function Handler:run(root, last)
4242
log.node('latex', node)
4343
self.context.latex:add(node)
4444
if last then
45-
local rows = self.context.latex:get()
46-
self:convert(rows)
47-
for _, nodes in ipairs(rows) do
48-
self:render(nodes)
45+
local nodes = self.context.latex:get()
46+
self:convert(nodes)
47+
for _, row in ipairs(self:rows(nodes)) do
48+
self:render(row)
4949
end
5050
end
5151
return self.marks:get()
5252
end
5353

5454
---@private
55-
---@param rows render.md.Node[][]
56-
function Handler:convert(rows)
55+
---@param nodes render.md.Node[]
56+
function Handler:convert(nodes)
5757
local cmd = self.config.converter
5858
local inputs = {} ---@type string[]
59-
for _, nodes in ipairs(rows) do
60-
for _, node in ipairs(nodes) do
61-
local text = node.text
62-
local new = not Handler.cache[text]
63-
local unique = not vim.tbl_contains(inputs, text)
64-
if new and unique then
65-
inputs[#inputs + 1] = text
66-
end
59+
for _, node in ipairs(nodes) do
60+
local text = Handler.text(node)
61+
if not Handler.cache[text] and not vim.tbl_contains(inputs, text) then
62+
inputs[#inputs + 1] = text
6763
end
6864
end
6965
if vim.system then
@@ -92,6 +88,24 @@ function Handler:convert(rows)
9288
end
9389
end
9490

91+
---@private
92+
---@param nodes render.md.Node[]
93+
---@return render.md.Node[][]
94+
function Handler:rows(nodes)
95+
table.sort(nodes)
96+
local result = {} ---@type render.md.Node[][]
97+
result[#result + 1] = { nodes[1] }
98+
for i = 2, #nodes do
99+
local node, last = nodes[i], result[#result]
100+
if node.start_row == last[#last].start_row then
101+
last[#last + 1] = node
102+
else
103+
result[#result + 1] = { node }
104+
end
105+
end
106+
return result
107+
end
108+
95109
---@private
96110
---@param nodes render.md.Node[]
97111
function Handler:render(nodes)
@@ -100,7 +114,7 @@ function Handler:render(nodes)
100114
local _, line = first:line('first', 0)
101115

102116
for _, node in ipairs(nodes) do
103-
local output = str.split(Handler.cache[node.text], '\n', true)
117+
local output = str.split(Handler.cache[Handler.text(node)], '\n', true)
104118
if self.config.virtual or #output > 1 then
105119
local col = node.start_col
106120
local prefix = str.pad(line and str.width(line:sub(1, col)) or col)
@@ -156,6 +170,14 @@ function Handler:indent(node)
156170
end
157171
end
158172

173+
---@private
174+
---@param node render.md.Node
175+
---@return string
176+
function Handler.text(node)
177+
local s = node.text
178+
return vim.trim(s:match('^%$*(.-)%$*$') or s)
179+
end
180+
159181
---@class render.md.handler.Latex: render.md.Handler
160182
local M = {}
161183

lua/render-markdown/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local state = require('render-markdown.state')
55
local M = {}
66

77
---@private
8-
M.version = '8.8.4'
8+
M.version = '8.8.5'
99

1010
function M.check()
1111
M.start('versions')

lua/render-markdown/request/latex.lua

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,9 @@ function Latex:add(node)
1515
self.nodes[#self.nodes + 1] = node
1616
end
1717

18-
---@return render.md.Node[][]
18+
---@return render.md.Node[]
1919
function Latex:get()
20-
table.sort(self.nodes)
21-
local result = {} ---@type render.md.Node[][]
22-
result[#result + 1] = { self.nodes[1] }
23-
for i = 2, #self.nodes do
24-
local node, last = self.nodes[i], result[#result]
25-
if node.start_row == last[#last].start_row then
26-
last[#last + 1] = node
27-
else
28-
result[#result + 1] = { node }
29-
end
30-
end
31-
return result
20+
return self.nodes
3221
end
3322

3423
return Latex

tests/latex_spec.lua

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,31 @@
33
local util = require('tests.util')
44

55
---@param lines string[]
6-
---@param prefix string
7-
---@param suffix string
86
---@return string
9-
local function text(lines, prefix, suffix)
10-
return prefix .. table.concat(lines, '\n') .. suffix
7+
local function join(lines)
8+
return table.concat(lines, '\n')
119
end
1210

1311
describe('latex.md', function()
1412
it('default', function()
1513
local inline = {
16-
raw = { '$\\sqrt{3x-1}+(1+x)^2$' },
17-
out = { '√(3x-1)+(1+x)^2' },
14+
raw = '\\sqrt{3x-1}+(1+x)^2',
15+
out = '√(3x-1)+(1+x)^2',
1816
}
1917
local block = {
2018
raw = {
2119
'f(x,y) = x + \\sqrt{y}',
2220
'f(x,y) = \\sqrt{y} + \\frac{x^2}{4y}',
2321
},
2422
out = {
25-
' f(x,y) = x + √(y)',
26-
' f(x,y) = √(y) + x^2/4y',
23+
'f(x,y) = x + √(y)',
24+
'f(x,y) = √(y) + x^2/4y',
2725
},
2826
}
2927

3028
util.system.mock('latex2text', {
31-
[text(inline.raw, '', '')] = text(inline.out, '', '\n'),
32-
[text(block.raw, '$$\n', '\n$$')] = text(block.out, '\n', '\n\n'),
29+
[inline.raw] = inline.out .. '\n',
30+
[join(block.raw)] = join(block.out) .. '\n',
3331
})
3432
util.setup.file('demo/latex.md')
3533

@@ -40,14 +38,14 @@ describe('latex.md', function()
4038
marks:add(row:get(0, 1), { 0, 0 }, util.heading.bg(1))
4139

4240
marks:add(row:get(1, 0), { 0, 21 }, {
43-
virt_text = { { inline.out[1], 'RmMath' } },
41+
virt_text = { { inline.out, 'RmMath' } },
4442
virt_text_pos = 'inline',
4543
conceal = '',
4644
})
4745
marks:add(row:get(2), 0, {
4846
virt_lines = vim.iter(block.out)
4947
:map(function(line)
50-
return { { line .. (' '):rep(28 - #line), 'RmMath' } }
48+
return { { line .. (' '):rep(24 - #line), 'RmMath' } }
5149
end)
5250
:totable(),
5351
virt_lines_above = true,
@@ -56,7 +54,7 @@ describe('latex.md', function()
5654
util.assert_view(marks, {
5755
'󰫎 󰲡 LaTeX',
5856
'',
59-
' ' .. inline.out[1],
57+
' ' .. inline.out,
6058
'',
6159
' ' .. block.out[1],
6260
' ' .. block.out[2],

0 commit comments

Comments
 (0)