diff --git a/doc/preview.nvim.txt b/doc/preview.nvim.txt index 914f72d..a3d4981 100644 --- a/doc/preview.nvim.txt +++ b/doc/preview.nvim.txt @@ -157,12 +157,8 @@ Import them from `preview.presets`: `presets.typst` typst compile → PDF `presets.latex` latexmk -pdf → PDF (with clean support) - `presets.pdflatex` pdflatex → PDF (single pass, no latexmk) - `presets.tectonic` tectonic → PDF (Rust-based LaTeX engine) `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 8a23766..fc20f89 100644 --- a/lua/preview/presets.lua +++ b/lua/preview/presets.lua @@ -93,28 +93,6 @@ local function parse_pandoc(output) return diagnostics end ----@param output string ----@return preview.Diagnostic[] -local function parse_asciidoctor(output) - local diagnostics = {} - for line in output:gmatch('[^\r\n]+') do - local severity, _, lnum, msg = line:match('^asciidoctor: (%u+): (.+): line (%d+): (.+)$') - if lnum then - local sev = vim.diagnostic.severity.ERROR - if severity == 'WARNING' then - sev = vim.diagnostic.severity.WARN - end - table.insert(diagnostics, { - lnum = tonumber(lnum) - 1, - col = 0, - message = msg, - severity = sev, - }) - end - end - return diagnostics -end - ---@type preview.ProviderConfig M.typst = { ft = 'typst', @@ -159,38 +137,6 @@ M.latex = { open = true, } ----@type preview.ProviderConfig -M.pdflatex = { - ft = 'tex', - cmd = { 'pdflatex' }, - args = function(ctx) - return { '-interaction=nonstopmode', '-file-line-error', '-synctex=1', ctx.file } - end, - output = function(ctx) - return (ctx.file:gsub('%.tex$', '.pdf')) - end, - error_parser = function(output) - return parse_latexmk(output) - end, - open = true, -} - ----@type preview.ProviderConfig -M.tectonic = { - ft = 'tex', - cmd = { 'tectonic' }, - args = function(ctx) - return { ctx.file } - end, - output = function(ctx) - return (ctx.file:gsub('%.tex$', '.pdf')) - end, - error_parser = function(output) - return parse_latexmk(output) - end, - open = true, -} - ---@type preview.ProviderConfig M.markdown = { ft = 'markdown', @@ -241,42 +187,4 @@ M.github = { reload = true, } ----@type preview.ProviderConfig -M.asciidoctor = { - ft = 'asciidoc', - cmd = { 'asciidoctor' }, - args = function(ctx) - return { ctx.file, '-o', ctx.output } - end, - output = function(ctx) - return (ctx.file:gsub('%.adoc$', '.html')) - end, - error_parser = function(output) - return parse_asciidoctor(output) - end, - clean = function(ctx) - return { 'rm', '-f', (ctx.file:gsub('%.adoc$', '.html')) } - end, - open = true, - 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 ab030f0..8085a3c 100644 --- a/spec/presets_spec.lua +++ b/spec/presets_spec.lua @@ -157,112 +157,6 @@ describe('presets', function() end) end) - describe('pdflatex', function() - local tex_ctx = { - bufnr = 1, - file = '/tmp/document.tex', - root = '/tmp', - ft = 'tex', - } - - it('has ft', function() - assert.are.equal('tex', presets.pdflatex.ft) - end) - - it('has cmd', function() - assert.are.same({ 'pdflatex' }, presets.pdflatex.cmd) - end) - - it('returns args with flags and file path', function() - local args = presets.pdflatex.args(tex_ctx) - assert.are.same( - { '-interaction=nonstopmode', '-file-line-error', '-synctex=1', '/tmp/document.tex' }, - args - ) - end) - - it('returns pdf output path', function() - assert.are.equal('/tmp/document.pdf', presets.pdflatex.output(tex_ctx)) - end) - - it('has open enabled', function() - assert.is_true(presets.pdflatex.open) - end) - - it('has no clean command', function() - assert.is_nil(presets.pdflatex.clean) - end) - - it('has no reload', function() - assert.is_nil(presets.pdflatex.reload) - end) - - it('parses file-line-error format', function() - local output = './document.tex:10: Undefined control sequence.' - local diagnostics = presets.pdflatex.error_parser(output, tex_ctx) - assert.are.equal(1, #diagnostics) - assert.are.equal(9, diagnostics[1].lnum) - assert.are.equal(0, diagnostics[1].col) - assert.are.equal('Undefined control sequence.', diagnostics[1].message) - assert.are.equal(vim.diagnostic.severity.ERROR, diagnostics[1].severity) - end) - - it('returns empty table for clean output', function() - assert.are.same({}, presets.pdflatex.error_parser('', tex_ctx)) - end) - end) - - describe('tectonic', function() - local tex_ctx = { - bufnr = 1, - file = '/tmp/document.tex', - root = '/tmp', - ft = 'tex', - } - - it('has ft', function() - assert.are.equal('tex', presets.tectonic.ft) - end) - - it('has cmd', function() - assert.are.same({ 'tectonic' }, presets.tectonic.cmd) - end) - - it('returns args with file path', function() - assert.are.same({ '/tmp/document.tex' }, presets.tectonic.args(tex_ctx)) - end) - - it('returns pdf output path', function() - assert.are.equal('/tmp/document.pdf', presets.tectonic.output(tex_ctx)) - end) - - it('has open enabled', function() - assert.is_true(presets.tectonic.open) - end) - - it('has no clean command', function() - assert.is_nil(presets.tectonic.clean) - end) - - it('has no reload', function() - assert.is_nil(presets.tectonic.reload) - end) - - it('parses file-line-error format', function() - local output = './document.tex:5: Missing $ inserted.' - local diagnostics = presets.tectonic.error_parser(output, tex_ctx) - assert.are.equal(1, #diagnostics) - assert.are.equal(4, diagnostics[1].lnum) - assert.are.equal(0, diagnostics[1].col) - assert.are.equal('Missing $ inserted.', diagnostics[1].message) - assert.are.equal(vim.diagnostic.severity.ERROR, diagnostics[1].severity) - end) - - it('returns empty table for clean output', function() - assert.are.same({}, presets.tectonic.error_parser('', tex_ctx)) - end) - end) - describe('markdown', function() local md_ctx = { bufnr = 1, @@ -447,116 +341,4 @@ describe('presets', function() assert.are.same({}, diagnostics) end) end) - - describe('asciidoctor', function() - local adoc_ctx = { - bufnr = 1, - file = '/tmp/document.adoc', - root = '/tmp', - ft = 'asciidoc', - output = '/tmp/document.html', - } - - it('has ft', function() - assert.are.equal('asciidoc', presets.asciidoctor.ft) - end) - - it('has cmd', function() - assert.are.same({ 'asciidoctor' }, presets.asciidoctor.cmd) - end) - - it('returns args with file and output', function() - assert.are.same( - { '/tmp/document.adoc', '-o', '/tmp/document.html' }, - presets.asciidoctor.args(adoc_ctx) - ) - end) - - it('returns html output path', function() - assert.are.equal('/tmp/document.html', presets.asciidoctor.output(adoc_ctx)) - end) - - it('returns clean command', function() - assert.are.same({ 'rm', '-f', '/tmp/document.html' }, presets.asciidoctor.clean(adoc_ctx)) - end) - - it('has open enabled', function() - assert.is_true(presets.asciidoctor.open) - end) - - it('has reload enabled for SSE', function() - assert.is_true(presets.asciidoctor.reload) - end) - - it('parses error messages', function() - local output = - 'asciidoctor: ERROR: document.adoc: line 8: invalid part, must have at least one section' - local diagnostics = presets.asciidoctor.error_parser(output, adoc_ctx) - assert.are.equal(1, #diagnostics) - assert.are.equal(7, diagnostics[1].lnum) - assert.are.equal(0, diagnostics[1].col) - assert.are.equal('invalid part, must have at least one section', diagnostics[1].message) - assert.are.equal(vim.diagnostic.severity.ERROR, diagnostics[1].severity) - end) - - it('parses warning messages', function() - local output = 'asciidoctor: WARNING: document.adoc: line 52: section title out of sequence' - local diagnostics = presets.asciidoctor.error_parser(output, adoc_ctx) - assert.are.equal(1, #diagnostics) - assert.are.equal(51, diagnostics[1].lnum) - assert.are.equal(vim.diagnostic.severity.WARN, diagnostics[1].severity) - end) - - it('returns empty table for clean output', 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)