Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate JSON docs with Gson #5738

Merged
merged 30 commits into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0d21393
Start work on new json docs generation
Pikachu920 Jun 10, 2023
70f296f
Merge remote-tracking branch 'origin/master' into fix/json-docs
Pikachu920 Jun 11, 2023
bff5226
Add more to the JSON
Pikachu920 Jun 11, 2023
2c6841a
Add sections
Pikachu920 Aug 1, 2023
141cad5
Add ID generation to JSON docs
Pikachu920 Dec 19, 2023
724d3f0
Fix SkriptCommand errors
Pikachu920 Dec 19, 2023
e75278c
Add license header
Pikachu920 Dec 19, 2023
6dc3ee0
Merge branch 'dev/feature' into fix/json-docs
Pikachu920 Dec 19, 2023
9a540d9
Test duplicate checker
Pikachu920 Dec 19, 2023
b1fac55
Merge remote-tracking branch 'origin/fix/json-docs' into fix/json-docs
Pikachu920 Dec 19, 2023
1e141f4
Existing IDs actually start at 2
Pikachu920 Dec 19, 2023
856e81b
Address reviews
Pikachu920 Dec 19, 2023
2dfdfa3
Remove test class
Pikachu920 Dec 19, 2023
9b85439
Address reviews
Pikachu920 Dec 20, 2023
78b9c21
Merge branch 'dev/feature' into fix/json-docs
Pikachu920 Dec 21, 2023
0f72ebf
Address reviews
Pikachu920 Jan 2, 2024
fcfa58a
Try new way of generating IDs
Pikachu920 Sep 5, 2024
468dca7
Add license header
Pikachu920 Sep 5, 2024
2c1bad3
Merge branch 'dev/feature' into fix/json-docs
Pikachu920 Sep 5, 2024
73fa78d
Fix nullable import
Pikachu920 Sep 5, 2024
40f172c
Merge remote-tracking branch 'origin/dev/feature' into fix/json-docs
Pikachu920 Sep 5, 2024
80adf80
Add javadocs
Pikachu920 Sep 5, 2024
868d683
Remove license headers
Pikachu920 Sep 5, 2024
dc80514
Merge remote-tracking branch 'origin/fix/json-docs' into fix/json-docs
Pikachu920 Sep 5, 2024
36877c4
Address reviews
Pikachu920 Sep 6, 2024
9e33cf6
Address reviews
Pikachu920 Sep 6, 2024
704eb04
Address reviews
Pikachu920 Sep 9, 2024
33e3344
Address reviews
Pikachu920 Sep 9, 2024
ba63d20
Address reviews
Pikachu920 Sep 9, 2024
8866bf3
Merge branch 'dev/feature' into fix/json-docs
Pikachu920 Sep 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/main/java/ch/njol/skript/SkriptCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import ch.njol.skript.aliases.Aliases;
import ch.njol.skript.command.CommandHelp;
import ch.njol.skript.doc.Documentation;
import ch.njol.skript.doc.DocumentationIdProvider;
import ch.njol.skript.doc.HTMLGenerator;
import ch.njol.skript.doc.JSONGenerator;
import ch.njol.skript.localization.ArgsMessage;
import ch.njol.skript.localization.Language;
import ch.njol.skript.localization.PluralizingArgsMessage;
Expand Down Expand Up @@ -404,9 +406,11 @@ else if (args[0].equalsIgnoreCase("gen-docs")) {
}
File outputDir = Documentation.getDocsOutputDirectory();
outputDir.mkdirs();
HTMLGenerator generator = new HTMLGenerator(templateDir, outputDir);
HTMLGenerator htmlGenerator = new HTMLGenerator(templateDir, outputDir, new DocumentationIdProvider());
JSONGenerator jsonGenerator = new JSONGenerator(templateDir, outputDir, new DocumentationIdProvider());
Skript.info(sender, "Generating docs...");
generator.generate(); // Try to generate docs... hopefully
htmlGenerator.generate(); // Try to generate docs... hopefully
jsonGenerator.generate();
Skript.info(sender, "Documentation generated!");
}

