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

feat: markdownlint rule to disallow newline in link text #69

Merged
merged 1 commit into from
May 16, 2024
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
1 change: 1 addition & 0 deletions configs/markdownlint.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"no-inline-html": false,
"no-angle-brackets": false,
"no-curly-braces": false,
"no-newline-in-links": false,
"link-image-style": {
"shortcut": false
}
Expand Down
30 changes: 30 additions & 0 deletions markdownlint-rules/emd004.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const { addError, filterTokens } = require('markdownlint/helpers');

module.exports = {
names: ['EMD004', 'no-newline-in-links'],
description: 'Newlines inside link text',
tags: ['newline', 'links'],
parser: 'markdownit',
function: function EMD004(params, onError) {
filterTokens(params, 'inline', (token) => {
const { children } = token;
let { lineNumber } = token;
let inLink = false;
for (const child of children) {
const { type } = child;
if (type === 'link_open') {
inLink = true;
} else if (type === 'link_close') {
inLink = false;
} else if (type === 'softbreak') {
if (inLink) {
addError(onError, lineNumber);
break;
} else {
lineNumber++;
}
}
}
});
},
};
3 changes: 2 additions & 1 deletion markdownlint-rules/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const EMD002 = require('./emd002.js');
const EMD003 = require('./emd003.js');
const EMD004 = require('./emd004.js');

module.exports = [EMD002, EMD003];
module.exports = [EMD002, EMD003, EMD004];
8 changes: 8 additions & 0 deletions tests/__snapshots__/electron-markdownlint.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`electron-markdownlint > should not allow newlines in link text if EMD004 enabled 1`] = `
"<root>newline-in-link-text.md:1 EMD004/no-newline-in-links Newlines inside link text
<root>newline-in-link-text.md:4 EMD004/no-newline-in-links Newlines inside link text
<root>newline-in-link-text.md:7 EMD004/no-newline-in-links Newlines inside link text
<root>newline-in-link-text.md:10 EMD004/no-newline-in-links Newlines inside link text
"
`;

exports[`electron-markdownlint > should not allow opening angle brackets if EMD002 enabled 1`] = `
"<root>angle-brackets.md:3:13 EMD002/no-angle-brackets No unescaped opening angle brackets in text (does not play nice with MDX) [Unescaped opening angle bracket]
<root>angle-brackets.md:9:16 EMD002/no-angle-brackets No unescaped opening angle brackets in text (does not play nice with MDX) [Unescaped opening angle bracket]
Expand Down
42 changes: 42 additions & 0 deletions tests/electron-markdownlint.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,46 @@ describe('electron-markdownlint', () => {
expect(stdout).toBe('');
expect(status).toEqual(0);
});

it('should not allow newlines in link text if EMD004 enabled', () => {
const { status, stderr, stdout } = cp.spawnSync(
process.execPath,
[
path.resolve(__dirname, '../dist/bin/markdownlint-cli-wrapper.js'),
'--enable',
'EMD004',
'--',
path.resolve(FIXTURES_DIR, 'newline-in-link-text.md'),
],
{ stdio: 'pipe', encoding: 'utf-8' },
);

let fixturesRoot = `${FIXTURES_DIR}${path.sep}`;

if (os.platform() === 'win32') {
fixturesRoot = fixturesRoot.replace(/\\/g, '\\\\');
}

expect(stderr.replace(new RegExp(fixturesRoot, 'g'), '<root>')).toMatchSnapshot();
expect(stdout).toBe('');
expect(status).toEqual(1);
});

it('should allow newlines in link text if EMD004 not enabled', () => {
const { status, stderr, stdout } = cp.spawnSync(
process.execPath,
[
path.resolve(__dirname, '../dist/bin/markdownlint-cli-wrapper.js'),
'--disable',
'EMD004',
'--',
path.resolve(FIXTURES_DIR, 'newline-in-link-text.md'),
],
{ stdio: 'pipe', encoding: 'utf-8' },
);

expect(stderr).toBe('');
expect(stdout).toBe('');
expect(status).toEqual(0);
});
});
6 changes: 3 additions & 3 deletions tests/fixtures/angle-brackets.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ protocol.registerSchemesAsPrivileged([
])
```

A standard scheme adheres to what RFC 3986 calls [generic URI
syntax](https://tools.ietf.org/html/rfc3986#section-3). For example `http` and
`https` are standard schemes, while `file` is not.
A standard scheme adheres to what RFC 3986 calls
[generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3).
For example `http` and `https` are standard schemes, while `file` is not.

Registering a scheme as standard allows relative and absolute resources to
be resolved correctly when served. Otherwise the scheme will behave like the
Expand Down
11 changes: 11 additions & 0 deletions tests/fixtures/newline-in-link-text.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This has [a link
with a newline](https://google.com)

This has [a link
with a newline](https://google.com)

This has [
a link with a newline](https://google.com)

This has [a link with a newline
](https://google.com)