Skip to content

Commit

Permalink
Merge pull request #12223 from quarto-dev/bugfix/issue-12042
Browse files Browse the repository at this point in the history
convert - preserve markdown after yaml in raw cells
  • Loading branch information
cscheid authored Mar 7, 2025
2 parents 4ca63a7 + d6ca49c commit af454e8
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 6 deletions.
4 changes: 4 additions & 0 deletions news/changelog-1.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ All changes included in 1.7:

- ([#11608](https://github.com/quarto-dev/quarto-cli/pull/11608)): Do not issue error message when calling `quarto check info`.

## `quarto convert`

- ([#12042](https://github.com/quarto-dev/quarto-cli/issues/12042)): Preserve Markdown content that follows YAML metadata in a `raw` .ipynb cell.

## `html` format

- ([#11860](https://github.com/quarto-dev/quarto-cli/issues/11860)): ES6 modules that import other local JS modules in documents with `embed-resources: true` are now correctly embedded.
Expand Down
25 changes: 19 additions & 6 deletions src/command/convert/jupyter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
jupyterCellSrcAsLines,
jupyterCellSrcAsStr,
} from "../../core/jupyter/jupyter-shared.ts";
import { assert } from "testing/asserts";

export async function markdownToJupyterNotebook(
file: string,
Expand Down Expand Up @@ -71,11 +72,15 @@ export async function jupyterNotebookToMarkdown(
case "raw":
// see if this is the front matter
if (frontMatter === undefined) {
frontMatter = partitionYamlFrontMatter(
jupyterCellSrcAsStr(cell),
)?.yaml;
if (!frontMatter) {
md.push(...mdFromRawCell(cellWithOptions));
const { yaml: cellYaml, markdown: cellMarkdown } =
partitionYamlFrontMatter(
jupyterCellSrcAsStr(cell),
) || {};
if (cellYaml) {
frontMatter = cellYaml;
}
if (cellMarkdown) {
md.push(cellMarkdown);
}
} else {
md.push(...mdFromRawCell(cellWithOptions));
Expand Down Expand Up @@ -130,14 +135,22 @@ export async function jupyterNotebookToMarkdown(
}
}

// if we found front matter, then the markdown source will start with enough
// newlines for the front matter to have been detected in the first place.
// So we only need to add newlines if there was no front matter.
//
// If this invariant breaks, we have a bug of some kind, so let's just assert it
assert(frontMatter || !mdSource.match(/^\n\n/));
const maybeYamlMdBreak = frontMatter ? "" : "\n\n";

// return yaml + markdown
const yamlText = stringify(yaml, {
indent: 2,
lineWidth: -1,
sortKeys: false,
skipInvalid: true,
});
return `---\n${yamlText}---\n\n${mdSource}`;
return `---\n${yamlText}---${maybeYamlMdBreak}${mdSource}`;
}

async function mdFromCodeCell(
Expand Down
32 changes: 32 additions & 0 deletions tests/docs/convert/issue-12042.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"title: My Document\n",
"format: html\n",
"jupyter: python3\n",
"keep-ipynb: true\n",
"---\n",
"\n",
"\n",
"\n",
"## Introduction\n",
"\n",
"Here I place some text."
]
}
],
"metadata": {
"kernelspec": {
"name": "python3",
"language": "python",
"display_name": "Python 3 (ipykernel)",
"path": "/Users/cscheid/virtualenvs/homebrew-python3/share/jupyter/kernels/python3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
36 changes: 36 additions & 0 deletions tests/smoke/convert/convert-issue-12042.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* convert-backticks.test.ts
*
* Copyright (C) 2020-2024 Posit Software, PBC
*
*/
import { existsSync } from "../../../src/deno_ral/fs.ts";
import {
ExecuteOutput,
testQuartoCmd,
} from "../../test.ts";
import { assert } from "testing/asserts";

(() => {
const input = "docs/convert/backticks.ipynb";
testQuartoCmd(
"convert",
["docs/convert/issue-12042.ipynb"],
[
{
name: "convert-markdown-after-yaml",
verify: async (outputs: ExecuteOutput[]) => {
const txt = Deno.readTextFileSync("docs/convert/issue-12042.qmd");
assert(txt.includes("Here I place some text."), "Markdown text not found in output");
}
}
],
{
teardown: async () => {
if (existsSync("docs/convert/issue-12042.qmd")) {
Deno.removeSync("docs/convert/issue-12042.qmd");
}
}
},
);
})();

0 comments on commit af454e8

Please sign in to comment.