Expand Down
38 changes: 38 additions & 0 deletions src/main/java/ch/njol/skript/doc/DocumentationGenerator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.doc;

import java.io.File;

public abstract class DocumentationGenerator {

protected File templateDir;
protected File outputDir;

protected DocumentationIdProvider idProvider;

public DocumentationGenerator(File templateDir, File outputDir, DocumentationIdProvider idProvider) {
this.idProvider = idProvider;
this.templateDir = templateDir;
this.outputDir = outputDir;
}

public abstract void generate();

}
70 changes: 70 additions & 0 deletions src/main/java/ch/njol/skript/doc/DocumentationIdProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript.doc;

import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.lang.SkriptEventInfo;
import ch.njol.skript.lang.function.Function;

import java.util.HashMap;
import java.util.Map;

public class DocumentationIdProvider {
Pikachu920 marked this conversation as resolved.
Show resolved Hide resolved

private Map<String, Integer> idCollisionCounter = new HashMap<>();


private String addCollisionSuffix(String id) {
Pikachu920 marked this conversation as resolved.
Show resolved Hide resolved
Integer collisionCount = idCollisionCounter.get(id);
idCollisionCounter.merge(id, 2, Integer::sum);
if (collisionCount == null) {
return id;
}
return id + "-" + collisionCount;
}

public String getId(Class<?> clazz) {
DocumentationId documentationIdAnnotation = clazz.getAnnotation(DocumentationId.class);
if (documentationIdAnnotation == null) {
return addCollisionSuffix(clazz.getSimpleName());
}
return addCollisionSuffix(documentationIdAnnotation.value());
}

public String getId(Function<?> function) {
return addCollisionSuffix(function.getName());
}

public String getId(ClassInfo<?> classInfo) {
String explicitlyDefinedId = classInfo.getDocumentationID();
if (explicitlyDefinedId != null) {
return addCollisionSuffix(explicitlyDefinedId);
}
return addCollisionSuffix(classInfo.getCodeName());
}

public String getId(SkriptEventInfo<?> eventInfo) {
String explicitlyDefinedId = eventInfo.getDocumentationID();
if (explicitlyDefinedId != null) {
return addCollisionSuffix(explicitlyDefinedId);
}
return addCollisionSuffix(eventInfo.getId());
}

}
74 changes: 21 additions & 53 deletions src/main/java/ch/njol/skript/doc/HTMLGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,10 @@
import ch.njol.skript.lang.SyntaxElementInfo;
import ch.njol.skript.lang.function.Functions;
import ch.njol.skript.lang.function.JavaFunction;
import ch.njol.skript.lang.function.Parameter;
import ch.njol.skript.registrations.Classes;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.annotation.Nullable;
import org.skriptlang.skript.lang.entry.EntryData;
import org.skriptlang.skript.lang.entry.EntryValidator;
Expand All @@ -59,21 +57,17 @@
* pages by combining data from annotations and templates.
*
*/
public class HTMLGenerator {
public class HTMLGenerator extends DocumentationGenerator {

private static final String SKRIPT_VERSION = Skript.getVersion().toString().replaceAll("-(dev|alpha|beta)\\d*", ""); // Filter branches
private static final Pattern NEW_TAG_PATTERN = Pattern.compile(SKRIPT_VERSION + "(?!\\.)"); // (?!\\.) to avoid matching 2.6 in 2.6.1 etc.
private static final Pattern RETURN_TYPE_LINK_PATTERN = Pattern.compile("( ?href=\"(classes\\.html|)#|)\\$\\{element\\.return-type-linkcheck}");

private final File template;
private final File output;
private final String skeleton;

public HTMLGenerator(File templateDir, File outputDir) {
this.template = templateDir;
this.output = outputDir;

this.skeleton = readFile(new File(template + "/template.html")); // Skeleton which contains every other page
public HTMLGenerator(File templateDir, File outputDir, DocumentationIdProvider idGenerator) {
super(templateDir, outputDir, idGenerator);
this.skeleton = readFile(new File(this.templateDir + "/template.html")); // Skeleton which contains every other page
}

/**
Expand Down Expand Up @@ -208,15 +202,16 @@ public int compare(@Nullable JavaFunction<?> o1, @Nullable JavaFunction<?> o2) {
* Generates documentation using template and output directories
* given in the constructor.
*/
@Override
@SuppressWarnings("unchecked")
public void generate() {
for (File f : template.listFiles()) {
for (File f : templateDir.listFiles()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (File f : templateDir.listFiles()) {
for (File file : templateDir.listFiles()) {

if (f.getName().matches("css|js|assets")) { // Copy CSS/JS/Assets folders
String slashName = "/" + f.getName();
File fileTo = new File(output + slashName);
File fileTo = new File(outputDir + slashName);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
File fileTo = new File(outputDir + slashName);
File fileTo = new File(outputDir, file.getName());

doesn't this work? this way you don't need slashName

fileTo.mkdirs();
for (File filesInside : new File(template + slashName).listFiles()) {
if (filesInside.isDirectory())
for (File filesInside : new File(templateDir + slashName).listFiles()) {
if (filesInside.isDirectory())
continue;

if (!filesInside.getName().toLowerCase(Locale.ENGLISH).endsWith(".png")) { // Copy images
Expand Down Expand Up @@ -262,7 +257,7 @@ else if (!filesInside.getName().matches("(?i)(.*)\\.(html?|js|css|json)")) {
}

for (String name : replace) {
String temp = readFile(new File(template + "/templates/" + name));
String temp = readFile(new File(templateDir + "/templates/" + name));
temp = temp.replace("${skript.version}", Skript.getVersion().toString());
page = page.replace("${include " + name + "}", temp);
}
Expand All @@ -273,7 +268,7 @@ else if (!filesInside.getName().matches("(?i)(.*)\\.(html?|js|css|json)")) {
String[] genParams = page.substring(generate + 11, nextBracket).split(" ");
StringBuilder generated = new StringBuilder();

String descTemp = readFile(new File(template + "/templates/" + genParams[1]));
String descTemp = readFile(new File(templateDir + "/templates/" + genParams[1]));
String genType = genParams[0];
boolean isDocsPage = genType.equals("docs");

Expand Down Expand Up @@ -382,7 +377,7 @@ else if (!filesInside.getName().matches("(?i)(.*)\\.(html?|js|css|json)")) {
page = minifyHtml(page);
}
assert page != null;
writeFile(new File(output + File.separator + name), page);
writeFile(new File(outputDir + File.separator + name), page);
}
}

Expand Down Expand Up @@ -471,15 +466,7 @@ private String generateAnnotated(String descTemp, SyntaxElementInfo<?> info, @Nu
.replace("\\", "\\\\").replace("\"", "\\\"").replace("\t", " "));

// Documentation ID
DocumentationId docId = c.getAnnotation(DocumentationId.class);
String ID = docId != null ? (docId != null ? docId.value() : null) : info.c.getSimpleName();
// Fix duplicated IDs
if (page != null) {
if (page.contains("href=\"#" + ID + "\"")) {
ID = ID + "-" + (StringUtils.countMatches(page, "href=\"#" + ID + "\"") + 1);
}
}
desc = desc.replace("${element.id}", ID);
desc = desc.replace("${element.id}", idProvider.getId(c));

// Events
Events events = c.getAnnotation(Events.class);
Expand Down Expand Up @@ -550,7 +537,7 @@ private String generateAnnotated(String descTemp, SyntaxElementInfo<?> info, @Nu
// Assume element.pattern generate
for (String data : toGen) {
String[] split = data.split(" ");
String pattern = readFile(new File(template + "/templates/" + split[1]));
String pattern = readFile(new File(templateDir + "/templates/" + split[1]));
StringBuilder patterns = new StringBuilder();
for (String line : getDefaultIfNullOrEmpty(info.patterns, "Missing patterns.")) {
assert line != null;
Expand Down Expand Up @@ -604,14 +591,7 @@ private String generateEvent(String descTemp, SkriptEventInfo<?> info, @Nullable
desc = desc.replace("${element.keywords}", keywords == null ? "" : Joiner.on(", ").join(keywords));

// Documentation ID
String ID = info.getDocumentationID() != null ? info.getDocumentationID() : info.getId();
// Fix duplicated IDs
if (page != null) {
if (page.contains("href=\"#" + ID + "\"")) {
ID = ID + "-" + (StringUtils.countMatches(page, "href=\"#" + ID + "\"") + 1);
}
}
desc = desc.replace("${element.id}", ID);
desc = desc.replace("${element.id}", idProvider.getId(c));

// Events
Events events = c.getAnnotation(Events.class);
Expand Down Expand Up @@ -658,7 +638,7 @@ private String generateEvent(String descTemp, SkriptEventInfo<?> info, @Nullable
// Assume element.pattern generate
for (String data : toGen) {
String[] split = data.split(" ");
String pattern = readFile(new File(template + "/templates/" + split[1]));
String pattern = readFile(new File(templateDir + "/templates/" + split[1]));
StringBuilder patterns = new StringBuilder();
for (String line : getDefaultIfNullOrEmpty(info.patterns, "Missing patterns.")) {
assert line != null;
Expand Down Expand Up @@ -710,14 +690,7 @@ private String generateClass(String descTemp, ClassInfo<?> info, @Nullable Strin
desc = desc.replace("${element.keywords}", keywords == null ? "" : Joiner.on(", ").join(keywords.value()));

// Documentation ID
String ID = info.getDocumentationID() != null ? info.getDocumentationID() : info.getCodeName();
// Fix duplicated IDs
if (page != null) {
if (page.contains("href=\"#" + ID + "\"")) {
ID = ID + "-" + (StringUtils.countMatches(page, "href=\"#" + ID + "\"") + 1);
}
}
desc = desc.replace("${element.id}", ID);
desc = desc.replace("${element.id}", idProvider.getId(info));

// Events
Events events = c.getAnnotation(Events.class);
Expand Down Expand Up @@ -764,7 +737,7 @@ private String generateClass(String descTemp, ClassInfo<?> info, @Nullable Strin
// Assume element.pattern generate
for (String data : toGen) {
String[] split = data.split(" ");
String pattern = readFile(new File(template + "/templates/" + split[1]));
String pattern = readFile(new File(templateDir + "/templates/" + split[1]));
StringBuilder patterns = new StringBuilder();
String[] lines = getDefaultIfNullOrEmpty(info.getUsage(), "Missing patterns.");
if (lines == null)
Expand Down Expand Up @@ -819,7 +792,7 @@ private String generateFunction(String descTemp, JavaFunction<?> info) {
desc = desc.replace("${element.keywords}", keywords == null ? "" : Joiner.on(", ").join(keywords));

// Documentation ID
desc = desc.replace("${element.id}", info.getName());
desc = desc.replace("${element.id}", idProvider.getId(info));

// Events
desc = handleIf(desc, "${if events}", false); // Functions do not require events nor plugins (at time writing this)
Expand Down Expand Up @@ -854,14 +827,9 @@ private String generateFunction(String descTemp, JavaFunction<?> info) {
// Assume element.pattern generate
for (String data : toGen) {
String[] split = data.split(" ");
String pattern = readFile(new File(template + "/templates/" + split[1]));
String pattern = readFile(new File(templateDir + "/templates/" + split[1]));
String patterns = "";
Parameter<?>[] params = info.getParameters();
String[] types = new String[params.length];
for (int i = 0; i < types.length; i++) {
types[i] = params[i].toString();
}
String line = docName + "(" + Joiner.on(", ").join(types) + ")"; // Better not have nulls
String line = info.getSignature().toString(true, false); // Better not have nulls
Pikachu920 marked this conversation as resolved.
Show resolved Hide resolved
patterns += pattern.replace("${element.pattern}", line);

desc = desc.replace("${generate element.patterns " + split[1] + "}", patterns);
Expand Down
Loading