Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
d343627
WIP Vitepress
EastArctica Dec 10, 2025
a80be23
Merge branch 'stonecutter' into backports/1.21.8-vitepress
EastArctica Jan 6, 2026
b49a426
Add missing copyVitepressDoc to stonecutter
EastArctica Jan 6, 2026
082c2fb
doclet changes
EastArctica Jan 7, 2026
19a50c8
WIP Core doclet replacement
EastArctica Jan 9, 2026
d29536b
Add DocletCategory
EastArctica Jan 9, 2026
010ea58
Add DocletCategory to all Entity Helpers
EastArctica Jan 9, 2026
bc45cc2
Fix missing DocletCategory places
EastArctica Jan 9, 2026
fd579a1
Improve markdown rendering
EastArctica Jan 9, 2026
d28fe8f
Add WIP categories
EastArctica Jan 10, 2026
b5ff968
Sort uncategorized to the bottom
EastArctica Jan 10, 2026
14d5781
Rename categories + add events
EastArctica Jan 10, 2026
a609c63
Merge branch 'main' into backports/1.21.8-vitepress
EastArctica Jan 11, 2026
8d757a3
Update links in markdown writer
EastArctica Jan 11, 2026
9581de1
Move doclet to com.jsmacros
EastArctica Jan 12, 2026
0975152
Add .kotlin to gitignore
EastArctica Jan 12, 2026
9bd531a
Merge branch 'backports/1.21.8-vitepress' of https://github.com/JsMac…
EastArctica Jan 12, 2026
4f578a8
Migrate wiki.vg to minecraft.wiki
EastArctica Jan 13, 2026
38aec7b
Various TypeScript improvements
EastArctica Jan 13, 2026
6b36d84
Fix same page doc links
EastArctica Jan 15, 2026
995b4e2
Merge branch 'main' into backports/1.21.8-vitepress
EastArctica Mar 9, 2026
ba09750
Fix merge
EastArctica Mar 9, 2026
cbce664
Update slf4j and remove buggy javadoc.io
EastArctica Mar 9, 2026
a17df55
Migrate to jsmacrosce branding
EastArctica Mar 9, 2026
359518c
Fix link resolution for newer javadocs
EastArctica Mar 9, 2026
5bfd687
Improve md docgen
EastArctica Mar 9, 2026
86db6dd
Migrate to MarkdownBuilder
EastArctica Mar 9, 2026
c12dcab
Migrate to ClassGroup
EastArctica Mar 9, 2026
5685479
Improve ClassGroup usage
EastArctica Mar 9, 2026
4fb1d48
Unify McVersion & Links options
EastArctica Mar 10, 2026
f89859c
Add vitepress dev script
EastArctica Mar 10, 2026
faada1b
Make vitepress-dev.sh ignore gitignored files
EastArctica Mar 10, 2026
d6d3d45
WIP vitepress improvements
EastArctica Mar 11, 2026
e015f8b
Clean up Structure.d.ts & Pass tsc checks
EastArctica Mar 11, 2026
debea45
Rework core doclet to use DocBodyNodes instead of working with strings
EastArctica Mar 11, 2026
5180876
Use relative paths where possible in mddoclet
EastArctica Mar 12, 2026
1f1f4ff
push deprecated badge to the right in mddoclet
EastArctica Mar 12, 2026
3eef026
Add DocletIgnore to many classes
EastArctica Mar 13, 2026
630ee66
Fix TsRenderer NPE
EastArctica Mar 13, 2026
f1cba87
Many md changes, Implement sub-sidebar entries for sub-classes, Make …
EastArctica Mar 13, 2026
5e28be8
Minor import cleanup
EastArctica Mar 13, 2026
c85bfbd
Fix accidental paste
EastArctica Mar 13, 2026
e291323
Add documentation to RecvMessage, PlayerJoin, PlayerLeave
EastArctica Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# gradle

.kotlin/
.gradle/
build/
out/
Expand Down Expand Up @@ -42,5 +43,10 @@ docs/web/[0-9]*
*.af~lock~
*.af~lock~:com.dropbox.ignored

