From eba71583304be3ae03c8cfe696a5d3111c94c244 Mon Sep 17 00:00:00 2001 From: sergeych Date: Sat, 25 Apr 2026 16:46:51 +0300 Subject: [PATCH] Fix SPA sample links and sample doc publishing --- docs/lyng.io.db.md | 2 +- docs/pi_spigot_perf_baseline.md | 2 +- examples/error2.lyng | 0 site/build.gradle.kts | 77 ++++++++++++++++++++++++++-- site/src/jsMain/kotlin/Main.kt | 8 ++- site/src/jsMain/resources/index.html | 30 +++++++++-- 6 files changed, 108 insertions(+), 11 deletions(-) delete mode 100644 examples/error2.lyng diff --git a/docs/lyng.io.db.md b/docs/lyng.io.db.md index 10bd8f1..43cd706 100644 --- a/docs/lyng.io.db.md +++ b/docs/lyng.io.db.md @@ -190,7 +190,7 @@ assertThrows(RollbackException) { ## Runnable serialization sample -A complete runnable example is in [examples/sqlite_serialization.lyng](/home/sergeych/dev/lyng/examples/sqlite_serialization.lyng). +A complete runnable example is in [examples/sqlite_serialization.lyng](../examples/sqlite_serialization.lyng). It uses: diff --git a/docs/pi_spigot_perf_baseline.md b/docs/pi_spigot_perf_baseline.md index ecf5ffb..272a27d 100644 --- a/docs/pi_spigot_perf_baseline.md +++ b/docs/pi_spigot_perf_baseline.md @@ -4,7 +4,7 @@ Saved on April 4, 2026 before the `List` indexed-access follow-up fix. Benchmark target: - [examples/pi-bench.py](/home/sergeych/dev/lyng/examples/pi-bench.py) -- [examples/pi-bench.lyng](/home/sergeych/dev/lyng/examples/pi-bench.lyng) +- [examples/pi-bench.lyng](../examples/pi-bench.lyng) Execution path: - Python: `python3 examples/pi-bench.py` diff --git a/examples/error2.lyng b/examples/error2.lyng deleted file mode 100644 index e69de29..0000000 diff --git a/site/build.gradle.kts b/site/build.gradle.kts index 86ffbb4..9bfd074 100644 --- a/site/build.gradle.kts +++ b/site/build.gradle.kts @@ -78,18 +78,73 @@ kotlin { } // Generate an index of markdown documents under project /docs as a JSON array +val generateSampleDocPages by tasks.registering { + group = "documentation" + description = "Generates Markdown wrapper pages for Lyng sample files" + + val examplesDir = rootProject.projectDir.resolve("examples") + val docsSamplesDir = rootProject.projectDir.resolve("docs/samples") + val outDir = layout.buildDirectory.dir("generated-sample-docs/docs") + + inputs.dir(examplesDir) + inputs.dir(docsSamplesDir) + outputs.dir(outDir) + + doLast { + val outRoot = outDir.get().asFile + outRoot.mkdirs() + + fun generateFrom(sourceRoot: java.io.File, targetSubdir: String) { + if (!sourceRoot.exists()) return + sourceRoot.walkTopDown() + .filter { it.isFile && it.extension.equals("lyng", ignoreCase = true) } + .forEach { source -> + val rel = sourceRoot.toPath().relativize(source.toPath()).toString().replace('\\', '/') + val target = outRoot.resolve("$targetSubdir/$rel.md") + target.parentFile.mkdirs() + val title = source.name + val sourceText = source.readText() + val body = buildString { + append("# ").append(title).append("\n\n") + append("Generated from `") + append( + when (targetSubdir) { + "examples" -> "examples/$rel" + "samples" -> "docs/samples/$rel" + else -> "$targetSubdir/$rel" + } + ) + append("` during site build.\n\n") + append("```lyng\n") + append(sourceText) + if (!sourceText.endsWith("\n")) append('\n') + append("```\n") + } + target.writeText(body) + } + } + + generateFrom(examplesDir, "examples") + generateFrom(docsSamplesDir, "samples") + } +} + val generateDocsIndex by tasks.registering { group = "documentation" description = "Generates docs-index.json listing all Markdown files under /docs" val docsDir = rootProject.projectDir.resolve("docs") + val generatedDocsDir = layout.buildDirectory.dir("generated-sample-docs/docs") val outDir = layout.buildDirectory.dir("generated-resources") inputs.dir(docsDir) + inputs.dir(generatedDocsDir) outputs.dir(outDir) + dependsOn(generateSampleDocPages) + doLast { - val docs = mutableListOf() + val docs = linkedSetOf() if (docsDir.exists()) { docsDir.walkTopDown() .filter { it.isFile && it.extension.equals("md", ignoreCase = true) } @@ -100,6 +155,16 @@ val generateDocsIndex by tasks.registering { docs += "docs/$rel" } } + val generatedRoot = generatedDocsDir.get().asFile + if (generatedRoot.exists()) { + generatedRoot.walkTopDown() + .filter { it.isFile && it.extension.equals("md", ignoreCase = true) } + .forEach { f -> + val rel = generatedRoot.toPath().relativize(f.toPath()).toString() + .replace('\\', '/') + docs += "docs/$rel" + } + } val out = outDir.get().asFile out.mkdirs() val file = out.resolve("docs-index.json") @@ -113,7 +178,7 @@ val generateDocsIndex by tasks.registering { append(']') } file.writeText(json) - println("Generated ${'$'}{file.absolutePath} with ${'$'}{docs.size} entries") + println("Generated ${file.absolutePath} with ${docs.size} entries") } } @@ -137,7 +202,7 @@ val generateSiteVersion by tasks.registering(Copy::class) { // Ensure any ProcessResources task depends on docs index generation so the JSON is packaged tasks.configureEach { if (name.endsWith("ProcessResources")) { - dependsOn(generateDocsIndex, generateSiteVersion) + dependsOn(generateSampleDocPages, generateDocsIndex, generateSiteVersion) } } @@ -148,16 +213,20 @@ listOf( "jsProcessResources" ).forEach { taskName -> tasks.matching { it.name == taskName }.configureEach { - dependsOn(generateDocsIndex) + dependsOn(generateSampleDocPages, generateDocsIndex) } } // Copy Markdown docs into the "docs/" folder in the final resources, so paths in docs-index.json match files tasks.named("jsProcessResources").configure { + duplicatesStrategy = DuplicatesStrategy.EXCLUDE // Ensure we don't end up with two copies at root; we no longer add docs as a plain resources srcDir from(rootProject.projectDir.resolve("docs")) { into("docs") } + from(layout.buildDirectory.dir("generated-sample-docs/docs")) { + into("docs") + } } // Optional: configure toolchain if needed by the project; uses root Kotlin version from version catalog diff --git a/site/src/jsMain/kotlin/Main.kt b/site/src/jsMain/kotlin/Main.kt index 773a65e..0b3430f 100644 --- a/site/src/jsMain/kotlin/Main.kt +++ b/site/src/jsMain/kotlin/Main.kt @@ -986,10 +986,14 @@ fun rewriteAnchors( } continue } - if (href.contains(".md")) { + if (href.contains(".md") || href.contains(".lyng")) { val parts = href.split('#', limit = 2) - val mdPath = parts[0] + val rawPath = parts[0] val frag = if (parts.size > 1) parts[1] else null + val mdPath = when { + rawPath.endsWith(".lyng") -> "$rawPath.md" + else -> rawPath + } val target = if (mdPath.startsWith("docs/")) { normalizePath(mdPath) } else { diff --git a/site/src/jsMain/resources/index.html b/site/src/jsMain/resources/index.html index df36bd8..801b9c2 100644 --- a/site/src/jsMain/resources/index.html +++ b/site/src/jsMain/resources/index.html @@ -21,8 +21,32 @@ Lyng language + - + - + @@ -455,7 +479,7 @@
- +