Docs: add dutch, support for generated documentation in non-repo location, remove from housekeeping

This commit is contained in:
Pieter Vander Vennet 2025-10-07 23:29:57 +02:00
parent b4cb1b97cc
commit b4d89e48f5
8 changed files with 171 additions and 45 deletions

View file

@ -1,8 +1,12 @@
README
======
[🇳🇱 In het nederlands](https://docs.mapcomplete.org/nl)
Welcome to the documentation directory of MapComplete!
The documentation is meant to be viewed on our [documentation website](https://docs.mapcomplete.org).
This is meant for more advanced users and contributors of MapComplete.
- Some general information is in the top section

View file

@ -13,6 +13,10 @@
<body>
<div id="app"></div>
<script>
let language = "en"
if (document.location.pathname.startsWith("/nl/")) {
language = "nl"
}
window.$docsify = {
name: "MapComplete Docs",
noEmoji: true,
@ -23,8 +27,8 @@
maxAge: 86400000, // 1 day cache
paths: "auto",
auto2top: true,
placeholder: "Search",
noData: "No Results!",
placeholder: language === "nl" ? "Zoeken" : "Search",
noData: language === "nl" ? "Geen resultaten gevonden" : "No Results found",
depth: 2,
},
}

18
Docs/nl/README.md Normal file
View file

@ -0,0 +1,18 @@
README
======
[In English](https://docs.mapcomplete.org/)
Welkom op de documentatiewebsite voor MapComplete.
De informatie die je hier vindt is bedoeld voor iets geavanceerdere gebruikers.
Je kunt hier (onder andere) een overzicht vinden van welke attributen er gebruikt worden door welke lagen.
Noot: de [Engelse documentatie](https://docs.mapcomplete.org) bevat meer informatie
Voor andere vragen:
- Ideëen voor verbeteringen en rapporteren van bugs is via [de issue tracker](https://source.mapcomplete.org/mapcomplete/mapcomplete/issues) (dit mag in het Nederlands)
- Er is een chat rond MapComplete op [matrix (engelstalig)](https://app.element.io/#/room/#MapComplete:matrix.org)
- Tenslotte kan je ook de ontwikkelaar emailen op info@mapcomplete.org (Nederlands / Engels)

View file

@ -0,0 +1,4 @@
# Wat is MapComplete?
MapComplete is een OpenStreetMap-webeditor die zich richt op het weergeven en aanpassen van OpenStreetMap-data.
Het biedt vooraf gedefinieerde “themas” (zoals bankjes, fietsenrekken, kunstwerken, enz.) laat gebruikers direct informatie zien of bewerken zonder technische kennis van OSM.

85
Docs/nl/index.html Normal file
View file

@ -0,0 +1,85 @@
<!DOCTYPE html>
<!-- This is meant to be run with docsify -->
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
</head>
<body>
<div id="app"></div>
<script>
let language = "en"
if (document.location.pathname.startsWith("/nl/")) {
language = "nl"
}
window.$docsify = {
name: "MapComplete Docs",
noEmoji: true,
loadSidebar: true,
autoToTop: true,
repo: "https://source.mapcomplete.org/mapcomplete/mapcomplete/",
search: {
maxAge: 86400000, // 1 day cache
paths: "auto",
auto2top: true,
placeholder: language === "nl" ? "Zoeken" : "Search",
noData: language === "nl" ? "Geen resultaten gevonden" : "No Results found",
depth: 2,
},
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.js"></script>
<style>
.sidebar a {
line-height: 1.3em;
}
.sidebar {
padding-left: 1rem;
}
.sidebar strong {
font-size: 1.2em;
}
.sidebar p:has(strong){
margin: 0;
top: 0;
position: sticky;
background: white;
padding: 0.25rem;
}
.sidebar a:has(strong) {
margin-top: 1em;
}
.active a {
color: #42b983 !important;;
color: var(--theme-color, #42b983) !important;
font-weight: 600 !important;
border-right: 2px solid !important;
}
/*noinspection CssUnusedSymbol*/
.back-to-mc {
display: block;
padding: 0.5rem;
background: #3f3f39;
color: white;
border: 2px solid white;
border-radius: 0.5rem;
}
</style>
</body>
</html>

View file

@ -100,7 +100,7 @@
"generate:translations": "vite-node scripts/generateTranslations.ts",
"reset:translations": "vite-node scripts/generateTranslations.ts -- --ignore-weblate",
"generate:layouts": "export NODE_OPTIONS=\"--max-old-space-size=8192\" && vite-node scripts/generateLayouts.ts",
"generate:docs": "rm -rf Docs/Themes/* && rm -rf Docs/Layers/* && rm -rf Docs/TagInfo && mkdir Docs/TagInfo && export NODE_OPTIONS=\"--max-old-space-size=16000\" && vite-node scripts/generateDocs.ts && vite-node scripts/generateTaginfoProjectFiles.ts",
"generate:docs": "rm -rf Docs/Themes/* && rm -rf Docs/Layers/* && rm -rf Docs/TagInfo && mkdir Docs/TagInfo && export NODE_OPTIONS=\"--max-old-space-size=16000\" && cp Docs/index.html Docs/nl/index.html && vite-node scripts/generateDocs.ts",
"generate:mapcomplete-changes-theme": "export NODE_OPTIONS=\"--max-old-space-size=8192\" && vite-node scripts/generateLayerOverview.ts -- --generate-change-map",
"generate:licenses": "vite-node scripts/generateLicenseInfo.ts -- --no-fail",
"generate:layeroverview": "export NODE_OPTIONS=\"--max-old-space-size=16000\" && vite-node scripts/generateLayerOverview.ts",
@ -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:docs && 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...'",
"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...'",
"###": "MICROSERVICES AND SERVER MAINTAINENCE",
"release": "standard-version && git push --follow-tags",
"release:minor": "standard-version --release-as minor",

View file

@ -1,8 +1,5 @@
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"
import { AllKnownLayouts } from "../src/Customizations/AllKnownLayouts"
import SimpleMetaTaggers from "../src/Logic/SimpleMetaTagger"
import SpecialVisualizations from "../src/UI/SpecialVisualizations"
import { ExtraFunctions } from "../src/Logic/ExtraFunctions"
import QueryParameterDocumentation from "../src/UI/QueryParameterDocumentation"
import ScriptUtils from "./ScriptUtils"
import Translations from "../src/UI/i18n/Translations"
@ -15,12 +12,9 @@ import Constants from "../src/Models/Constants"
import LayerConfig from "../src/Models/ThemeConfig/LayerConfig"
import DependencyCalculator from "../src/Models/ThemeConfig/DependencyCalculator"
import { AllSharedLayers } from "../src/Customizations/AllSharedLayers"
import Validators from "../src/UI/InputElement/Validators"
import questions from "../public/assets/generated/layers/questions.json"
import { LayerConfigJson } from "../src/Models/ThemeConfig/Json/LayerConfigJson"
import { TagUtils } from "../src/Logic/Tags/TagUtils"
import Script from "./Script"
import { Changes } from "../src/Logic/Osm/Changes"
import TableOfContents from "../src/UI/Base/TableOfContents"
import MarkdownUtils from "../src/Utils/MarkdownUtils"
import { parse as parse_html } from "node-html-parser"
@ -30,6 +24,12 @@ import { ServerSourceInfo, SourceOverview } from "../src/Models/SourceOverview"
import { Lists } from "../src/Utils/Lists"
import { Translation, TypedTranslation } from "../src/UI/i18n/Translation"
import language_translations from "../src/assets/language_translations.json"
import { Changes } from "../src/Logic/Osm/Changes"
import SimpleMetaTaggers from "../src/Logic/SimpleMetaTagger"
import { ExtraFunctions } from "../src/Logic/ExtraFunctions"
import Validators from "../src/UI/InputElement/Validators"
import { TagUtils } from "../src/Logic/Tags/TagUtils"
import SpecialVisualizations from "../src/UI/SpecialVisualizations"
/**
* Converts a markdown-file into a .json file, which a walkthrough/slideshow element can use
@ -137,17 +137,15 @@ export class GenerateDocs extends Script {
async main(args: string[]) {
console.log("Starting documentation generation...")
ScriptUtils.fixUtils()
{
// For studio: prepare slideshow
new ToSlideshowJson(
"./Docs/Studio/Introduction.md",
"./src/assets/studio_introduction.json",
"./src/assets/studio_introduction.json"
).convert()
new ToSlideshowJson(
"./Docs/Studio/TagRendering_How_to_work_with_TagRenderings.md",
"./src/assets/studio_tagrenderings_intro.json",
"./src/assets/studio_tagrenderings_intro.json"
).convert()
}
@ -159,10 +157,10 @@ export class GenerateDocs extends Script {
this.generateEliDocs()
this.generateBuiltinUnits()
this.writeMarkdownFile("./Docs/Studio/SpecialInputElements.md", Validators.HelpText(), [
"src/UI/InputElement/Validators.ts",
"src/UI/InputElement/Validators.ts"
])
this.writeMarkdownFile("./Docs/Studio/Tags_format.md", TagUtils.generateDocs(), [
"src/Logic/Tags/TagUtils.ts",
"src/Logic/Tags/TagUtils.ts"
])
this.writeMarkdownFile(
@ -170,19 +168,18 @@ export class GenerateDocs extends Script {
SpecialVisualizations.HelpMessage(),
["src/UI/SpecialVisualizations.ts"],
{
tocMaxDepth: 3,
},
tocMaxDepth: 3
}
)
this.writeMarkdownFile(
"./Docs/Studio/CalculatedTags.md",
["# Metatags", SimpleMetaTaggers.HelpText(), ExtraFunctions.HelpText()].join("\n"),
["src/Logic/SimpleMetaTagger.ts", "src/Logic/ExtraFunctions.ts"],
{ noTableOfContents: false },
{ noTableOfContents: false }
)
}
// For dev
{
this.generateQueryParameterDocs()
@ -196,28 +193,29 @@ export class GenerateDocs extends Script {
}
this.generateOverviewsForAllSingleLayer()
this.generateNormalLayerOverview()
if (!existsSync("./Docs/nl")) {
mkdirSync("./Docs/nl")
}
Array.from(AllKnownLayouts.allKnownLayouts.values()).map((theme) => {
this.generateForTheme(theme)
// this.generateForTheme(theme, { path: "./Docs/themes_nl", lang: "nl" })
this.generateForTheme(theme, { path: "./Docs/nl/Themes", lang: "nl" })
ScriptUtils.erasableLog("Written docs for theme", theme.id)
})
/*
if (!existsSync("./Docs/themes_nl")) {
mkdirSync("./Docs/themes_nl")
}
this.generateOverviewsForAllSingleLayer("./Docs/layers_nl", "nl")
//*/
this.generateOverviewsForAllSingleLayer("./Docs/nl/Layers", "nl")
}
this.writeMarkdownFile("./Docs/ChangesetMeta.md", Changes.getDocs(), [
"src/Logic/Osm/Changes.ts",
"src/Logic/Osm/ChangesetHandler.ts",
"src/Logic/Osm/ChangesetHandler.ts"
])
new WikiPageGenerator().generate()
this.generateSidebar() // Must be last as it inspects the generated markdown files
this.generateSidebar("nl")
console.log("Generated docs")
}
@ -267,10 +265,10 @@ export class GenerateDocs extends Script {
(s) => `[${s}](https://source.mapcomplete.org/MapComplete/MapComplete/src/branch/develop/${s})`).join(", ")
const generatedFrom =
new TypedTranslation<{ sources }>({
en: "This document is autogenerated from {sources}",
nl: "Dit document werd gegenereerd op basis van {sources}",
}).Subs({ sources }).textFor(lang)
new TypedTranslation<{ sources, date }>({
en: "This document is autogenerated from {sources} on {date}",
nl: "Dit document werd gegenereerd op basis van {sources} op {date}"
}).Subs({ sources, date: new Date().toDateString() }).textFor(lang)
writeFileSync(filename, warnAutomated + md + (options?.noWarn ? "" : "\n\n" + generatedFrom + "\n"))
@ -479,7 +477,7 @@ export class GenerateDocs extends Script {
builtinsPerLayer.set(layer.id, usedBuiltins)
}
let docs: string[] = [
const docs: string[] = [
"# Which tagrendering is used where?", "",
"This document details where a tagRendering from one layer is reused in another layer, either by directly using it or by using a `{\"builtin\": id, \"override\": ...}` syntax",
"Having this overview supports e.g. refactoring efforts",
@ -588,6 +586,9 @@ export class GenerateDocs extends Script {
}
const path = options?.path ?? "./Docs/Themes"
if (!existsSync(path)) {
mkdirSync(path)
}
this.writeMarkdownFile(
path + "/" + theme.id + ".md",
el.join("\n"),
@ -725,15 +726,16 @@ export class GenerateDocs extends Script {
/**
* Generates the '_sidebar.md' file that is used by docsify
*/
private generateSidebar() {
private generateSidebar(subdirectory = "") {
const tr = Translations.t.app.back.textFor(subdirectory)
const sidebar: string[] = [
"<a href='https://mapcomplete.org' class='back-to-mc'>Back to MapComplete</a>",
`<a href='https://mapcomplete.org' class='back-to-mc'>${tr}</a>`
]
const allFiles = ScriptUtils.readDirRecSync("./Docs")
const allFiles = ScriptUtils.readDirRecSync("./Docs/" + subdirectory)
.filter(path => path.endsWith(".md"))
.filter(path => !path.startsWith("_"))
.map(path => path.substring("./Docs/".length))
.map(path => path.substring("./Docs/".length + subdirectory.length + 1))
console.log("AllFiles: " + subdirectory, allFiles)
const perDirectory = new Map<string, string[]>()
function addFile(dir: string, path: string) {
@ -760,22 +762,32 @@ export class GenerateDocs extends Script {
}
// The directories to run over:
const directories = [
const directories: [string, Translation | string][] = [
["", ""],
["Studio", "For theme builders"],
["Dev", "For developers"],
["Layers", "Overview of layers"], ["Themes", "Overview of map themes"],
["UserTests", "Usability tests with users"]]
["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
]
for (const [dir, title] of directories) {
if (title === null) {
continue
}
const files = perDirectory.get(dir)
if (!files) {
console.error("No directory for " + dir)
continue
}
if (dir !== "") {
sidebar.push(`\n\n [**${title}**](${dir}/README.md)`)
let titleStr = title
if (typeof titleStr !== "string") {
titleStr = titleStr.textFor(subdirectory)
}
sidebar.push(`\n\n [**${titleStr}**](${dir}/README.md)`)
}
for (const path of files) {
if (path.startsWith("_") || path.endsWith("README.md")) {
@ -790,7 +802,7 @@ export class GenerateDocs extends Script {
}
}
this.writeMarkdownFile("./Docs/_sidebar.md", sidebar.join("\n"), [], {
this.writeMarkdownFile("./Docs/" + subdirectory + "/_sidebar.md", sidebar.join("\n"), [], {
noTableOfContents: true,
noWarn: true,
})

View file

@ -4,7 +4,6 @@ import { Translation } from "../src/UI/i18n/Translation"
import { readFileSync, writeFileSync } from "fs"
import ThemeConfig from "../src/Models/ThemeConfig/ThemeConfig"
import LayerConfig from "../src/Models/ThemeConfig/LayerConfig"
import { Utils } from "../src/Utils"
import { Lists } from "../src/Utils/Lists"
import { Strings } from "../src/Utils/Strings"
@ -239,7 +238,7 @@ function generateProjectsOverview(files: string[]) {
.concat(
files.map(
(f) =>
`${f} https://source.mapcomplete.org/MapComplete/MapComplete/raw/branch/develop/Docs/TagInfo/${f}.json`
`${f} https://docs.mapcomplete.org/TagInfo/${f}.json`
)
)
.sort()