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") } }