diff --git a/Docs/index.html b/Docs/index.html index 5dd0c019f..5da76f8c9 100644 --- a/Docs/index.html +++ b/Docs/index.html @@ -12,6 +12,7 @@
+ - - - - - - - diff --git a/package.json b/package.json index abf40435f..6631021e0 100644 --- a/package.json +++ b/package.json @@ -141,7 +141,7 @@ "optimize-images-scaledown-jpg": "cd assets/ && find . -regextype sed -regex \".*/.*.\\(jpg\\|JPG\\|JPEG\\|jpeg\\)\" -exec mogrify -resize 640x640\\> '{}' \\; && echo 'JPGs are optimized'", "generate:schemas": "export NODE_OPTIONS=\"--max-old-space-size=8192\" && ./scripts/generateSchemas.sh && echo 'tsjson is done' && vite-node scripts/fixSchemas.ts ", "reuse-compliance": "reuse lint", - "housekeeping": "export NODE_OPTIONS=\"--max-old-space-size=1200\" && git pull && npx update-browserslist-db@latest && npm run generate && npm run generate:schemas && npm run generate:contributor-list && vite-node scripts/fetchLanguages.ts && vite-node scripts/generateSunnyUnlabeled.ts && npm run format && npm run lint:themes && git add assets/ langs/ Docs/ **/*.ts Docs/* src/* && vite-node scripts/generateTaginfoProjectFiles.ts && git commit -m 'chore: automated housekeeping...'", + "housekeeping": "export NODE_OPTIONS=\"--max-old-space-size=1200\" && git pull && npx update-browserslist-db@latest && npm run generate && npm run generate:schemas && npm run generate:contributor-list && vite-node scripts/fetchLanguages.ts && vite-node scripts/generateSunnyUnlabeled.ts && npm run format && npm run lint:themes && git add assets/ langs/ Docs/ **/*.ts Docs/* src/* && git commit -m 'chore: automated housekeeping...'", "###": "MICROSERVICES AND SERVER MAINTAINENCE", "release": "standard-version && git push --follow-tags", "release:minor": "standard-version --release-as minor", diff --git a/scripts/generateDocs.ts b/scripts/generateDocs.ts index d1822daf2..e378773d2 100644 --- a/scripts/generateDocs.ts +++ b/scripts/generateDocs.ts @@ -130,6 +130,8 @@ class WikiPageGenerator { } export class GenerateDocs extends Script { + private generatedPaths: string[] = [] + constructor() { super("Generates various documentation files") } @@ -192,7 +194,11 @@ export class GenerateDocs extends Script { mkdirSync("./Docs/Themes") } this.generateOverviewsForAllSingleLayer() - this.generateNormalLayerOverview() + this.generateNormalLayerOverview("Layers") + this.generateNormalLayerOverview("Layers", "nl") + this.generateNormalLayerOverview("Themes") + this.generateNormalLayerOverview("Themes", "nl") + if (!existsSync("./Docs/nl")) { mkdirSync("./Docs/nl") } @@ -212,10 +218,16 @@ export class GenerateDocs extends Script { ]) new WikiPageGenerator().generate() + this.generatedPaths.push("wikiIndex.txt") this.generateSidebar() // Must be last as it inspects the generated markdown files this.generateSidebar("nl") + this.generatedPaths.push(".gitignore") + writeFileSync("./Docs/.gitignore", this.generatedPaths + .map(p => p.replace("./Docs/", "")) + .join("\n"), "utf-8") + console.log("Generated docs") } @@ -272,6 +284,7 @@ export class GenerateDocs extends Script { writeFileSync(filename, warnAutomated + md + (options?.noWarn ? "" : "\n\n" + generatedFrom + "\n")) + this.generatedPaths.push(filename) } @@ -725,8 +738,9 @@ export class GenerateDocs extends Script { /** * Generates the '_sidebar.md' file that is used by docsify + * Returns _all_ the filepaths (including ''hidden'' ones) */ - private generateSidebar(subdirectory = "") { + private generateSidebar(subdirectory = ""): string[] { const tr = Translations.t.app.back.textFor(subdirectory) const sidebar: string[] = [ `${tr}` @@ -734,8 +748,8 @@ export class GenerateDocs extends Script { const allFiles = ScriptUtils.readDirRecSync("./Docs/" + subdirectory) .filter(path => path.endsWith(".md")) .filter(path => !path.startsWith("_")) + .filter(path => !path.startsWith("./Docs/nl/") || path.startsWith("./Docs/" + subdirectory)) .map(path => path.substring("./Docs/".length + subdirectory.length + 1)) - console.log("AllFiles: " + subdirectory, allFiles) const perDirectory = new Map() function addFile(dir: string, path: string) { @@ -761,6 +775,9 @@ export class GenerateDocs extends Script { } } + perDirectory.delete("nl") + + // The directories to run over: const directories: [string, Translation | string][] = [ ["", ""], @@ -769,7 +786,6 @@ export class GenerateDocs extends Script { ["Layers", new Translation({ en: "Overview of layers", nl: "Overzicht van de lagen" })], ["Themes", new Translation({ en: "Overview of map themes", nl: "Overzicht van de themas" })], ["UserTests", "Usability tests with users"], - ["nl", null] // indicate skip ] @@ -789,6 +805,9 @@ export class GenerateDocs extends Script { } sidebar.push(`\n\n [**${titleStr}**](${dir}/README.md)`) } + if (dir === "Layers" || dir == "Themes") { + continue + } for (const path of files) { if (path.startsWith("_") || path.endsWith("README.md")) { continue @@ -806,17 +825,60 @@ export class GenerateDocs extends Script { noTableOfContents: true, noWarn: true, }) + const scriptPath = `./Docs/${subdirectory}/_paths.js` + writeFileSync(scriptPath, "var docsify_paths = " + JSON.stringify(allFiles)) + this.generatedPaths.push(scriptPath) + + return allFiles } - private generateNormalLayerOverview() { - const doc = ["# Layers", - `The following layers are available in MapComplete ${Constants.vNumber}:`, - MarkdownUtils.list( - Array.from(AllSharedLayers.sharedLayers.keys()).map( - (id) => `[${id}](./Layers/${id}.md)`, - ), - )] - this.writeMarkdownFile("./Docs/Layers/README.md", doc.join("\n\n"), ["./assets/layers/*.json"]) + private generateNormalLayerOverview(type: "Layers" | "Themes", subdir = "") { + + const layerinfo: [string, string, string][] = [] + const source: { + get(id: string): { id: string, name?: Translation, title?: Translation, description?: Translation }, + keys(): Iterable + } + = type === "Layers" ? AllSharedLayers.sharedLayers : AllKnownLayouts.allKnownLayouts + const keys = Array.from(source.keys()) + keys.sort() + + for (const id of keys) { + const layer = source.get(id) + let name = layer.title + if (type === "Layers") { + const layer_ = (layer) + if (!layer_.isNormal()) { + continue + } + name = layer.name + } + layerinfo.push([`[${id}](./Layers/${id})`, name.textFor(subdir), (layer["shortDescription"] ?? layer.description)?.textFor(subdir)]) + } + + const titles = { + "Layers": new Translation({ en: "Layers", nl: "Lagen" }), + "Themes": new Translation({ en: "Themes", nl: "Kaartthema's" }) + } + + const intro: Record> = { + "Layers": new TypedTranslation<{ version }>({ + en: "The following layers are available in MapComplete {version}:", + nl: "De volgende lagen zijn beschikbaar in MapComplete {version}:" + }), + "Themes": new TypedTranslation<{ version }>({ + en: "The following themes are available in MapComplete {version}:", + nl: "De volgende kaartthemas zijn beschikbaar in MapComplete {version}:" + }) + } + + const doc = ["# " + titles[type].textFor(subdir), + intro[type].Subs({ version: Constants.vNumber }).textFor(subdir) + , MarkdownUtils.table( + ["id", "name", "description"], + layerinfo) + ] + this.writeMarkdownFile(`./Docs/${subdir}/${type}/README.md`, doc.join("\n\n"), [`./assets/${type.toLowerCase()}/*.json`]) } /** diff --git a/src/UI/i18n/Translation.ts b/src/UI/i18n/Translation.ts index 73dc61a03..ebbd293dc 100644 --- a/src/UI/i18n/Translation.ts +++ b/src/UI/i18n/Translation.ts @@ -225,10 +225,11 @@ export class Translation { * @param copyContext if set, the context of 'this' will be added to the new translation. If not, _context will be removed alltogether * @return The object itself (this) if all strings are the same * - * new Translation({"en": "This is a sentence. This is another sentence"}).FirstSentence().textFor("en") // "This is a sentence" - * new Translation({"en": "This is a sentence
This is another sentence"}).FirstSentence().textFor("en") // "This is a sentence" - * new Translation({"en": "This is a sentence
This is another sentence"}).FirstSentence().textFor("en") // "This is a sentence" - * new Translation({"en": "This is a sentence with a bold word. This is another sentence"}).FirstSentence().textFor("en") // "This is a sentence with a bold word" + * new Translation({"en": "This is a sentence. This is another sentence"}).FirstSentence().textFor("en") // => "This is a sentence" + * new Translation({"en": "This is a sentence
This is another sentence"}).FirstSentence().textFor("en") // => "This is a sentence" + * new Translation({"en": "This is a sentence \n\n This is another sentence"}).FirstSentence().textFor("en") // => "This is a sentence" + * new Translation({"en": "This is a sentence
This is another sentence"}).FirstSentence().textFor("en") // => "This is a sentence" + * new Translation({"en": "This is a sentence with a bold word. This is another sentence"}).FirstSentence().textFor("en") // => "This is a sentence with a bold word" * @constructor */ public FirstSentence(copyContext: boolean = false): Translation { @@ -239,7 +240,7 @@ export class Translation { continue } let txt = this.translations[lng] - txt = txt.replace(/(\.||
|。).*/, "").trim() + txt = txt.replace(/(\.||
|。|\n).*/s, "").trim() txt = Utils.EllipsesAfter(txt, 255) allSame = allSame && txt == this.translations[lng] tr[lng] = txt