From 4665deee6c87e15bd8fd789fe724be68944a31ac Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Wed, 4 Mar 2026 13:54:01 -0500 Subject: [PATCH] feat(presets): add quarto preset Adds a quarto preset for .qmd scientific documents rendering to self-contained HTML with SSE live-reload. Uses --embed-resources to avoid a _files directory in the common case. No error_parser since quarto errors are heterogeneous (mixed R/Python/pandoc output). --- doc/preview.nvim.txt | 1 + lua/preview/presets.lua | 18 ++++++++++++++++ spec/presets_spec.lua | 48 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/doc/preview.nvim.txt b/doc/preview.nvim.txt index e946126..914f72d 100644 --- a/doc/preview.nvim.txt +++ b/doc/preview.nvim.txt @@ -162,6 +162,7 @@ Import them from `preview.presets`: `presets.markdown` pandoc → HTML (standalone, embedded) `presets.github` pandoc → HTML (GitHub-styled, `-f gfm` input) `presets.asciidoctor` asciidoctor → HTML (AsciiDoc with SSE reload) + `presets.quarto` quarto render → HTML (scientific publishing) Enable presets with `preset_name = true`: >lua diff --git a/lua/preview/presets.lua b/lua/preview/presets.lua index 8891c11..16e41ca 100644 --- a/lua/preview/presets.lua +++ b/lua/preview/presets.lua @@ -262,4 +262,22 @@ M.asciidoctor = { reload = true, } +---@type preview.ProviderConfig +M.quarto = { + ft = 'quarto', + cmd = { 'quarto' }, + args = function(ctx) + return { 'render', ctx.file, '--to', 'html', '--embed-resources' } + end, + output = function(ctx) + return (ctx.file:gsub('%.qmd$', '.html')) + end, + clean = function(ctx) + local base = ctx.file:gsub('%.qmd$', '') + return { 'rm', '-rf', base .. '.html', base .. '_files' } + end, + open = true, + reload = true, +} + return M diff --git a/spec/presets_spec.lua b/spec/presets_spec.lua index 55a00c4..9ce2cfc 100644 --- a/spec/presets_spec.lua +++ b/spec/presets_spec.lua @@ -518,4 +518,52 @@ describe('presets', function() assert.are.same({}, presets.asciidoctor.error_parser('', adoc_ctx)) end) end) + + describe('quarto', function() + local qmd_ctx = { + bufnr = 1, + file = '/tmp/document.qmd', + root = '/tmp', + ft = 'quarto', + output = '/tmp/document.html', + } + + it('has ft', function() + assert.are.equal('quarto', presets.quarto.ft) + end) + + it('has cmd', function() + assert.are.same({ 'quarto' }, presets.quarto.cmd) + end) + + it('returns args with render subcommand and html format', function() + assert.are.same( + { 'render', '/tmp/document.qmd', '--to', 'html', '--embed-resources' }, + presets.quarto.args(qmd_ctx) + ) + end) + + it('returns html output path', function() + assert.are.equal('/tmp/document.html', presets.quarto.output(qmd_ctx)) + end) + + it('returns clean command removing html and _files directory', function() + assert.are.same( + { 'rm', '-rf', '/tmp/document.html', '/tmp/document_files' }, + presets.quarto.clean(qmd_ctx) + ) + end) + + it('has open enabled', function() + assert.is_true(presets.quarto.open) + end) + + it('has reload enabled for SSE', function() + assert.is_true(presets.quarto.reload) + end) + + it('has no error_parser', function() + assert.is_nil(presets.quarto.error_parser) + end) + end) end)