mirror of
https://github.com/neovim/neovim
synced 2025-07-16 17:21:49 +00:00
fix(tohtml): enclose font-family names in quotation marks
Font-family names must be enclosed in quotation marks to ensure that fonts are applied correctly when there are spaces in the name. Fix an issue where multiple fonts specified in `vim.o.guifont` are inserted as a single element, treating them as a single font. Support for escaping commas with backslash and ignoring spaces after a comma. ref `:help 'guifont'`
This commit is contained in:
committed by
Justin M. Keyes
parent
b40ec083ae
commit
e37404f7fe
@ -1293,9 +1293,25 @@ local function opt_to_global_state(opt, title)
|
|||||||
local fonts = {}
|
local fonts = {}
|
||||||
if opt.font then
|
if opt.font then
|
||||||
fonts = type(opt.font) == 'string' and { opt.font } or opt.font --[[@as (string[])]]
|
fonts = type(opt.font) == 'string' and { opt.font } or opt.font --[[@as (string[])]]
|
||||||
|
for i, v in pairs(fonts) do
|
||||||
|
fonts[i] = ('"%s"'):format(v)
|
||||||
|
end
|
||||||
elseif vim.o.guifont:match('^[^:]+') then
|
elseif vim.o.guifont:match('^[^:]+') then
|
||||||
table.insert(fonts, vim.o.guifont:match('^[^:]+'))
|
-- Example:
|
||||||
|
-- Input: "Font,Escape\,comma, Ignore space after comma"
|
||||||
|
-- Output: { "Font","Escape,comma","Ignore space after comma" }
|
||||||
|
local prev = ''
|
||||||
|
for name in vim.gsplit(vim.o.guifont:match('^[^:]+'), ',', { trimempty = true }) do
|
||||||
|
if vim.endswith(name, '\\') then
|
||||||
|
prev = prev .. vim.trim(name:sub(1, -2) .. ',')
|
||||||
|
elseif vim.trim(name) ~= '' then
|
||||||
|
table.insert(fonts, ('"%s%s"'):format(prev, vim.trim(name)))
|
||||||
|
prev = ''
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
-- Generic family names (monospace here) must not be quoted
|
||||||
|
-- because the browser recognizes them as font families.
|
||||||
table.insert(fonts, 'monospace')
|
table.insert(fonts, 'monospace')
|
||||||
--- @type vim.tohtml.state.global
|
--- @type vim.tohtml.state.global
|
||||||
local state = {
|
local state = {
|
||||||
|
@ -136,6 +136,53 @@ local function run_tohtml_and_assert(screen, func)
|
|||||||
screen:expect({ grid = expected.grid, attr_ids = expected.attr_ids })
|
screen:expect({ grid = expected.grid, attr_ids = expected.attr_ids })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param guifont boolean
|
||||||
|
local function test_generates_html(guifont)
|
||||||
|
insert([[line]])
|
||||||
|
exec('set termguicolors')
|
||||||
|
local bg = fn.synIDattr(fn.hlID('Normal'), 'bg#', 'gui')
|
||||||
|
local fg = fn.synIDattr(fn.hlID('Normal'), 'fg#', 'gui')
|
||||||
|
if guifont then
|
||||||
|
exec_lua [[
|
||||||
|
vim.o.guifont="Font,Escape\\,comma, Ignore space after comma"
|
||||||
|
local outfile = vim.fn.tempname() .. '.html'
|
||||||
|
local html = require('tohtml').tohtml(0,{title="title"})
|
||||||
|
vim.fn.writefile(html, outfile)
|
||||||
|
vim.cmd.split(outfile)
|
||||||
|
]]
|
||||||
|
else
|
||||||
|
exec_lua [[
|
||||||
|
local outfile = vim.fn.tempname() .. '.html'
|
||||||
|
local html = require('tohtml').tohtml(0,{title="title",font={ "dumyfont","anotherfont" }})
|
||||||
|
vim.fn.writefile(html, outfile)
|
||||||
|
vim.cmd.split(outfile)
|
||||||
|
]]
|
||||||
|
end
|
||||||
|
local out_file = api.nvim_buf_get_name(api.nvim_get_current_buf())
|
||||||
|
eq({
|
||||||
|
'<!DOCTYPE html>',
|
||||||
|
'<html>',
|
||||||
|
'<head>',
|
||||||
|
'<meta charset="UTF-8">',
|
||||||
|
'<title>title</title>',
|
||||||
|
('<meta name="colorscheme" content="%s"></meta>'):format(api.nvim_get_var('colors_name')),
|
||||||
|
'<style>',
|
||||||
|
('* {font-family: %s,monospace}'):format(
|
||||||
|
guifont and '"Font","Escape,comma","Ignore space after comma"' or '"dumyfont","anotherfont"'
|
||||||
|
),
|
||||||
|
('body {background-color: %s; color: %s}'):format(bg, fg),
|
||||||
|
'</style>',
|
||||||
|
'</head>',
|
||||||
|
'<body style="display: flex">',
|
||||||
|
'<pre>',
|
||||||
|
'line',
|
||||||
|
'',
|
||||||
|
'</pre>',
|
||||||
|
'</body>',
|
||||||
|
'</html>',
|
||||||
|
}, fn.readfile(out_file))
|
||||||
|
end
|
||||||
|
|
||||||
describe(':TOhtml', function()
|
describe(':TOhtml', function()
|
||||||
--- @type test.functional.ui.screen
|
--- @type test.functional.ui.screen
|
||||||
local screen
|
local screen
|
||||||
@ -146,38 +193,12 @@ describe(':TOhtml', function()
|
|||||||
exec('colorscheme default')
|
exec('colorscheme default')
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('expected internal html generated', function()
|
it('generates html', function()
|
||||||
insert([[line]])
|
test_generates_html(false)
|
||||||
exec('set termguicolors')
|
end)
|
||||||
local bg = fn.synIDattr(fn.hlID('Normal'), 'bg#', 'gui')
|
|
||||||
local fg = fn.synIDattr(fn.hlID('Normal'), 'fg#', 'gui')
|
it("generates html, respects 'guifont'", function()
|
||||||
exec_lua [[
|
test_generates_html(true)
|
||||||
local outfile = vim.fn.tempname() .. '.html'
|
|
||||||
local html = require('tohtml').tohtml(0,{title="title",font="dumyfont"})
|
|
||||||
vim.fn.writefile(html, outfile)
|
|
||||||
vim.cmd.split(outfile)
|
|
||||||
]]
|
|
||||||
local out_file = api.nvim_buf_get_name(api.nvim_get_current_buf())
|
|
||||||
eq({
|
|
||||||
'<!DOCTYPE html>',
|
|
||||||
'<html>',
|
|
||||||
'<head>',
|
|
||||||
'<meta charset="UTF-8">',
|
|
||||||
'<title>title</title>',
|
|
||||||
('<meta name="colorscheme" content="%s"></meta>'):format(api.nvim_get_var('colors_name')),
|
|
||||||
'<style>',
|
|
||||||
'* {font-family: dumyfont,monospace}',
|
|
||||||
('body {background-color: %s; color: %s}'):format(bg, fg),
|
|
||||||
'</style>',
|
|
||||||
'</head>',
|
|
||||||
'<body style="display: flex">',
|
|
||||||
'<pre>',
|
|
||||||
'line',
|
|
||||||
'',
|
|
||||||
'</pre>',
|
|
||||||
'</body>',
|
|
||||||
'</html>',
|
|
||||||
}, fn.readfile(out_file))
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('expected internal html generated from range', function()
|
it('expected internal html generated from range', function()
|
||||||
|
Reference in New Issue
Block a user