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

fix: renderer.code includes space at beginning of each line of code #1645

Merged
merged 19 commits into from May 2, 2020
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 37 additions & 2 deletions src/Tokenizer.js
Expand Up @@ -29,6 +29,38 @@ function outputLink(cap, link, raw) {
}
}

function indentCodeCompensation(raw, text) {
if (raw === undefined) {
return text;
}
UziTech marked this conversation as resolved.
Show resolved Hide resolved

const matchIndentToCode = raw.match(/^(\s+)(?:```)/);

if (matchIndentToCode === null) {
return text;
}

const indentToCode = matchIndentToCode[1];

return text
.split('\n')
.map(node => {
const matchIndentInNode = node.match(/^\s+/);
if (matchIndentInNode === null) {
return node;
}

const [indentInNode] = matchIndentInNode;

if (indentInNode.length >= indentToCode.length) {
return node.slice(indentToCode.length);
}

return node;
})
.join('\n');
}

/**
* Tokenizer
*/
Expand Down Expand Up @@ -77,11 +109,14 @@ module.exports = class Tokenizer {
fences(src) {
const cap = this.rules.block.fences.exec(src);
if (cap) {
const raw = cap[0];
const text = indentCodeCompensation(raw, cap[3] || '');

return {
type: 'code',
raw: cap[0],
raw,
lang: cap[2] ? cap[2].trim() : cap[2],
text: cap[3] || ''
text
};
}
}
Expand Down
13 changes: 12 additions & 1 deletion test/helpers/helpers.js
@@ -1,5 +1,6 @@
const marked = require('../../src/marked.js');
const htmlDiffer = require('./html-differ.js');
const assert = require('assert');

beforeEach(() => {
marked.setOptions(marked.getDefaults());
Expand Down Expand Up @@ -37,6 +38,16 @@ beforeEach(() => {
return result;
}
};
}
},
toRenderExact: () => ({
compare: async(spec, expected) => {
const result = {};
const actual = marked(spec.markdown, spec.options);

result.pass = assert.strictEqual(expected, actual) === undefined;

return result;
}
})
});
});
6 changes: 6 additions & 0 deletions test/specs/new/code_compensation_indent.html
@@ -0,0 +1,6 @@
<p>This is some text.</p>
<ol>
<li><p>This is a list element.</p>
<pre><code>const x = 5;
const y = x + 5;</code></pre></li>
</ol>
11 changes: 11 additions & 0 deletions test/specs/new/code_compensation_indent.md
@@ -0,0 +1,11 @@
---
renderExact: true
---
This is some text.

1. This is a list element.

```
const x = 5;
const y = x + 5;
```
5 changes: 5 additions & 0 deletions test/specs/run-spec.js
Expand Up @@ -16,17 +16,22 @@ function runSpecs(title, dir, showCompletionTable, options) {
spec.options = Object.assign({}, options, (spec.options || {}));
const example = (spec.example ? ' example ' + spec.example : '');
const passFail = (spec.shouldFail ? 'fail' : 'pass');

if (typeof spec.options.silent === 'undefined') {
spec.options.silent = true;
}

if (spec.options.sanitizer) {
// eslint-disable-next-line no-eval
spec.options.sanitizer = eval(spec.options.sanitizer);
}

(spec.only ? fit : (spec.skip ? xit : it))('should ' + passFail + example, async() => {
const before = process.hrtime();
if (spec.shouldFail) {
await expectAsync(spec).not.toRender(spec.html);
} else if (spec.options.renderExact) {
await expectAsync(spec).toRenderExact(spec.html);
} else {
await expectAsync(spec).toRender(spec.html);
}
Expand Down