Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script files not picked up by julia engine #10034

Open
jkrumbiegel opened this issue Jun 17, 2024 · 7 comments · May be fixed by #11807
Open

Script files not picked up by julia engine #10034

jkrumbiegel opened this issue Jun 17, 2024 · 7 comments · May be fixed by #11807
Assignees
Labels
bug Something isn't working julia
Milestone

Comments

@jkrumbiegel
Copy link
Contributor

Bug description

It appears that julia script files do not get sent to the julia engine even if specifying engine: julia in the frontmatter. Instead, they are run by the jupyter engine.

Steps to reproduce

I tried quarto render testfile.jl where testfile.jl had this content:

# %% [markdown]
# ---
# engine: julia
# ---

# %%
println("the result is $(1 + 1)")

Expected behavior

Julia engine would try to render this file

Actual behavior

Jupyter engine rendered the file.

Your environment

No response

Quarto check output

Quarto 1.5.40
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.2.0: OK
      Dart Sass version 1.70.0: OK
      Deno version 1.41.0: OK
      Typst version 0.11.0: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.5.40
      Path: /Applications/quarto/bin

[✓] Checking tools....................OK
      TinyTeX: v2024.03
      Chromium: (not installed)

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /Users/krumbiegel/Library/TinyTeX/bin/universal-darwin
      Version: 2023

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK
      Version: 3.12.2 (Conda)
      Path: /Users/krumbiegel/miniconda3/bin/python
      Jupyter: 5.5.0
      Kernels: julia-1.10, julia-1.8, julia-1.7, python3

[✓] Checking Jupyter engine render....OK

[✓] Checking R installation...........OK
      Version: 4.3.2
      Path: /Library/Frameworks/R.framework/Resources
      LibPaths:
        - /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
      knitr: 1.45
      rmarkdown: 2.26

[✓] Checking Knitr engine render......OK
@jkrumbiegel jkrumbiegel added the bug Something isn't working label Jun 17, 2024
@mcanouil mcanouil added the julia label Jun 17, 2024
@cscheid cscheid added this to the v1.6 milestone Jun 17, 2024
@cscheid cscheid self-assigned this Jun 17, 2024
@cderv
Copy link
Collaborator

cderv commented Jun 17, 2024

For the context, currently those files are claimed by Jupyter engine

claimsFile: (file: string, ext: string) => {
return kJupyterNotebookExtensions.includes(ext.toLowerCase()) ||
isJupyterPercentScript(file);
},

and Julia claims no file

claimsFile: (file: string, ext: string) => false,

This is probably not clear in our doc, but as of now when using script as input to render, the engine option in those file is not used and this is too late - the file has already been claimed by an engine.

Does Julia engine support same Percent script syntax from Jupytext ? https://jupytext.readthedocs.io/en/latest/formats-scripts.html

Currently, we do detect .py and check if it has percent syntax. If so, Jupyter engine claims it.

If the same file could also be working for Julia engine, I think we should indeed parse the file header and detect the engine: julia specification t know which engine is claiming the file

@jkrumbiegel
Copy link
Contributor Author

I did not add any claimsFile as the assumption was that the previous behavior with the jupyter backend should not be impacted. Otherwise I would've claimed normal julia codeblocks in a .qmd file as well.

Does Julia engine support same Percent script syntax from Jupytext

Yes, we do have support for that style

@cderv
Copy link
Collaborator

cderv commented Jun 18, 2024

Thanks for the confirmation.

When we added Jupyter Percent Script support, we only associated it with the Jupyter engine, no matter is content.

So, we definitely need to adapt the claimFiles for Jupyter so that the Julia engine can also claim the .jl script.
I would say

  • Either we change default and Percent script .jl file should be claimed by Julia engine
  • Either we need to look into the Percent script to check which engine: julia is set in the field as we do for .qmd document.

For comparaison, engine: knitr does not support the same syntax of percent script. So any .R file with Percent script syntax will be claimed by Jupyter and not knitr engine.

Thanks for the report !

@jkrumbiegel
Copy link
Contributor Author

jkrumbiegel commented Jun 18, 2024

