2021-03-20 06:29:13 +00:00
|
|
|
const { cloneDeep } = require('lodash');
|
2020-02-24 14:05:18 +00:00
|
|
|
|
|
|
|
exports.translateComments = (text, lang, dict, codeLang) => {
|
|
|
|
const knownComments = Object.keys(dict);
|
|
|
|
const config = { knownComments, dict, lang };
|
2021-03-20 06:29:13 +00:00
|
|
|
const input = { text, commentCounts: new Map() };
|
2020-02-24 14:05:18 +00:00
|
|
|
switch (codeLang) {
|
|
|
|
case 'js':
|
|
|
|
case 'jsx':
|
2021-03-20 06:29:13 +00:00
|
|
|
return transMultiline(transInline(input, config), config);
|
2020-02-24 14:05:18 +00:00
|
|
|
case 'html':
|
2021-03-20 06:29:13 +00:00
|
|
|
return transScript(transHTML(transCSS(input, config), config), config);
|
2020-02-24 14:05:18 +00:00
|
|
|
default:
|
2021-03-20 06:29:13 +00:00
|
|
|
return input;
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-09-09 16:08:38 +00:00
|
|
|
exports.translateCommentsInChallenge = (challenge, lang, dict) => {
|
2021-02-03 09:46:27 +00:00
|
|
|
const challClone = cloneDeep(challenge);
|
2020-09-28 13:13:18 +00:00
|
|
|
if (!challClone.files) {
|
2021-03-16 15:22:39 +00:00
|
|
|
console.warn(`Challenge ${challClone.title} has no seed to translate`);
|
2020-09-28 13:13:18 +00:00
|
|
|
} else {
|
|
|
|
Object.keys(challClone.files).forEach(key => {
|
|
|
|
if (challClone.files[key].contents) {
|
2021-03-20 06:29:13 +00:00
|
|
|
let { text, commentCounts } = this.translateComments(
|
2020-09-28 13:13:18 +00:00
|
|
|
challenge.files[key].contents,
|
|
|
|
lang,
|
|
|
|
dict,
|
|
|
|
challClone.files[key].ext
|
|
|
|
);
|
2021-03-20 06:29:13 +00:00
|
|
|
challClone.__commentCounts = commentCounts;
|
|
|
|
challClone.files[key].contents = text;
|
2020-09-28 13:13:18 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2020-02-24 14:05:18 +00:00
|
|
|
return challClone;
|
|
|
|
};
|
|
|
|
|
|
|
|
// bare urls could be interpreted as comments, so we have to lookbehind for
|
|
|
|
// http:// or https://
|
2021-03-20 06:29:13 +00:00
|
|
|
function transInline(input, config) {
|
|
|
|
return translateGeneric(input, config, '((?<!https?:)//\\s*)', '(\\s*$)');
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
|
2021-03-20 06:29:13 +00:00
|
|
|
function transMultiline(input, config) {
|
|
|
|
return translateGeneric(input, config, '(/\\*\\s*)', '(\\s*\\*/)');
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CSS has to be handled separately since it is looking for comments inside tags
|
2021-03-20 06:29:13 +00:00
|
|
|
function transCSS({ text, commentCounts }, config) {
|
2020-02-24 14:05:18 +00:00
|
|
|
const regex = /<style>.*?<\/style>/gms;
|
|
|
|
const matches = text.matchAll(regex);
|
|
|
|
|
|
|
|
for (const [match] of matches) {
|
2021-03-20 06:29:13 +00:00
|
|
|
let { text: styleText } = transMultiline(
|
|
|
|
{ text: match, commentCounts },
|
|
|
|
config
|
|
|
|
);
|
|
|
|
text = text.replace(match, styleText);
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
2021-03-20 06:29:13 +00:00
|
|
|
return { text, commentCounts };
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
|
2021-03-20 06:29:13 +00:00
|
|
|
function transScript({ text, commentCounts }, config) {
|
2020-09-28 13:13:18 +00:00
|
|
|
const regex = /<script>.*?<\/script>/gms;
|
|
|
|
const matches = text.matchAll(regex);
|
|
|
|
|
|
|
|
for (const [match] of matches) {
|
2021-03-20 06:29:13 +00:00
|
|
|
let { text: scriptText } = transMultiline(
|
|
|
|
transInline({ text: match, commentCounts }, config),
|
|
|
|
config
|
2020-09-28 13:13:18 +00:00
|
|
|
);
|
2021-03-20 06:29:13 +00:00
|
|
|
text = text.replace(match, scriptText);
|
2020-09-28 13:13:18 +00:00
|
|
|
}
|
2021-03-20 06:29:13 +00:00
|
|
|
return { text, commentCounts };
|
|
|
|
}
|
|
|
|
|
|
|
|
function transHTML(input, config) {
|
|
|
|
return translateGeneric(input, config, '(<!--\\s*)', '(\\s*-->)');
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
|
2021-03-20 06:29:13 +00:00
|
|
|
function updateCounts(map, key) {
|
|
|
|
if (map.has(key)) {
|
|
|
|
map.set(key, map.get(key) + 1);
|
|
|
|
} else {
|
|
|
|
map.set(key, 1);
|
|
|
|
}
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
|
2021-03-20 06:29:13 +00:00
|
|
|
function translateGeneric(
|
|
|
|
{ text, commentCounts },
|
|
|
|
config,
|
|
|
|
regexBefore,
|
|
|
|
regexAfter
|
|
|
|
) {
|
2020-02-24 14:05:18 +00:00
|
|
|
const { knownComments, dict, lang } = config;
|
|
|
|
const regex = new RegExp(regexBefore + '(.*?)' + regexAfter, 'gms');
|
|
|
|
const matches = text.matchAll(regex);
|
|
|
|
|
|
|
|
for (const [match, before, comment, after] of matches) {
|
|
|
|
if (knownComments.includes(comment)) {
|
2021-03-20 06:29:13 +00:00
|
|
|
updateCounts(commentCounts, dict[comment][lang]);
|
2020-02-24 14:05:18 +00:00
|
|
|
text = text.replace(match, `${before}${dict[comment][lang]}${after}`);
|
2021-02-03 09:43:32 +00:00
|
|
|
} else if (comment.trim()) {
|
|
|
|
throw `${comment} does not appear in the comment dictionary`;
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-20 06:29:13 +00:00
|
|
|
return { text, commentCounts };
|
2020-02-24 14:05:18 +00:00
|
|
|
}
|
2021-03-20 06:29:13 +00:00
|
|
|
|
|
|
|
exports.translateGeneric = translateGeneric;
|