Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion news/changelog-1.6.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ All changes included in 1.6:
- ([#10039](https://github.com/quarto-dev/quarto-cli/issues/10039)): `quarto inspect` properly handles `!expr` tag in metadata.
- ([#10188](https://github.com/quarto-dev/quarto-cli/issues/10188)): `quarto inspect` properly resolves includes across subdirectory boundaries.

## Lua Filters
## Lua Filters and extensions

- ([#10004](https://github.com/quarto-dev/quarto-cli/issues/10004)): Resolve callout titles, theorem names, and `code-summary` content through `quarto_ast_pipeline()` and `process_shortcodes()`.
- ([#10196](https://github.com/quarto-dev/quarto-cli/issues/10196)): Protect against nil values in `float.caption_long`.
- ([#10328](https://github.com/quarto-dev/quarto-cli/issues/10328)): Interpret subcells as subfloats when subcap count matches subcell count.
- ([#10624](https://github.com/quarto-dev/quarto-cli/issues/10624)): Don't crash when proof environments are empty in `pdf`.
- ([#10858](https://github.com/quarto-dev/quarto-cli/issues/10858)): Don't crash in `gfm` when `content` of a `FloatRefTarget` is of type `Blocks`.
- ([#10894](https://github.com/quarto-dev/quarto-cli/issues/10894)): Fix configuration of title and prefix in callouts for `html`, `revealjs`, `pdf`, and `typst`.
- ([#10999](https://github.com/quarto-dev/quarto-cli/issues/10999)): New API entry point: `quarto.paths.rscript()` to resolve `Rscript` path in Lua filters and extensions consistently with Quarto itself.

## `dashboard` Format

Expand Down
11 changes: 10 additions & 1 deletion src/command/render/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import { QuartoFilterSpec } from "./types.ts";
import { Metadata } from "../../config/types.ts";
import { kProjectType } from "../../project/types.ts";
import { bibEngine } from "../../config/pdf.ts";
import { resourcePath } from "../../core/resources.ts";
import { rBinaryPath, resourcePath } from "../../core/resources.ts";
import { crossrefFilterActive, crossrefFilterParams } from "./crossref.ts";
import { layoutFilterParams } from "./layout.ts";
import { pandocMetadataPath } from "./render-paths.ts";
Expand Down Expand Up @@ -195,10 +195,19 @@ export async function filterParamsJson(
[kShinyPythonExec]: isShinyPython ? await pythonExec() : undefined,
[kExecutionEngine]: options.executionEngine,
[kBrand]: options.format.render[kBrand],
"quarto-environment": await quartoEnvironmentParams(options),
};
return JSON.stringify(params);
}

async function quartoEnvironmentParams(_options: PandocOptions) {
return {
"paths": {
"Rscript": await rBinaryPath("Rscript"),
},
};
}

export function removeFilterParams(metadata: Metadata) {
delete metadata[kQuartoParams];
}
Expand Down
30 changes: 23 additions & 7 deletions src/core/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,23 @@ export function pandocBinaryPath(): string {
: architectureToolsPath("pandoc");
}

export async function rBinaryPath(binary: string): Promise<string> {
const _r_binary_path: Map<string, string> = new Map();
export async function rBinaryPath(
binary: string,
forceLookup = false,
): Promise<string> {
if (forceLookup) {
_r_binary_path.delete(binary);
}
const v = _r_binary_path.get(binary);
if (v) {
return v;
}
const setPath = (path: string) => {
_r_binary_path.set(binary, path);
return path;
};

debug(`-- Searching for R binary --`);
// if there is a QUARTO_R environment variable then respect that
const quartoR = Deno.env.get("QUARTO_R");
Expand All @@ -105,14 +121,14 @@ export async function rBinaryPath(binary: string): Promise<string> {
let rHomeBin = join(rHome, "bin", binary);
if (safeExistsSync(rHomeBin)) {
debug(`Found in ${rHomeBin}`);
return rHomeBin;
return setPath(rHomeBin);
}
if (Deno.build.os === "windows") {
// Some installation have binaries in the sub folder only
rHomeBin = join(rHome, "bin", "x64", binary);
if (safeExistsSync(rHomeBin)) {
debug(`Found in ${rHomeBin}`);
return rHomeBin;
return setPath(rHomeBin);
}
}
}
Expand All @@ -122,7 +138,7 @@ export async function rBinaryPath(binary: string): Promise<string> {
const path = await which(binary);
if (path) {
debug(`Found in PATH at ${path}`);
return path;
return setPath(path);
}

// on windows check the registry for a current version
Expand All @@ -143,7 +159,7 @@ export async function rBinaryPath(binary: string): Promise<string> {
);
if (installPath) {
debug(`Found in Windows Registry at ${join(installPath, "bin")}`);
return join(installPath, "bin", binary);
return setPath(join(installPath, "bin", binary));
}
}
// last ditch, try to find R in program files
Expand All @@ -157,7 +173,7 @@ export async function rBinaryPath(binary: string): Promise<string> {
for (const walk of walkSync(join(progFiles, "R"))) {
if (walk.isDirectory && walk.name === "bin") {
debug(`Found ${walk.path}`);
return join(walk.path, binary);
return setPath(join(walk.path, binary));
}
}
}
Expand All @@ -167,7 +183,7 @@ export async function rBinaryPath(binary: string): Promise<string> {

// We couldn't find R, just pass the binary itself and hope it works out!
debug(`Quarto did no found ${binary} and will try to use it directly.`);
return binary;
return setPath(binary);
}

export function projectTypeResourcePath(projectType: string) {
Expand Down
9 changes: 9 additions & 0 deletions src/resources/lua-types/quarto/paths.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---@meta

quarto.paths = {}

--[[
Returns the path to the `Rscript` file that Quarto itself would use in its knitr engine.
]]
---@return string # Path to `Rscript` file
function quarto.paths.rscript() end
38 changes: 22 additions & 16 deletions src/resources/pandoc/datadir/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2072,24 +2072,30 @@ quarto = {
crossref = {}
},
project = {
directory = projectDirectory(),
offset = projectOffset(),
profile = pandoc.List(projectProfiles()),
output_directory = projectOutputDirectory()
directory = projectDirectory(),
offset = projectOffset(),
profile = pandoc.List(projectProfiles()),
output_directory = projectOutputDirectory()
},
utils = {
dump = utils.dump,
table = utils.table,
type = utils.type,
resolve_path = resolvePathExt,
resolve_path_relative_to_document = resolvePath,
as_inlines = utils.as_inlines,
as_blocks = utils.as_blocks,
string_to_blocks = utils.string_to_blocks,
string_to_inlines = utils.string_to_inlines,
render = utils.render,
match = utils.match,
add_to_blocks = utils.add_to_blocks
dump = utils.dump,
table = utils.table,
type = utils.type,
resolve_path = resolvePathExt,
resolve_path_relative_to_document = resolvePath,
as_inlines = utils.as_inlines,
as_blocks = utils.as_blocks,
string_to_blocks = utils.string_to_blocks,
string_to_inlines = utils.string_to_inlines,
render = utils.render,
match = utils.match,
add_to_blocks = utils.add_to_blocks,
},
paths = {
rscript = function()
-- matches the path from `quartoEnvironmentParams` from src/command/render/filters.ts
return param('quarto-environment', nil).paths.Rscript
end,
},
json = json,
base64 = base64,
Expand Down
5 changes: 5 additions & 0 deletions tests/docs/smoke-all/2024/10/07/issue-10999.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function Pandoc(doc)
if quarto.paths.rscript() == nil then
crash()
end
end
7 changes: 7 additions & 0 deletions tests/docs/smoke-all/2024/10/07/issue-10999.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: issue-10999
filters:
- issue-10999.lua
---

## hello.
Loading