diff --git a/.claude/rules/filters/lua-development.md b/.claude/rules/filters/lua-development.md index fdc9659e09..dc881078f1 100644 --- a/.claude/rules/filters/lua-development.md +++ b/.claude/rules/filters/lua-development.md @@ -142,6 +142,25 @@ if quarto.log.debug then end ``` +## External Command Execution + +Use `pandoc.pipe()` instead of `io.popen()` for calling external programs: + +```lua +-- ✅ Correct - pandoc.pipe passes args as array, no shell interpretation +local ok, result = pcall(pandoc.pipe, command, {"arg1", "arg2"}, "") +if not ok then + quarto.log.error("Command failed: " .. tostring(result)) +end + +-- ❌ Wrong - io.popen uses shell, breaks on paths with spaces +local handle = io.popen(command .. " arg1 arg2", "r") +``` + +`io.popen()` passes a string to the shell, which breaks when paths contain spaces (e.g., `C:\Program Files\...`). `pandoc.pipe()` calls the executable directly with arguments as an array — no shell, no quoting issues. + +Reference: `quarto-pre/shiny.lua`, `quarto-post/pdf-images.lua` + ## Filter Return Values ```lua diff --git a/news/changelog-1.9.md b/news/changelog-1.9.md index c6f919abb1..23b93a4d99 100644 --- a/news/changelog-1.9.md +++ b/news/changelog-1.9.md @@ -86,6 +86,7 @@ All changes included in 1.9: - ([#13978](https://github.com/quarto-dev/quarto-cli/pull/13978)): Keep term and description together in definition lists to avoid breaking across pages. (author: @mcanouil) - ([#13878](https://github.com/quarto-dev/quarto-cli/issues/13878)): Typst now uses Pandoc's skylighting for syntax highlighting by default (consistent with other formats). Use `syntax-highlighting: idiomatic` to opt-in to Typst's native syntax highlighting instead. - ([#14126](https://github.com/quarto-dev/quarto-cli/issues/14126)): Fix Skylighting code blocks in Typst lacking full-width background, padding, and border radius. A postprocessor patches the Pandoc-generated Skylighting function to add `width: 100%`, `inset: 8pt`, and `radius: 2pt` to the block call, matching the styling of native code blocks. Brand `monospace-block.background-color` also now correctly applies to Skylighting output. This workaround will be removed once the fix is upstreamed to Skylighting. +- ([#14202](https://github.com/quarto-dev/quarto-cli/issues/14202)): Fix CSS inlining (`juice`) failing on Windows when Quarto is installed in a path with spaces (e.g., `C:\Program Files\Quarto\`). ### `pdf` diff --git a/src/resources/filters/normalize/astpipeline.lua b/src/resources/filters/normalize/astpipeline.lua index 1065d70562..881d935dd9 100644 --- a/src/resources/filters/normalize/astpipeline.lua +++ b/src/resources/filters/normalize/astpipeline.lua @@ -65,28 +65,19 @@ function quarto_ast_pipeline() jin:write(htmltext) jin:flush() local quarto_path = quarto.config.cli_path() - local jout, jerr = io.popen(quarto_path .. ' run ' .. - pandoc.path.join({os.getenv('QUARTO_SHARE_PATH'), 'scripts', 'juice.ts'}) .. ' ' .. - juice_in, 'r') - if not jout then - quarto.log.error('Running juice failed with message: ' .. (jerr or "Unknown error")) + local juice_script = pandoc.path.join({os.getenv('QUARTO_SHARE_PATH'), 'scripts', 'juice.ts'}) + local ok, content = pcall(pandoc.pipe, quarto_path, {'run', juice_script, juice_in}, '') + if not ok then + quarto.log.error('Running juice failed: ' .. tostring(content)) return htmltext end - local content = jout:read('a') - local success, _, exitCode = jout:close() - -- Check the exit status - if not success then - quarto.log.error("Running juice failed with exit code: " .. (exitCode or "unknown exit code")) - return htmltext - else - local index = 1 - content = content:gsub(data_uri_uuid:gsub('-', '%%-'), function(_) - local data_uri = data_uris[index] - index = index + 1 - return data_uri - end) - return content - end + local index = 1 + content = content:gsub(data_uri_uuid:gsub('-', '%%-'), function(_) + local data_uri = data_uris[index] + index = index + 1 + return data_uri + end) + return content end) end local function should_handle_raw_html_as_table(el)