Files
scripts
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
parent directory.. | ||||
import path from "path"
import fs from "fs-extra"
import { escapeHtml } from "./utils"
import { resolveInfo } from "./loader"
import { QUIZ_ROOT, REPO, DIFFICULTY_COLORS, DIFFICULTY_RANK } from "./configs"
import { defaultLocale, f, SupportedLocale, supportedLocales, t } from "./locales"
import { generateBadge, generateBadgeLink, generateDifficultyBadge, generateDifficultyBadgeInverted } from "./badge"
import type { Quiz, QuizMetaInfo } from "./types"
export function getNearborREADME(quiz: Quiz, locale?: string) {
return locale && locale !== defaultLocale && quiz.readme[locale]
? `./README.${locale}.md`
: "./README.md"
}
export function generateShareAnswerLink(quiz: Quiz, locale: string = defaultLocale) {
const info = resolveInfo(quiz, locale)
if (locale === defaultLocale)
return `https://github.com/webfansplz/vuejs-challenges/issues/new?labels=answer,${encodeURIComponent(locale)}&template=0-answer.md&title=${encodeURIComponent(`${quiz.no} - ${info.title}`)}`
else
return `https://github.com/webfansplz/vuejs-challenges/issues/new?labels=answer,${encodeURIComponent(locale)}&template=1-answer.${locale}.md&title=${encodeURIComponent(`${quiz.no} - ${info.title}`)}`
}
export function generateSolutionsLink(no: number) {
return `${REPO}/issues?q=label%3A${no}+label%3Aanswer`
}
function generateAuthorInfo(author: Partial<QuizMetaInfo["author"]> = {}) {
return `By ${author.name}${author.github ? ` <a href="https://github.com/${author.github}" target="_blank">@${author.github}</a>` : ""}`
}
export function generateQuizREADME(quiz: Quiz, locale?: string, absolute = false) {
const prefix = absolute ? `${REPO}/blob/master` : "."
return locale && locale !== defaultLocale && quiz.readme[locale]
? `${prefix}/questions/${quiz.path}/README.${locale}.md`
: `${prefix}/questions/${quiz.path}/README.md`
}
function quizToBadge(quiz: Quiz, locale: string, absolute = false) {
const info = resolveInfo(quiz, locale)
return generateBadgeLink(
generateQuizREADME(quiz, locale, absolute),
"",
`${quiz.no}・${quiz.info![locale]?.title || quiz.info![defaultLocale]?.title}`,
DIFFICULTY_COLORS[info.difficulty],
)
}
export function getAllTags(quizes: Quiz[], locale: string) {
const set = new Set<string>()
for (const quiz of quizes) {
const info = resolveInfo(quiz, locale)
for (const tag of (info?.tags || []))
set.add(tag as string)
}
return Array.from(set).sort()
}
export function getQuizesByTag(quizes: Quiz[], locale: string, tag: string) {
return quizes.filter((quiz) => {
const info = resolveInfo(quiz, locale)
return !!info.tags?.includes(tag)
})
}
async function insertInfoToREADME(filepath: string, quiz: Quiz, locale: SupportedLocale) {
if (!fs.existsSync(filepath))
return
const text = await fs.readFile(filepath, "utf-8")
/* eslint-disable prefer-template */
const info = resolveInfo(quiz, locale)
if (Object.keys(info).length === 0) return
const availableLocales = supportedLocales.filter(l => l !== locale).filter(l => !!quiz.readme[l])
const fileContent = text
.replace(
/<!--info-header-start-->[\s\S]*<!--info-header-end-->/,
"<!--info-header-start-->"
+ `<h1>${escapeHtml(info.title || "")} ${generateDifficultyBadge(info.difficulty, locale)} ${(info.tags || []).map(i => generateBadge("", `#${i}`, "999")).join(" ")}</h1>`
+ `<blockquote><p>${generateAuthorInfo(info.author)}</p></blockquote>`
+ "<p>"
+ generateBadgeLink(quiz.quizLink, "", t(locale, "badge.take-the-challenge"), "213547", "?logo=vue.js&logoColor=42b883")
+ (availableLocales.length ? (" " + availableLocales.map(l => generateBadgeLink(getNearborREADME(quiz, l), "", t(l, "display"), "gray")).join(" ")) : "")
// + (quiz.stackblitzLink[locale]
// ? " " + `<a href=${quiz.stackblitzLink[locale]}>${t(locale, "badge.take-the-challenge-unit-test")}</a>`
// : "")
+ "</p>"
+ "<!--info-header-end-->",
)
.replace(
/<!--info-footer-start-->[\s\S]*<!--info-footer-end-->/,
"<!--info-footer-start--><br>"
+ generateBadgeLink(`../../${f("README", locale, "md")}`, "", t(locale, "badge.back"), "grey")
+ generateBadgeLink(generateShareAnswerLink(quiz, locale), "", t(locale, "badge.share-your-solutions"), "teal")
+ generateBadgeLink(generateSolutionsLink(quiz.no), "", t(locale, "badge.checkout-solutions"), "de5a77", "?logo=awesome-lists&logoColor=white")
+ "<!--info-footer-end-->",
)
await fs.writeFile(filepath, fileContent, "utf-8")
}
export async function updateQuizREADME(quizes: Quiz[]) {
// update each questions' readme
for (const quiz of quizes) {
for (const locale of supportedLocales) {
await insertInfoToREADME(
path.join(
QUIZ_ROOT,
quiz.path,
f("README", locale, "md"),
),
quiz,
locale,
)
}
}
}
export async function updateIndexREADME(quizes: Quiz[]) {
// update index README
for (const locale of supportedLocales) {
const filepath = path.resolve(__dirname, "..", f("README", locale, "md"))
let challengesREADME = ""
let prev = ""
// By Difficulty
const quizesByDifficulty = [...quizes].sort((a, b) => {
const preInfo = resolveInfo(a, locale)
const activeInfo = resolveInfo(b, locale)
return DIFFICULTY_RANK.indexOf(preInfo.difficulty!) - DIFFICULTY_RANK.indexOf(activeInfo.difficulty!)
})
for (const quiz of quizesByDifficulty) {
const info = resolveInfo(quiz, locale)
if (Object.keys(info).length === 0) return
if (prev !== info!.difficulty!) {
challengesREADME += `${prev ? "<br><br>" : ""}${generateDifficultyBadgeInverted(info!.difficulty!, locale, quizesByDifficulty.filter((q) => {
const qInfo = resolveInfo(q, locale)
return qInfo.difficulty === info!.difficulty
}).length)}<br>`
}
challengesREADME += quizToBadge(quiz, locale)
prev = info!.difficulty!
}
// By Tags
challengesREADME += "<br><details><summary>By Tags</summary><br><table><tbody>"
const tags = getAllTags(quizes, locale)
for (const tag of tags) {
challengesREADME += `<tr><td>${generateBadge("", `#${tag}`, "999")}</td><td>`
getQuizesByTag(quizesByDifficulty, locale, tag)
.forEach((quiz) => {
challengesREADME += quizToBadge(quiz, locale)
})
challengesREADME += "</td></tr>"
}
challengesREADME += "</tbody></table></details>"
let readme = await fs.readFile(filepath, "utf-8")
readme = readme.replace(
/<!--challenges-start-->[\s\S]*<!--challenges-end-->/m,
`<!--challenges-start-->\n${challengesREADME}\n<!--challenges-end-->`,
)
await fs.writeFile(filepath, readme, "utf-8")
}
}