Skip to content

Commit 07b160b

Browse files
committed
✨ fix extra whitespace problems in bad-linebreaks run
1 parent a0054a1 commit 07b160b

File tree

5 files changed

+87
-44
lines changed

5 files changed

+87
-44
lines changed

.eslintrc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ module.exports = {
1212
"arrow-spacing": "error",
1313
"brace-style": ["error", "1tbs"],
1414
"keyword-spacing": "error",
15-
"object-curly-spacing": ["error", "always"]
15+
"object-curly-spacing": ["error", "always"],
16+
"semi": ["error", "always"],
1617
},
1718
overrides: [
1819
{

scripts/bad-linebreaks-test.mjs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
import { strict as assert } from 'node:assert';
2-
import { findBadLinebreaks } from './bad-linebreaks.mjs';
2+
import { findBadStuff } from './bad-linebreaks.mjs';
33
import fs from 'fs';
44
import crypto from 'crypto';
55

66
const afterMD = './scripts/test-samples/bad-linebreaks-sample-after.md';
77
const beforeMD = './scripts/test-samples/bad-linebreaks-sample-before.md';
88

99
// verify hash values to detect file tampering
10-
const knownAfterHash = '5e03eeb87149ca238ab55d422913c0f8';
11-
const knownBeforeHash = '1f2c5d3956a9aceb29dd2b872c20a021';
10+
const knownAfterHash = 'c2b5b7cc30cf5d4ce28274848eeba743';
11+
const knownBeforeHash = 'c9cf57714ec19de2aeea68d45536b119';
1212
const afterHash = await getHashSlingingSlasher(afterMD);
1313
const beforeHash = await getHashSlingingSlasher(beforeMD);
1414
assert.strictEqual(afterHash, knownAfterHash);
1515
assert.strictEqual(beforeHash, knownBeforeHash);
1616

1717
let fixed, totalMatches;
1818

19-
({ fixed, totalMatches } = findBadLinebreaks(beforeMD, true));
20-
assert.strictEqual(totalMatches, 12);
19+
({ fixed, totalMatches } = findBadStuff(beforeMD, true));
20+
assert.strictEqual(totalMatches.badLinebreaks, 12);
21+
assert.strictEqual(totalMatches.extraWhitespace, 28);
2122
assert.strictEqual(fixed, fs.readFileSync(afterMD, 'utf8').toString());
2223

23-
({ fixed, totalMatches } = findBadLinebreaks(afterMD, true));
24-
assert.strictEqual(totalMatches, 0);
24+
({ fixed, totalMatches } = findBadStuff(afterMD, true));
25+
assert.strictEqual(totalMatches.badLinebreaks, 0);
26+
assert.strictEqual(totalMatches.extraWhitespace, 0);
2527
assert.strictEqual(fixed, fs.readFileSync(afterMD, 'utf8').toString());
2628

27-
({ fixed, totalMatches } = findBadLinebreaks(beforeMD));
28-
assert.strictEqual(totalMatches, 12);
29+
({ fixed, totalMatches } = findBadStuff(beforeMD));
30+
assert.strictEqual(totalMatches.badLinebreaks, 12);
31+
assert.strictEqual(totalMatches.extraWhitespace, 28);
2932

3033
function getHashSlingingSlasher(file) { // 💀
3134
return new Promise((res, rej) => {

scripts/bad-linebreaks.mjs

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,54 +7,84 @@ import { glob } from 'glob';
77
// import attributes when?
88
const mdlintConfig = JSON.parse(fs.readFileSync('.markdownlint-cli2.jsonc', 'utf8').toString());
99

10-
const re = /(?<=[\w\d ])\n(?=[\w\d ])/g;
10+
const reBadLinebreaks = /(?<=[\w\d ])\n(?=[\w\d ])/g;
11+
const reExtraWhitespace = /^ +| (?= )| +$/gm;
1112

12-
export function findBadLinebreaks(file, fix = false) {
13+
export function findBadStuff(file, fix = false) {
1314

1415
let contents = fs.readFileSync(file, 'utf8').toString();
1516

16-
const tokens = marked.lexer(contents, { ...marked.getDefaults(), })
17+
const tokens = marked.lexer(contents, { ...marked.getDefaults(), });
1718

1819
const o = [];
19-
let totalMatches = 0;
20+
const totalMatches = { badLinebreaks: 0, extraWhitespace: 0 };
2021

2122
for (let i = 0; i < tokens.length; i++) {
2223

2324
const t = tokens[i];
25+
let tokenContent = t.raw;
2426

2527
if (t.type === 'paragraph') {
28+
tokenContent = findBadLinebreaks(tokenContent, totalMatches, fix, file);
29+
tokenContent = findExtraWhitespace(tokenContent, totalMatches, fix, file);
30+
}
2631

27-
const matches = Array.from(t.raw.matchAll(re));
28-
totalMatches += matches.length;
32+
// we don't need to build this array if `fix` is `false`, but this keeps complexity down
33+
o.push(tokenContent);
2934

30-
if (fix) {
31-
if (matches.length > 0) {
35+
}
3236

33-
let fixedContent = t.raw;
37+
return {
38+
fixed: o.join(''),
39+
totalMatches,
40+
};
3441

35-
for (const m of matches) {
36-
fixedContent = `${fixedContent.slice(0, m.index)} ${fixedContent.slice(m.index + 1)}`;
37-
}
42+
}
3843

39-
o.push(fixedContent);
44+
function findBadLinebreaks(tokenContent, totalMatches, fix, file) {
4045

41-
} else {
42-
o.push(t.raw);
43-
}
44-
} else if (matches.length > 0) {
45-
console.log(`${file}\nfound paragraph with ${matches.length} erroneous linebreak(s):\n${t.raw}\n`);
46+
const matches = Array.from(tokenContent.matchAll(reBadLinebreaks));
47+
totalMatches.badLinebreaks += matches.length;
48+
49+
if (fix) {
50+
51+
if (matches.length > 0) {
52+
53+
let fixedContent = tokenContent;
54+
55+
for (const m of matches) {
56+
fixedContent = `${fixedContent.slice(0, m.index)} ${fixedContent.slice(m.index + 1)}`;
4657
}
4758

48-
} else if (fix) {
49-
o.push(t.raw);
59+
return fixedContent;
60+
5061
}
5162

63+
} else if (matches.length > 0) {
64+
console.error(`${file}\nfound paragraph with ${matches.length} erroneous linebreak(s):\n${tokenContent}\n`);
5265
}
5366

54-
return {
55-
fixed: o.join(''),
56-
totalMatches,
57-
};
67+
return tokenContent;
68+
69+
}
70+
71+
function findExtraWhitespace(tokenContent, totalMatches, fix, file) {
72+
73+
const matches = Array.from(tokenContent.matchAll(reExtraWhitespace));
74+
const extraWhitespaceCharacters = matches.join('').length;
75+
totalMatches.extraWhitespace += extraWhitespaceCharacters;
76+
77+
if (fix) {
78+
79+
if (matches.length > 0) {
80+
return tokenContent.replace(reExtraWhitespace, '');
81+
}
82+
83+
} else if (matches.length > 0) {
84+
console.error(`${file}\nfound paragraph with ${extraWhitespaceCharacters} extra whitespace character(s):\n${tokenContent}\n`);
85+
}
86+
87+
return tokenContent;
5888

5989
}
6090

@@ -69,17 +99,26 @@ export async function processFiles(fix) {
6999

70100
for (const f of files) {
71101

72-
const { fixed, totalMatches } = findBadLinebreaks(f, fix);
102+
const { fixed, totalMatches } = findBadStuff(f, fix);
73103

74104
if (fix) {
75105
fs.writeFileSync(f, fixed);
76106
}
77107

78-
if (totalMatches > 0) {
108+
if (totalMatches.badLinebreaks > 0 || totalMatches.extraWhitespace > 0) {
79109

80110
if (fix) {
81-
console.log(`fixed ${totalMatches} erroneous linebreaks in ${f}`);
111+
112+
if (totalMatches.badLinebreaks > 0) {
113+
console.log(`fixed ${totalMatches.badLinebreaks} erroneous linebreak(s) in ${f}`);
114+
}
115+
116+
if (totalMatches.extraWhitespace > 0) {
117+
console.log(`fixed ${totalMatches.extraWhitespace} extra whitespace character(s) in ${f}`);
118+
}
119+
82120
} else {
121+
console.error('fix bad linebreaks and whitespace by running `npm run bad-linebreaks:fix` or `npm run fix:all`');
83122
process.exitCode = 1;
84123
}
85124

scripts/test-samples/bad-linebreaks-sample-after.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ AAA: Lorem.
1111

1212
BBB: This is a sentence.
1313

14-
CCC: This is a sentence with trailing spaces.
14+
CCC: This is a sentence with trailing spaces.
1515

1616
CCC: This is a sentence.
1717
DDD: This is also a sentence.
@@ -40,9 +40,9 @@ let biscuits = "delicious";
4040

4141
## story time!
4242

43-
True! nervous, very, very dreadfully nervous I had been and am; but why will you say that I am mad? The disease had sharpened my senses, not destroyed, not dulled them. Above all was the sense of hearing acute. I heard all things in the heaven and in the earth. I heard many things in hell. How then am I mad? Hearken! and observe how healthily, how calmly I can tell you the whole story.
43+
True! nervous, very, very dreadfully nervous I had been and am; but why will you say that I am mad? The disease had sharpened my senses, not destroyed, not dulled them. Above all was the sense of hearing acute. I heard all things in the heaven and in the earth. I heard many things in hell. How then am I mad? Hearken! and observe how healthily, how calmly I can tell you the whole story.
4444

45-
It is impossible to say how first the idea entered my brain, but, once conceived, it haunted me day and night. Object there was none. Passion there was none. I loved the old man. He had never wronged me. He had never given me insult. For his gold I had no desire. I think it was his eye! Yes, it was this! One of his eyes resembled that of a vulture—a pale blue eye with a film over it. Whenever it fell upon me my blood ran cold, and so by degrees, very gradually, I made up my mind to take the life of the old man, and thus rid myself of the eye forever.
45+
It is impossible to say how first the idea entered my brain, but, once conceived, it haunted me day and night. Object there was none. Passion there was none. I loved the old man. He had never wronged me. He had never given me insult. For his gold I had no desire. I think it was his eye! Yes, it was this! One of his eyes resembled that of a vulture—a pale blue eye with a film over it. Whenever it fell upon me my blood ran cold, and so by degrees, very gradually, I made up my mind to take the life of the old man, and thus rid myself of the eye forever.
4646

4747
Now this is the point. You fancy me mad. Madmen know nothing. But you should have seen me. You should have seen how wisely I proceeded; with what caution, with what foresight, with what dissimulation, I went to work! I was never kinder to the old man than during the whole week before I killed him. And every night about midnight I turned the latch of his door and opened it—oh, so gently! And then when I had made an opening sufficient for my head I put in a dark lantern all closed, closed so that no light shone out, and then I thrust in my head. Oh, you would have laughed to see how cunningly I thrust it in! I moved it slowly, very, very slowly, so that I might not disturb the old man's sleep. It took me an hour to place my whole head within the opening so far that I could see him as he lay upon his bed. Ha! would a madman have been so wise as this? And then when my head was well in the room I undid the lantern cautiously—oh, so cautiously—cautiously (for the hinges creaked), I undid it just so much that a single thin ray fell upon the vulture eye. And this I did for seven long nights, every night just at midnight, but I found the eye always closed, and so it was impossible to do the work, for it was not the old man who vexed me, but his Evil Eye. And every morning, when the day broke, I went boldly into the chamber and spoke courageously to him, calling him by name in a hearty tone, and inquiring how he had passed the night. So you see he would have been a very profound old man, indeed, to suspect that every night, just at twelve, I looked in upon him while he slept.
4848

@@ -61,8 +61,8 @@ It was open, wide, wide open, and I grew furious as I gazed upon it. I saw it wi
6161
And now have I not told you that what you mistake for madness is but over-acuteness of the senses? now, I say, there came to my ears a low, dull, quick sound, such as a watch makes when enveloped in cotton. I knew that sound well, too. It was the beating of the old man's heart. It increased my fury, as the beating of a drum stimulates the soldier into courage.
6262

6363
But even yet I refrained and kept still. I scarcely breathed. I held the lantern motionless. I tried how steadily I could maintain the ray upon the eye. Meantime the hellish tattoo of the heart increased. It grew quicker and quicker, and louder and louder, every instant. The old man's terror must have been extreme! It grew louder, I say, louder every moment!—do you mark me well? I have told you that I am nervous: so I am. And now at the dead hour of the night, amid the dreadful silence of that old house, so strange a noise as this excited me to uncontrollable terror. Yet, for some minutes longer I refrained and stood still. But the beating grew louder, louder! I thought the heart must burst. And now a new anxiety seized me—the sound would be heard by a neighbor!
64-
The old man's hour had come! With a loud yell, I threw open the lantern and leaped into the room. He shrieked once—once only. In an instant I dragged him to the floor, and pulled the heavy bed over him. I then smiled gaily, to find the deed so far done. But for many minutes the heart beat on with a muffled sound. This, however, did not vex me; it would not be heard through the wall. At length it ceased. The old man was dead. I removed the bed and examined the corpse.
65-
Yes, he was stone, stone dead. I placed my hand upon the heart and held it there many minutes.
64+
The old man's hour had come! With a loud yell, I threw open the lantern and leaped into the room. He shrieked once—once only. In an instant I dragged him to the floor, and pulled the heavy bed over him. I then smiled gaily, to find the deed so far done. But for many minutes the heart beat on with a muffled sound. This, however, did not vex me; it would not be heard through the wall. At length it ceased. The old man was dead. I removed the bed and examined the corpse.
65+
Yes, he was stone, stone dead. I placed my hand upon the heart and held it there many minutes.
6666
There was no pulsation. He was stone dead. His eye would trouble me no more.
6767

6868
If still you think me mad, you will think so no longer when I describe the wise precautions I took for the concealment of the body. The night waned, and I worked hastily, but in silence.
@@ -74,7 +74,7 @@ When I had made an end of these labors, it was four o'clock—still dark as midn
7474
I smiled—for what had I to fear? I bade the gentlemen welcome. The shriek, I said, was my own in a dream. The old man, I mentioned, was absent in the country. I took my visitors all over the house. I bade them search—search well. I led them, at length, to his chamber.
7575
I showed them his treasures, secure, undisturbed. In the enthusiasm of my confidence, I brought chairs into the room, and desired them here to rest from their fatigues, while I myself, in the wild audacity of my perfect triumph, placed my own seat upon the very spot beneath which reposed the corpse of the victim.
7676

77-
The officers were satisfied. My manner had convinced them. I was singularly at ease. They sat, and while I answered cheerily, they chatted of familiar things. But, ere long, I felt myself getting pale and wished them gone. My head ached, and I fancied a ringing in my ears; but still they sat, and still chatted. The ringing became more distinct;—it continued and became more distinct. I talked more freely to get rid of the feeling, but it continued and gained definitiveness—until, at length, I found that the noise was not within my ears.
77+
The officers were satisfied. My manner had convinced them. I was singularly at ease. They sat, and while I answered cheerily, they chatted of familiar things. But, ere long, I felt myself getting pale and wished them gone. My head ached, and I fancied a ringing in my ears; but still they sat, and still chatted. The ringing became more distinct;—it continued and became more distinct. I talked more freely to get rid of the feeling, but it continued and gained definitiveness—until, at length, I found that the noise was not within my ears.
7878

7979
No doubt I now grew very pale; but I talked more fluently and with a heightened voice. Yet the sound increased—and what could I do? It was a low, dull, quick sound—much such a sound as a watch makes when enveloped in cotton. I gasped for breath—and yet the officers heard it not. I talked more quickly—more vehemently; but the noise steadily increased. I arose and argued about trifles, in a high key and with violent gesticulations; but the noise steadily increased. Why would they not be gone? I paced the floor to and fro with heavy strides, as if excited to fury by the observations of the men—but the noise steadily increased. O God! what could I do? I foamed—I raved—I swore! I swung the chair upon which I had been sitting, and grated it upon the boards, but the noise arose over all and continually increased. It grew louder—louder—louder! And still the men chatted pleasantly, and smiled. Was it possible they heard not? Almighty God!—no, no! They heard!—they suspected!—they knew!—they were making a mockery of my horror!—this I thought, and this I think. But anything was better than this agony! Anything was more tolerable than this derision! I could bear those hypocritical smiles no longer! I felt that I must scream or die!—and now—again!—hark! louder! louder! louder! louder!
8080

scripts/test-samples/bad-linebreaks-sample-before.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Ye Olde Meeting Notes
22

3-
this file has deliberate linting problems... do not fix.
3+
this file has deliberate linting problems... do not fix.
44

55
| ye | olde | table |
66
|------|------|-------|

0 commit comments

Comments
 (0)