# Vitepress docgen
node_modules/
**/.vitepress/cache/
**/.vitepress/dist/

# General working dir for anything that is needed during development
working/
57 changes: 48 additions & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ val distDirFile = distDir.asFile
val docsBuildDir = layout.buildDirectory.dir("docs").get().asFile
val docletJarFile = layout.projectDirectory.file("buildSrc/build/libs/buildSrc.jar").asFile

repositories {
mavenCentral()
}

val docletClasspath = configurations.detachedConfiguration(
dependencies.create("com.google.code.gson:gson:2.9.0")
)

// Root-level properties (available in root gradle.properties)
val modIdProvider = providers.gradleProperty("mod_id")
val channelProvider = providers.gradleProperty("channel").orElse("release")
Expand Down Expand Up @@ -222,8 +230,8 @@ if (isVersionedProject && hasMinecraftVersion) {
classpath = documentationClasspath
dependsOn(minecraftArtifactTasks)
destinationDir = File(docsBuildDir, "python/JsMacrosAC")
options.doclet = "com.jsmacrosce.doclet.pydoclet.Main"
options.docletpath = mutableListOf(docletJarFile)
options.doclet = "com.jsmacrosce.doclet.core.pydoclet.Main"
options.docletpath = (listOf(docletJarFile) + docletClasspath.files).toMutableList()
(options as CoreJavadocOptions).addStringOption("v", project.version.toString())
}

Expand All @@ -242,8 +250,8 @@ if (isVersionedProject && hasMinecraftVersion) {
classpath = documentationClasspath
dependsOn(minecraftArtifactTasks)
destinationDir = File(docsBuildDir, "typescript/headers")
options.doclet = "com.jsmacrosce.doclet.tsdoclet.Main"
options.docletpath = mutableListOf(docletJarFile)
options.doclet = "com.jsmacrosce.doclet.core.tsdoclet.Main"
options.docletpath = (listOf(docletJarFile) + docletClasspath.files).toMutableList()
(options as CoreJavadocOptions).addStringOption("v", project.version.toString())
}

Expand All @@ -262,14 +270,14 @@ if (isVersionedProject && hasMinecraftVersion) {
classpath = documentationClasspath
dependsOn(minecraftArtifactTasks)
destinationDir = File(docsBuildDir, "web")
options.doclet = "com.jsmacrosce.doclet.webdoclet.Main"
options.docletpath = mutableListOf(docletJarFile)
options.doclet = "com.jsmacrosce.doclet.core.webdoclet.Main"
options.docletpath = (listOf(docletJarFile) + docletClasspath.files).toMutableList()
(options as CoreJavadocOptions).addStringOption("v", project.version.toString())
(options as CoreJavadocOptions).addStringOption("mcv", mcVersion)
(options as StandardJavadocDocletOptions).links(
"https://docs.oracle.com/javase/8/docs/api/",
"https://www.javadoc.io/doc/org.slf4j/slf4j-api/1.7.30/",
"https://javadoc.io/doc/com.neovisionaries/nv-websocket-client/latest/"
"https://www.slf4j.org/apidocs-2.0.17/",
"https://takahikokawasaki.github.io/nv-websocket-client/"
)
}

Expand All @@ -285,10 +293,41 @@ if (isVersionedProject && hasMinecraftVersion) {
}
}

tasks.register("generateVitepressDoc", Javadoc::class.java) {
group = "documentation"
description = "Generates the vitepress documentation for the project"
source(documentationSources)
classpath = documentationClasspath
dependsOn(minecraftArtifactTasks)
destinationDir = File(docsBuildDir, "vitepress")
options.doclet = "com.jsmacrosce.doclet.core.mddoclet.Main"
options.docletpath = (listOf(docletJarFile) + docletClasspath.files).toMutableList()
(options as CoreJavadocOptions).addStringOption("v", project.version.toString())
(options as CoreJavadocOptions).addStringOption("mcv", mcVersion)
(options as StandardJavadocDocletOptions).links(
"https://docs.oracle.com/javase/8/docs/api/",
"https://www.slf4j.org/apidocs-2.0.17/",
"https://takahikokawasaki.github.io/nv-websocket-client/",
"https://www.graalvm.org/sdk/javadoc/"
)
}