one question, when you process such a script file, what does target.markdown contain in the end? A markdown transformation or the original script? Or would that not be set at all in that case, because the source is not markdown

@cderv
Copy link
Collaborator

cderv commented Jun 18, 2024

Yes it will contain a markdown transformation. We process the script in Quarto to create a Markdown version

It happens in this function

export function markdownFromJupyterPercentScript(file: string) {
// determine language/kernel
const ext = extname(file).toLowerCase();
const language = ext === ".jl" ? "julia" : ext === ".r" ? "r" : "python";
// break into cells
const cells: PercentCell[] = [];
const activeCell = () => cells[cells.length - 1];
for (const line of lines(Deno.readTextFileSync(file).trim())) {
const header = percentCellHeader(line);
if (header) {
cells.push({ header, lines: [] });
} else {
activeCell()?.lines.push(line);
}
}
// resolve markdown and raw cells
const isTripleQuote = (line: string) => !!line.match(/^"{3,}\s*$/);
const asCell = (lines: string[]) => lines.join("\n") + "\n\n";
const stripPrefix = (line: string) => line.replace(/^#\s?/, "");
const cellContent = (cellLines: string[]) => {
if (
cellLines.length > 2 && isTripleQuote(cellLines[0]) &&
isTripleQuote(cellLines[cellLines.length - 1])
) {
return asCell(cellLines.slice(1, cellLines.length - 1));
} else {
// commented
return asCell(cellLines.map(stripPrefix));
}
};
return cells.reduce((markdown, cell) => {
const cellLines = trimEmptyLines(cell.lines);
if (cell.header.type === "code") {
if (cell.header.metadata) {
const yamlText = asYamlText(cell.header.metadata);
cellLines.unshift(...lines(yamlText).map((line) => `#| ${line}`));
}
markdown += asCell(["```{" + language + "}", ...cellLines, "```"]);
} else if (cell.header.type === "markdown") {
markdown += cellContent(cellLines);
} else if (cell.header.type == "raw") {
let rawContent = cellContent(cellLines);
const format = cell.header?.metadata?.["format"];
const mimeType = cell.header.metadata?.[kCellRawMimeType];
if (typeof (mimeType) === "string") {
const rawBlock = mdRawOutput(mimeType, lines(rawContent));
rawContent = rawBlock || rawContent;
} else if (typeof (format) === "string") {
rawContent = mdFormatOutput(format, lines(rawContent));
}
markdown += rawContent;
}
return markdown;
}, "");
}

that we call in our jupyter engine functions producing markdown

  • markdownForFile function
    markdownForFile(file: string): Promise<MappedString> {
    if (isJupyterNotebook(file)) {
    const nbJSON = Deno.readTextFileSync(file);
    const nb = JSON.parse(nbJSON) as JupyterNotebook;
    return Promise.resolve(asMappedString(markdownFromNotebookJSON(nb)));
    } else if (isJupyterPercentScript(file)) {
    return Promise.resolve(
    asMappedString(markdownFromJupyterPercentScript(file)),
    );
    } else {
    return Promise.resolve(mappedStringFromFile(file));
    }
    },
  • or another partitionedMarkdown
    partitionedMarkdown: async (file: string, format?: Format) => {
    if (isJupyterNotebook(file)) {
    return partitionMarkdown(await markdownFromNotebookFile(file, format));
    } else if (isJupyterPercentScript(file)) {
    return partitionMarkdown(markdownFromJupyterPercentScript(file));
    } else {
    return partitionMarkdown(Deno.readTextFileSync(file));
    }
    },

@albertomercurio
Copy link

Hello, I have the same problem. But the file is not even executed. I only see a html page with all the code, without syntax highlighting and without any output.

Are there any progresses on that?

@cderv
Copy link
Collaborator

cderv commented Feb 6, 2025

Are there any progresses on that?

If you look at the thread links just above and the sidebar on right, you should see that there is a PR in work. So progress there is.

Usually, if an issue is still open, it means it is still consider. Otherwise, it would be closed as non planned, or resolved. Regarding progress, milestones and other metadata on the issues can give you an hint on the activity.

Hope it helps clarify how issue tracking works. Thanks for your understanding.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working julia
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants