Skip to content

Commit 8c5b405

Browse files
committed
[repo] Various migration script fixes
- Look for inline code blocks - Replace `nowiki` with backticks - Attempt to handle links to interwiki translations better - Ensure that `<noinclude></noinclude>` tags are on their own line - Remove accidentally commited markdown lint config
1 parent ee7be19 commit 8c5b405

File tree

11 files changed

+276
-118
lines changed

11 files changed

+276
-118
lines changed

scripts/migration/phases/01-codeblocks/rule.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const {
2525

2626
const codeblockStart = /^<syntaxhighlight lang="(?<language>[^"]*)">/g;
2727
const codeblockEnd = /^<\/syntaxhighlight>/g;
28+
const codeblockSameLine = /(?<wholematch><syntaxhighlight lang="[^"]*">(?<content>.*)<\/syntaxhighlight>)/;
29+
const nowikiSameLine = /(?<wholematch><nowiki>(?<content>.*)<\/nowiki>)/;
2830

2931
module.exports = {
3032
names: ['convert-markup-codeblocks'],
@@ -33,6 +35,24 @@ module.exports = {
3335
function: function lint(params, onError) {
3436
forEachLine(getLineMetadata(params), (line, lineIndex) => {
3537
const lineNumber = lineIndex + 1;
38+
39+
const codeblockSameLineMatches = codeblockSameLine.exec(line);
40+
if (codeblockSameLineMatches) {
41+
console.log(codeblockSameLineMatches);
42+
addError(
43+
onError,
44+
lineNumber,
45+
codeblockSameLineMatches.input,
46+
codeblockSameLineMatches.input,
47+
[codeblockSameLineMatches.index + 1, codeblockSameLineMatches.groups.wholematch.length],
48+
{
49+
editColumn: codeblockSameLineMatches.index + 1,
50+
deleteCount: codeblockSameLineMatches.groups.wholematch.length,
51+
insertText: `\`${codeblockSameLineMatches.groups.content}\``,
52+
},
53+
);
54+
}
55+
3656
const codeblockStartMatches = codeblockStart.exec(line);
3757
if (codeblockStartMatches) {
3858
addError(
@@ -66,6 +86,22 @@ module.exports = {
6686
},
6787
);
6888
}
89+
90+
const nowikiSameLineMatches = nowikiSameLine.exec(line);
91+
if (nowikiSameLineMatches) {
92+
addError(
93+
onError,
94+
lineNumber,
95+
nowikiSameLineMatches.input,
96+
nowikiSameLineMatches.input,
97+
[nowikiSameLineMatches.index + 1, nowikiSameLineMatches.groups.wholematch.length],
98+
{
99+
editColumn: nowikiSameLineMatches.index + 1,
100+
deleteCount: nowikiSameLineMatches.groups.wholematch.length,
101+
insertText: `\`${nowikiSameLineMatches.groups.content}\``,
102+
},
103+
);
104+
}
69105
});
70106
},
71107
};

scripts/migration/phases/02-lists/rule.js

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,42 @@ const {
2323
getLineMetadata,
2424
} = require('markdownlint-rule-helpers');
2525

26-
const markupNumberedList = /^(?<marker># *)/;
26+
const markupNumberedList = /^(?<whole>(?<marker>#+) *)/;
27+
const markupBulletedList = /^(?<whole>(?<marker>\*+) *)/;
2728

2829
module.exports = {
2930
names: ['convert-markup-lists'],
3031
description: 'Convert markup lists to markdown lists',
3132
tags: ['migration'],
3233
function: function lint(params, onError) {
34+
const replaceListType = (line, lineNumber, listRegExp, insertText) => {
35+
const matches = listRegExp.exec(line);
36+
if (!matches) {
37+
return;
38+
}
39+
const linePrefix = ' '.repeat(matches.groups.marker.length - 1);
40+
addError(
41+
onError,
42+
lineNumber,
43+
matches.input,
44+
matches.input,
45+
[matches.index + 1, matches.input.length],
46+
{
47+
editColumn: matches.index + 1,
48+
deleteCount: matches.groups.whole.length,
49+
insertText: `${linePrefix}${insertText}`,
50+
},
51+
);
52+
};
53+
3354
forEachLine(getLineMetadata(params), (line, lineIndex, inCode) => {
3455
if (inCode) {
3556
return;
3657
}
3758

3859
const lineNumber = lineIndex + 1;
39-
40-
const numberedListMatches = markupNumberedList.exec(line);
41-
if (numberedListMatches) {
42-
addError(
43-
onError,
44-
lineNumber,
45-
numberedListMatches.input,
46-
numberedListMatches.input,
47-
[numberedListMatches.index + 1, numberedListMatches.input.length],
48-
{
49-
editColumn: numberedListMatches.index + 1,
50-
deleteCount: numberedListMatches.groups.marker.length,
51-
insertText: '1. ',
52-
},
53-
);
54-
}
60+
replaceListType(line, lineNumber, markupNumberedList, '1. ');
61+
replaceListType(line, lineNumber, markupBulletedList, '- ');
5562
});
5663
},
5764
};

scripts/migration/phases/03-headers/rule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ module.exports = {
4141
if (headerMatches) {
4242
const headerLevel = headerMatches.groups.marker.length;
4343
const headerMarkup = '#'.repeat(headerLevel);
44-
const headerText = headerMatches.groups.header.slice(0, 0 - headerLevel);
44+
const headerText = headerMatches.groups.header.slice(0, 0 - headerLevel).replace(/=*$/, '');
4545

4646
const fixInfo = {
4747
editColumn: 1,

scripts/migration/phases/05-wikilinks/rule.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,28 @@ const {
2626
const getWikilinkLink = (matches) => {
2727
const [link] = matches.groups.link.split('|');
2828

29-
return link
30-
.replaceAll(' ', '_');
29+
const normalisedLink = link.replaceAll(' ', '_');
30+
31+
if (link.indexOf(':') !== -1) {
32+
const pages = normalisedLink.split(':');
33+
const page = pages.pop();
34+
const lang = pages.pop();
35+
return `https://docs.moodle.org/${lang}/${page}`;
36+
}
37+
38+
return `https://docs.moodle.org/dev/${normalisedLink}`;
3139
};
3240

3341
const getWikilinkDescription = (matches) => {
3442
const [link, description] = matches.groups.link.split('|');
3543

3644
const value = description || link;
3745

46+
if (link.indexOf(':') !== -1 && !description) {
47+
const [, title] = link.split(':', 2);
48+
return title.replaceAll('_', ' ');
49+
}
50+
3851
return value
3952
.replaceAll('_', ' ');
4053
};
@@ -50,7 +63,7 @@ const replaceWikiLinks = (line, lineNumber, onError) => {
5063
const link = getWikilinkLink(matches);
5164
const description = getWikilinkDescription(matches);
5265
const column = matches.index + 1;
53-
const replacement = `[${description}](https://docs.moodle.org/dev/${link})`;
66+
const replacement = `[${description}](${link})`;
5467
const fixInfo = {
5568
editColumn: column,
5669
deleteCount: matches.groups.link.length + 4,

scripts/migration/phases/20-tables/.markdownlint-cli2.cjs renamed to scripts/migration/phases/10-noinclude/.markdownlint-cli2.cjs

File renamed without changes.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Copyright (c) Moodle Pty Ltd.
3+
*
4+
* Moodle is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Moodle is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
/* eslint-disable import/no-extraneous-dependencies */
19+
20+
const {
21+
addError,
22+
forEachLine,
23+
getLineMetadata,
24+
} = require('markdownlint-rule-helpers');
25+
26+
const search = /(?<match><\/?noinclude>)/;
27+
28+
const getFixInfo = (matches) => {
29+
if (matches.index === 0) {
30+
return {
31+
editColumn: matches.index + matches.groups.match.length + 1,
32+
deleteCount: 0,
33+
insertText: '\n\n',
34+
};
35+
}
36+
return {
37+
editColumn: matches.index + 1,
38+
deleteCount: 0,
39+
insertText: '\n\n',
40+
};
41+
};
42+
43+
module.exports = {
44+
names: ['noinclude-own-line'],
45+
description: 'The noinclude tag should be on its own line',
46+
tags: ['migration'],
47+
function: function lint(params, onError) {
48+
forEachLine(getLineMetadata(params), (line, lineIndex, inCode) => {
49+
if (inCode) {
50+
return;
51+
}
52+
53+
const lineNumber = lineIndex + 1;
54+
55+
const matches = search.exec(line);
56+
if (!matches) {
57+
return;
58+
}
59+
if (matches.input === matches.groups.match) {
60+
return;
61+
}
62+
63+
const fixInfo = getFixInfo(matches);
64+
addError(
65+
onError,
66+
lineNumber,
67+
matches.input,
68+
matches.input,
69+
[matches.index + 1, matches.groups.match.length],
70+
fixInfo,
71+
);
72+
});
73+
},
74+
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Copyright (c) Moodle Pty Ltd.
3+
*
4+
* Moodle is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Moodle is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
// For full details on all of these configuration settings:
19+
// https://github.com/DavidAnson/markdownlint-cli2#markdownlint-cli2cjs
20+
21+
const { getMigrationConfig } = require('../../markdownlint-cli2-config.cjs');
22+
const path = require('path');
23+
24+
module.exports = getMigrationConfig([
25+
path.join(__dirname, 'rule.js'),
26+
]);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* Copyright (c) Moodle Pty Ltd.
3+
*
4+
* Moodle is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* Moodle is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
/* eslint-disable import/no-extraneous-dependencies */
19+
20+
const {
21+
addError,
22+
forEachLine,
23+
getLineMetadata,
24+
} = require('markdownlint-rule-helpers');
25+
26+
module.exports = {
27+
names: ['convert-admonition'],
28+
description: 'Convert admonition-like paragraphs to admonitions',
29+
tags: ['migration'],
30+
function: function lint(params, onError) {
31+
const sameLineNote = /(?<admonition><p class="(?<type>note)">(?<content>.*?)(?=<\/p>)<\/p>)/g;
32+
const templateNote = /(?<admonition>\{\{Note\|(?<content>[^}]*)\}\})/;
33+
34+
const processMatches = (matches, lineNumber) => {
35+
if (!matches) {
36+
return;
37+
}
38+
addError(
39+
onError,
40+
lineNumber,
41+
matches.input,
42+
matches.input,
43+
[matches.index + 1, matches.groups.admonition.length],
44+
{
45+
editColumn: matches.index + 1,
46+
deleteCount: matches.groups.admonition.length,
47+
insertText: `\n\n:::${matches.groups?.type || 'note'}\n\n${matches.groups.content}\n\n:::\n\n`,
48+
},
49+
);
50+
};
51+
52+
forEachLine(getLineMetadata(params), (line, lineIndex, inCode) => {
53+
if (inCode) {
54+
// Do not make changes to code stanzas.
55+
return;
56+
}
57+
58+
const lineNumber = lineIndex + 1;
59+
60+
processMatches(sameLineNote.exec(line), lineNumber);
61+
processMatches(templateNote.exec(line), lineNumber);
62+
});
63+
},
64+
};

scripts/migration/phases/20-tables/migrate-table.mjs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ program
7575

7676
if (line.indexOf('|}') === 0) {
7777
inTable = false;
78-
tableData.body.push(tableData.currentRow);
78+
if (tableData.currentRow.length) {
79+
tableData.body.push(tableData.currentRow);
80+
}
7981
tableData.currentRow = [];
8082

8183
// Replace the table content.
@@ -114,14 +116,39 @@ program
114116

115117
// Process in reverse to make line ordering easier.
116118
replacements.reverse().forEach(({ tableLines: linesToReplace, tableData: thisTableData }) => {
117-
const newLines = [];
118-
if (thisTableData.header) {
119+
const newLines = [''];
120+
if (thisTableData.header.length) {
119121
newLines.push(`| ${thisTableData.header.join(' | ')} |`);
120122
newLines.push(`${'| --- '.repeat(thisTableData.header.length)}|`);
123+
thisTableData.body.forEach((row) => {
124+
newLines.push(`| ${row.join(' | ')} |`);
125+
});
126+
newLines.push('');
127+
} else {
128+
// GitHub Formatted Markdown does not support tables without a header.
129+
newLines.push('<!--');
130+
newLines.push(' Github Flavoured Markdown does not support tables without headers.');
131+
newLines.push(' We must use an HTML table here.');
132+
newLines.push(' Please note that Spacing in this table is important.');
133+
newLines.push(' Markdown must have empty newlines between it and HTML markup.');
134+
newLines.push('-->');
135+
newLines.push('<table><tbody>');
136+
thisTableData.body.forEach((row) => {
137+
let html = '<tr>';
138+
row.forEach((cell) => {
139+
html += '<td>';
140+
newLines.push(html);
141+
html = '';
142+
newLines.push('');
143+
newLines.push(cell);
144+
newLines.push('');
145+
html += '</td>';
146+
});
147+
html += '</tr>';
148+
newLines.push(html);
149+
});
150+
newLines.push('</tbody></table>');
121151
}
122-
thisTableData.body.forEach((row) => {
123-
newLines.push(`| ${row.join(' | ')} |`);
124-
});
125152

126153
lines.splice(linesToReplace[0], linesToReplace.length, ...newLines);
127154

0 commit comments

Comments
 (0)