tasks.register("copyVitepressDoc", Copy::class.java) {
group = "documentation"
description = "Copies the vitepress documentation to the build folder"
dependsOn("generateVitepressDoc")
from(rootProject.file("docs/vitepress"))
into(File(docsBuildDir, "vitepress"))
inputs.property("version", project.version.toString())
filesMatching("index.md") {
expand(mapOf("version" to project.version.toString()))
}
}

tasks.register("createDistDocs", Copy::class.java) {
group = "distribution"
description = "Packages generated documentation into the dist directory"
dependsOn("prepareDist", "copyPyDoc", "copyTSDoc", "copyWebDoc")
dependsOn("prepareDist", "copyPyDoc", "copyTSDoc", "copyWebDoc", "copyVitepressDoc")
from(docsBuildDir)
into(distDirFile)
}
Expand Down
9 changes: 6 additions & 3 deletions buildSrc/src/main/java/com/jsmacrosce/FileHandler.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.jsmacrosce;

import com.jsmacrosce.doclet.DocletIgnore;

import java.io.*;

/**
* @author Wagyourtail
* @since 1.1.8
*/
@DocletIgnore
public class FileHandler {
private final File f;

Expand Down Expand Up @@ -53,15 +56,15 @@ public FileHandler write(byte[] b) throws IOException {
* @since 1.1.8
*/
public String read() throws IOException {
String ret = "";
StringBuilder ret = new StringBuilder();
try (BufferedReader in = new BufferedReader(new FileReader(f))) {
String line = in.readLine();
while (line != null) {
ret += line + "\n";
ret.append(line).append("\n");
line = in.readLine();
}
}
return ret;
return ret.toString();
}

/**
Expand Down
232 changes: 232 additions & 0 deletions buildSrc/src/main/java/com/jsmacrosce/MarkdownBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
package com.jsmacrosce;

import com.jsmacrosce.doclet.DocletIgnore;

import java.util.Map;

/**
* Fluent builder for Markdown documents with VitePress-specific constructs.
*
* <p>Block-level methods automatically manage blank lines between elements.
* Consecutive bullet items (and items that immediately follow a
* {@link #boldHeader}) are not separated by blank lines; a blank line is
* inserted before any other block element that follows a list.
*
* <p>Inline helpers ({@link #codeSpan} and {@link #link}) are static so they
* can be used in contexts where only a {@code String} is needed, such as
* inside {@code MarkdownWriter} signatures.
*/
@DocletIgnore
public class MarkdownBuilder {

/** Tracks what the last emitted element was, to decide separators. */
private enum State {
/** Nothing has been emitted yet. */
START,
/** Last emitted element was a regular block (heading, paragraph, …). */
BLOCK,
/**
* Last emitted element was a list item or a bold-header (a bold label
* immediately followed by list items, e.g. {@code **Parameters:**}).
* Consecutive list elements never receive a blank-line separator.
*/
LIST
}

private final StringBuilder sb = new StringBuilder();
private State state = State.START;

// -----------------------------------------------------------------------
// Inline helpers (static — no state, return String)
// -----------------------------------------------------------------------

/**
* Wraps {@code text} in backtick fences, choosing a fence length that does
* not conflict with any backtick run already inside {@code text}.
*
* @param text the raw text content; must not be {@code null}
* @return a markdown inline code span
*/
public static String codeSpan(String text) {
if (text == null) {
return "";
}
int maxTicks = 0;
int current = 0;
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '`') {
current++;
if (current > maxTicks) {
maxTicks = current;
}
} else {
current = 0;
}
}
String fence = "`".repeat(maxTicks + 1);
return fence + text + fence;
}

/**
* Returns a markdown inline link: {@code [text](url)}.
*
* @param text the link label
* @param url the link target
* @return a markdown link string
*/
public static String link(String text, String url) {
return "[" + text + "](" + url + ")";
}

// -----------------------------------------------------------------------
// Block-level methods
// -----------------------------------------------------------------------

/**
* Emits a YAML frontmatter block at the current position.
*
* <p>Entries are written in insertion order. Values are emitted verbatim
* (no quoting is added by this method).
*
* @param entries key-value pairs for the frontmatter
* @return {@code this}
*/
public MarkdownBuilder frontmatter(Map<String, String> entries) {
beginBlock();
sb.append("---\n");
for (Map.Entry<String, String> entry : entries.entrySet()) {
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
}
sb.append("---\n");
state = State.BLOCK;
return this;
}

/**
* Emits {@code # … ## … ### …} depending on {@code level}.
*
* @param level ATX heading level (1–6)
* @param text heading text (not escaped by this method)
* @return {@code this}
*/
public MarkdownBuilder heading(int level, String text) {
beginBlock();
sb.append("#".repeat(level)).append(" ").append(text).append("\n");
state = State.BLOCK;
return this;
}

/**
* Emits a heading with a VitePress custom anchor: {@code ## text {#anchor}}.
*
* @param level ATX heading level (1–6)
* @param text heading text
* @param anchor anchor identifier (without the leading {@code #})
* @return {@code this}
*/
public MarkdownBuilder heading(int level, String text, String anchor) {
beginBlock();
sb.append("#".repeat(level)).append(" ").append(text)
.append(" {#").append(anchor).append("}\n");
state = State.BLOCK;
return this;
}

/**
* Emits a paragraph block. The text is appended verbatim followed by a
* single newline; the blank-line separator before the paragraph is managed
* automatically.
*
* @param text paragraph content (may include inline markdown)
* @return {@code this}
*/
public MarkdownBuilder paragraph(String text) {
if (text == null || text.isEmpty()) {
return this;
}
beginBlock();
sb.append(text).append("\n");
state = State.BLOCK;
return this;
}

/**
* Emits a bold "label" immediately followed by list items.
*
* <p>Example output: {@code **Parameters:**\n}. No blank line is inserted
* between this header and subsequent {@link #bulletItem} calls.
*
* @param label the bold label (without the {@code **} delimiters)
* @return {@code this}
*/
public MarkdownBuilder boldHeader(String label) {
beginBlock();
sb.append("**").append(label).append("**\n");
state = State.LIST;
return this;
}

/**
* Emits a list item ({@code - text\n}).
*
* <p>Consecutive bullet items are never separated by blank lines. A blank
* line is inserted before the first bullet item when it follows a
* non-list block (i.e. when the preceding state is {@link State#BLOCK}).
*
* @param text list-item content (may include inline markdown)
* @return {@code this}
*/
public MarkdownBuilder bulletItem(String text) {
if (state == State.BLOCK) {
sb.append("\n");
}
sb.append("- ").append(text).append("\n");
state = State.LIST;
return this;
}

/**
* Appends {@code text} verbatim without inserting any separator or
* modifying the current state. Use this for pre-formatted content whose
* structural role is best managed by the caller.
*
* @param text raw text to append
* @return {@code this}
*/
public MarkdownBuilder raw(String text) {
sb.append(text);
return this;
}

// -----------------------------------------------------------------------
// Rendering
// -----------------------------------------------------------------------

@Override
public String toString() {
return sb.toString();
}

// -----------------------------------------------------------------------
// Internal helpers
// -----------------------------------------------------------------------

/**
* Inserts a blank line before the upcoming block element when needed.
*
* <p>A blank line is inserted in two situations:
* <ul>
* <li>When the previous element was a regular block ({@link State#BLOCK})
* — each block element ends with {@code \n}, so appending one more
* {@code \n} creates the required {@code \n\n} separator.</li>
* <li>When the previous element was a list item or bold-header
* ({@link State#LIST}) — same logic applies.</li>
* </ul>
* In the initial {@link State#START} state nothing is emitted.
*/
private void beginBlock() {
if (state != State.START) {
sb.append("\n");
}
}
}
3 changes: 3 additions & 0 deletions buildSrc/src/main/java/com/jsmacrosce/Pair.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.jsmacrosce;

import com.jsmacrosce.doclet.DocletIgnore;

@DocletIgnore
public class Pair<T, U> {
T key;
U value;
Expand Down
Loading