Skip to content

Commit 0407f00

Browse files
kaicataldolipis
authored andcommitted
Feature: respect language-all comments for StackOverflow (#27)
1 parent e77dd4d commit 0407f00

File tree

1 file changed

+85
-31
lines changed

1 file changed

+85
-31
lines changed

ext/src/content/content.js

Lines changed: 85 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
function init() {
44
const GITHUB_URL = "https://github.com";
55
const GITHUB_VALID_PATHNAMES = /^\/.*\/.*\/(?:pull\/\d+(?:\/?|\/files\/?)$|commit|compare\/.*|issues\/\d+|issues\/new)/u;
6+
const POLLING_INTERVAL = 30;
67
let isGithubListenerAdded = false;
78

89
const STACKOVERFLOW_URL = "https://stackoverflow.com";
@@ -190,6 +191,7 @@ function init() {
190191
const codeBlocks = inputEl.value.split("\n").reduce((groups, line) => {
191192
const codeBlockRegex = /^\s{0,3}(?:```|~~~)/u;
192193
const indentedCodeLangRegex = /^\s*<!-- language: lang-.* -->/u;
194+
const langAllRegex = /^\s*<!-- language-all: lang-.+ -->/u;
193195
const emptyLineRegex = /^\s*$/u;
194196
const indentedCodeBlockRegex = /^\s{4}/u;
195197
const codeSnippetRegex = /`{1,2}[^\n`]+`{1,2}/u;
@@ -225,7 +227,7 @@ function init() {
225227
* ``const foo = `${bar}`;``
226228
*/
227229
} else if (codeSnippetRegex.test(line)) {
228-
groups.push(line);
230+
groups.push([line]);
229231

230232
/*
231233
* Code blocks using indented lines:
@@ -257,6 +259,13 @@ function init() {
257259
} else {
258260
groups.push([line]);
259261
}
262+
/*
263+
* language-all comments:
264+
*
265+
* <!-- language-all: lang-js -->
266+
*/
267+
} else if (langAllRegex.test(line)) {
268+
groups.push([line]);
260269
}
261270

262271
return groups;
@@ -268,50 +277,95 @@ function init() {
268277
}
269278

270279
if (codeBlocks.length) {
271-
/*
272-
* TODO: Add support for language-all: <!-- language-all: lang-* -->
273-
* Once this support is added, we can format inline code snippets (i.e. `const foo = 'bar';`).
274-
* https://stackoverflow.com/editing-help#syntax-highlighting
275-
*/
280+
let langAll = null;
281+
282+
// https://stackoverflow.com/editing-help#syntax-highlighting
276283
codeBlocks.forEach(lines => {
277-
const codeBlockRegex = /^\s{0,3}(?:```|~~~)\s*lang-(.+)/u;
278-
const indentedCodeRegex = /^\s*<!-- language: lang-(.+) -->/u;
284+
const codeBlockRegex = /^\s{0,3}(?:```|~~~)\s*(?:lang-(.+))?/u;
285+
const indentedCodeWithLangRegex = /^\s*<!-- language: lang-(.+) -->/u;
286+
const langAllRegex = /^\s*<!-- language-all: lang-(.+) -->/u;
287+
const codeSnippetRegex = /(`{1,2})([^\n`]+)(`{1,2})/gu;
279288
const [firstLine] = lines;
280-
const [, lang = null] =
289+
290+
if (langAllRegex.test(firstLine)) {
291+
[, langAll = null] = firstLine.match(langAllRegex);
292+
return;
293+
}
294+
295+
const [, lang = langAll] =
281296
firstLine.match(codeBlockRegex) ||
282-
firstLine.match(indentedCodeRegex) ||
297+
firstLine.match(indentedCodeWithLangRegex) ||
283298
[];
284299

285300
if (!lang) {
286301
return;
287302
}
288303

289-
const isCodeBlock = codeBlockRegex.test(firstLine);
290-
const indentedLineCodeBlockStartIdx = 2;
291-
const codeLines = isCodeBlock
292-
? lines.slice(1, -1)
293-
: lines.slice(indentedLineCodeBlockStartIdx);
294-
let formattedBlock = window.prettier.format(codeLines.join("\n"), {
295-
parser: PARSERS_LANG_MAP[lang],
296-
plugins: window.prettierPlugins
297-
});
298-
299-
// Prettier adds a trailing newline
300-
if (codeLines.length !== formattedBlock.split("\n").length) {
301-
formattedBlock = formattedBlock.replace(/\n$/u, "");
302-
}
304+
let formattedText = lines.join("\n");
305+
306+
// Code Snippets
307+
if (codeSnippetRegex.test(firstLine)) {
308+
formattedText = firstLine.replace(
309+
codeSnippetRegex,
310+
(match, openingBackticks, snippet, closingBackticks) => {
311+
let formattedSnippet = snippet;
312+
313+
try {
314+
formattedSnippet = window.prettier.format(snippet, {
315+
parser: PARSERS_LANG_MAP[lang],
316+
plugins: window.prettierPlugins
317+
});
318+
} catch {}
303319

304-
formattedBlock = isCodeBlock
305-
? `${firstLine}\n${formattedBlock}\n${lines[lines.length - 1]}`
306-
: `${firstLine}\n${lines[1]}\n ${
307-
formattedBlock.split("\n").length > 1
308-
? formattedBlock.split("\n").join("\n ")
309-
: formattedBlock
320+
return `${openingBackticks}${formattedSnippet}${closingBackticks}`;
321+
}
322+
);
323+
324+
// Code Blocks
325+
} else {
326+
const isCodeBlock = codeBlockRegex.test(firstLine);
327+
const isIndentedBlockWithLang = indentedCodeWithLangRegex.test(
328+
firstLine
329+
);
330+
let codeLines;
331+
332+
if (isCodeBlock) {
333+
codeLines = codeLines.slice(1, -1);
334+
} else {
335+
const indentedLineCodeBlockStartIdx = 2;
336+
codeLines = isIndentedBlockWithLang
337+
? lines.slice(indentedLineCodeBlockStartIdx)
338+
: lines;
339+
}
340+
341+
try {
342+
formattedText = window.prettier.format(codeLines.join("\n"), {
343+
parser: PARSERS_LANG_MAP[lang],
344+
plugins: window.prettierPlugins
345+
});
346+
} catch {
347+
return;
348+
}
349+
350+
if (isCodeBlock) {
351+
formattedText = `${firstLine}\n${formattedText}\n${
352+
lines[lines.length - 1]
310353
}`;
354+
} else {
355+
const langComment = isIndentedBlockWithLang
356+
? `${firstLine}\n${lines[1]}\n`
357+
: "";
358+
formattedText = `${langComment} ${
359+
formattedText.split("\n").length > 1
360+
? formattedText.split("\n").join("\n ")
361+
: formattedText
362+
}`;
363+
}
364+
}
311365

312366
inputEl.value = inputEl.value.replace(
313367
lines.join("\n"),
314-
formattedBlock
368+
formattedText
315369
);
316370
});
317371
}

0 commit comments

Comments
 (0)