diff --git a/compiler/src/knitr/__test__/knitr.test.ts b/compiler/src/knitr/__test__/knitr.test.ts index 7eddc865..7daeabaa 100644 --- a/compiler/src/knitr/__test__/knitr.test.ts +++ b/compiler/src/knitr/__test__/knitr.test.ts @@ -240,7 +240,7 @@ describe('knitr', () => { expect(ignoreWhitespace(md)).toContain( ignoreWhitespace(` - \`\`\`{.r-error} + \`\`\`{.r-error-output} Error in "120" + "5": non-numeric argument to binary operator \`\`\` `) @@ -284,7 +284,7 @@ describe('knitr', () => {
print(a)
Error in py_call_impl(callable, dots$args, dots$keywords): NameError: name 'a' is not defined
Detailed traceback:
@@ -301,7 +301,7 @@ describe('knitr', () => {
b
-
+
R Console
Error in eval(expr, envir, enclos): object 'b' not found
diff --git a/compiler/src/knitr/index.ts b/compiler/src/knitr/index.ts
index 8f7c5fe4..a38efd3a 100644
--- a/compiler/src/knitr/index.ts
+++ b/compiler/src/knitr/index.ts
@@ -84,10 +84,10 @@ function reportErrors(response: string, file: VFile) {
async function formatResponse(response: string) {
let md = response;
md = removeCustomPythonBinNotice(md);
- md = removeHashSigns(md);
md = addCodeBlockClasses(md);
- md = removeEmptyLog(md);
md = addErrorCodeBlock(md);
+ md = removeHashSigns(md);
+ md = removeEmptyLog(md);
md = addNewLineAfterKable(md);
return md;
}
@@ -96,16 +96,13 @@ function removeCustomPythonBinNotice(md: string) {
return md.replace(/^\$python\s\[1\]\s"\S+"/, '');
}
-function removeHashSigns(md: string) {
- let insideCodeBlock = false;
+function addCodeBlockClasses(md: string) {
return md
.split('\n')
.reduce((acc: string[], line) => {
- if (line.startsWith('```')) {
- insideCodeBlock = !insideCodeBlock;
- }
- if (insideCodeBlock) {
- acc.push(line.replace(/^##\s+/, ''));
+ if (line.startsWith('```{.knitr-output}')) {
+ const lang = findLanguageForOutput(acc);
+ acc.push(`\`\`\`{.${lang}-output}`);
} else {
acc.push(line);
}
@@ -114,13 +111,18 @@ function removeHashSigns(md: string) {
.join('\n');
}
-function addCodeBlockClasses(md: string) {
+function removeHashSigns(md: string) {
+ let insideCodeResponse = false;
+ let openingLine = '';
return md
.split('\n')
.reduce((acc: string[], line) => {
- if (line.startsWith('```{.knitr-output}')) {
- const lang = findLanguageForOutput(acc);
- acc.push(`\`\`\`{.${lang}-output}`);
+ if (line.startsWith('```')) {
+ insideCodeResponse = !insideCodeResponse;
+ openingLine = insideCodeResponse ? line : '';
+ }
+ if (insideCodeResponse && openingLine.endsWith('-output}')) {
+ acc.push(line.replace(/^##\s+/, ''));
} else {
acc.push(line);
}
@@ -137,9 +139,9 @@ function addErrorCodeBlock(md: string) {
return md
.split('\n')
.reduce((acc: string[], line, idx) => {
- if (line.startsWith('Error') && acc[idx - 1].startsWith('```')) {
+ if (line.startsWith('## Error') && acc[idx - 1].startsWith('```')) {
const lang = findLanguageForOutput(acc.slice(0, -1));
- acc[acc.length - 1] = `\`\`\`{.${lang}-error}`;
+ acc[acc.length - 1] = `\`\`\`{.${lang}-error-output}`;
}
acc.push(line);
return acc;
diff --git a/compiler/src/mdast/__test__/escaping.test.ts b/compiler/src/mdast/__test__/escaping.test.ts
new file mode 100644
index 00000000..9de85fc7
--- /dev/null
+++ b/compiler/src/mdast/__test__/escaping.test.ts
@@ -0,0 +1,22 @@
+import {
+ testProcessor,
+ unindentString,
+} from '../../test-utils/test-processor';
+
+describe('example', () => {
+ it('should allow the author to use sample markdown headings', async () => {
+ const { html } = await testProcessor(`
+ \`\`\`
+ ## This is a subsection
+ \`\`\`
+ `);
+
+ const expected = unindentString(`
+
+ ## This is a subsection
+
+ `);
+
+ expect(html).toBe(expected);
+ });
+});
diff --git a/compiler/src/mdast/code-blocks.ts b/compiler/src/mdast/code-blocks.ts
index e2c3e47f..27e48c11 100644
--- a/compiler/src/mdast/code-blocks.ts
+++ b/compiler/src/mdast/code-blocks.ts
@@ -73,7 +73,7 @@ function customCode(node: Code, ctx: Context, file: VFile) {
}
function addConsoleHeading(klass: string) {
- if (klass === 'r-output' || klass === 'r-error') {
+ if (klass === 'r-output' || klass === 'r-error-output') {
return {
type: 'element',
tagName: 'h6',
@@ -88,7 +88,7 @@ function addConsoleHeading(klass: string) {
],
};
}
- if (klass === 'python-output' || klass === 'python-error') {
+ if (klass === 'python-output' || klass === 'python-error-output') {
return {
type: 'element',
tagName: 'h6',
diff --git a/template/src/styles/code.scss b/template/src/styles/code.scss
index 462287f3..326662e3 100644
--- a/template/src/styles/code.scss
+++ b/template/src/styles/code.scss
@@ -32,7 +32,7 @@ code {
background: transparent;
}
- &[class$="error"] {
+ &[class$="error-output"] {
background: var(--errorColor);
color: white;
& > h6.console-heading {