package com.laytonsmith.tools.docgen;
import com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery;
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.PureUtilities.Common.StringUtils;
import com.laytonsmith.abstraction.Implementation;
import com.laytonsmith.annotations.api;
import com.laytonsmith.annotations.typeof;
import com.laytonsmith.commandhelper.CommandHelperFileLocations;
import com.laytonsmith.core.CHLog;
import com.laytonsmith.core.Documentation;
import com.laytonsmith.core.Installer;
import com.laytonsmith.core.Optimizable;
import com.laytonsmith.core.Prefs;
import com.laytonsmith.core.constructs.CFunction;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.events.Event;
import com.laytonsmith.core.exceptions.CRE.CREThrowable;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.extensions.ExtensionManager;
import com.laytonsmith.core.functions.ExampleScript;
import com.laytonsmith.core.functions.Function;
import com.laytonsmith.core.functions.FunctionBase;
import com.laytonsmith.core.functions.FunctionList;
import com.laytonsmith.tools.SimpleSyntaxHighlighter;
import com.laytonsmith.tools.docgen.templates.Template;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*
*/
public class DocGen {
public static void main(String[] args) throws Exception {
try{
//Boilerplate startup stuff
Implementation.setServerType(Implementation.Type.BUKKIT);
ClassDiscovery.getDefaultInstance().addDiscoveryLocation(ClassDiscovery.GetClassContainer(DocGen.class));
ExtensionManager.Initialize(ClassDiscovery.getDefaultInstance());
Installer.Install(CommandHelperFileLocations.getDefault().getConfigDirectory());
Prefs.init(CommandHelperFileLocations.getDefault().getPreferencesFile());
CHLog.initialize(CommandHelperFileLocations.getDefault().getConfigDirectory());
//StreamUtils.GetSystemOut().println(functions("wiki", api.Platforms.INTERPRETER_JAVA, true));
StreamUtils.GetSystemOut().println(examples("if", true));
//System.exit(0);
//events("wiki");
//StreamUtils.GetSystemOut().println(Template("persistence_network"));
} catch(Throwable t){
t.printStackTrace();
System.exit(1);
} finally {
System.exit(0);
}
}
public static String examples(String function, boolean staged) throws Exception {
FunctionBase fb = FunctionList.getFunction(new CFunction(function, Target.UNKNOWN));
if(fb instanceof Function){
Function f = (Function)fb;
String restricted = (f instanceof Function && ((Function)f).isRestricted()) ? "<div style=\"background-color: red; font-weight: bold; text-align: center;\">Yes</div>"
: "<div style=\"background-color: green; font-weight: bold; text-align: center;\">No</div>";
String optimizationMessage = "None";
if(f instanceof Optimizable){
Set<Optimizable.OptimizationOption> options = ((Optimizable)f).optimizationOptions();
List<String> list = new ArrayList<String>();
for(Optimizable.OptimizationOption option : options){
list.add("[[CommandHelper/" + (staged?"Staged/":"") + "Optimizer#" + option.name() + "|" + option.name() + "]]");
}
optimizationMessage = StringUtils.Join(list, "<br />");
}
DocInfo di = new DocInfo(f.docs());
StringBuilder thrown = new StringBuilder();
if (f instanceof Function && ((Function)f).thrown() != null) {
List thrownList = Arrays.asList(((Function)f).thrown());
for (int i = 0; i < thrownList.size(); i++) {
String t = ((Class<? extends CREThrowable>) thrownList.get(i)).getAnnotation(typeof.class).value();
if (i != 0) {
thrown.append("<br />\n");
}
thrown.append("[[CommandHelper/Exceptions#").append(t).append("|").append(t).append("]]");
}
}
String tableUsages = di.originalArgs.replace("|", "<hr />");
String [] usages = di.originalArgs.split("\\|");
StringBuilder usageBuilder = new StringBuilder();
for(String usage : usages){
usageBuilder.append("<pre>\n").append(f.getName()).append("(").append(usage.trim()).append(")\n</pre>");
}
StringBuilder exampleBuilder = new StringBuilder();
if(f.examples() != null && f.examples().length > 0){
int count = 1;
//If the output was automatically generated, change the color of the pre
for(ExampleScript es : f.examples()){
exampleBuilder.append("====Example ").append(count).append("====\n")
.append(es.getDescription()).append("\n\n"
+ "Given the following code:\n");
exampleBuilder.append(SimpleSyntaxHighlighter.Highlight(es.getScript())).append("\n");
String style = "";
if(es.isAutomatic()){
style = " style=\"background-color: #BDC7E9\"";
exampleBuilder.append("\n\nThe output would be:\n<pre");
} else {
exampleBuilder.append("\n\nThe output might be:\n<pre");
}
exampleBuilder.append(style).append(">").append(es.getOutput()).append("</pre>\n");
count++;
}
} else {
exampleBuilder.append("Sorry, there are no examples for this function! :(");
}
Class[] seeAlso = f.seeAlso();
String seeAlsoText = "";
if(seeAlso != null && seeAlso.length > 0){
seeAlsoText += "===See Also===\n";
boolean first = true;
for(Class c : seeAlso){
if(!first){
seeAlsoText += ", ";
}
first = false;
if(Function.class.isAssignableFrom(c)){
Function f2 = (Function)c.newInstance();
seeAlsoText += "<code>[[CommandHelper/" + (staged?"Staged/":"") + "API/" + f2.getName() + "|" + f2.getName() + "]]</code>";
} else if(Template.class.isAssignableFrom(c)){
Template t = (Template)c.newInstance();
seeAlsoText += "[[CommandHelper/" + (staged?"Staged/":"") + t.getName() + "|Learning Trail: " + t.getDisplayName() + "]]";
} else {
throw new Error("Unsupported class found in @seealso annotation: " + c.getName());
}
}
}
Map<String, String> templateFields = new HashMap<>();
templateFields.put("function_name", f.getName());
templateFields.put("returns", di.ret);
templateFields.put("tableUsages", tableUsages);
templateFields.put("throws", thrown.toString());
templateFields.put("since", f.since().toString());
templateFields.put("restricted", restricted);
templateFields.put("optimizationMessage", optimizationMessage);
templateFields.put("description", di.extendedDesc==null?di.desc:di.topDesc + "\n\n" + di.extendedDesc);
templateFields.put("usages", usageBuilder.toString());
templateFields.put("examples", exampleBuilder.toString());
templateFields.put("staged", staged?"Staged/":"");
templateFields.put("seeAlso", seeAlsoText);
String template = StreamUtils.GetString(DocGenTemplates.class.getResourceAsStream("/templates/example_templates"));
//Find all the %%templates%% in the template
Matcher m = Pattern.compile("%%(.*?)%%").matcher(template);
try{
while(m.find()){
String name = m.group(1);
String templateValue = templateFields.get(name);
template = template.replaceAll("%%" + Pattern.quote(name) + "%%", templateValue.replace("$", "\\$").replaceAll("\\'", "\\\\'"));
}
return template;
} catch(RuntimeException e){
throw new RuntimeException("Caught a runtime exception while generating template for " + function, e);
}
} else {
throw new RuntimeException(function + " does not implement Function");
}
}
/**
* Returns the documentation for a single function.
* @param type The type of output to use. May be one of: html, wiki, text
* @param platform The platform we're using
* @param staged Is this for the staged wiki?
* @return
* @throws ConfigCompileException
*/
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public static String functions(MarkupType type, api.Platforms platform, boolean staged) throws ConfigCompileException {
Set<FunctionBase> functions = FunctionList.getFunctionList(platform);
HashMap<Class, ArrayList<FunctionBase>> functionlist = new HashMap<Class, ArrayList<FunctionBase>>();
StringBuilder out = new StringBuilder();
for (FunctionBase f: functions) {
//Sort the functions into classes
Class apiClass = (f.getClass().getEnclosingClass() != null
? f.getClass().getEnclosingClass()
: null);
ArrayList<FunctionBase> fl = functionlist.get(apiClass);
if (fl == null) {
fl = new ArrayList<FunctionBase>();
functionlist.put(apiClass, fl);
}
fl.add(f);
}
if (type == MarkupType.HTML) {
out.append("Command Helper uses a language called MethodScript, which greatly extend the capabilities of the plugin, "
+ "and make the plugin a fully "
+ "<a href=\"http://en.wikipedia.org/wiki/Turing_Complete\">Turing Complete</a> language. "
+ "There are several functions defined, and they are grouped into \"classes\". \n");
} else if (type == MarkupType.WIKI) {
out.append("Command Helper uses a language called MethodScript, which greatly extend the capabilities of the plugin, "
+ "and make the plugin a fully "
+ "[http://en.wikipedia.org/wiki/Turing_Complete Turing Complete] language. "
+ "There are several functions defined, and they are grouped into \"classes\". \n");
out.append("<p>Each function has its own page for documentation, where you can view examples for how to use a"
+ " particular function.\n");
} else if (type == MarkupType.TEXT) {
out.append("Command Helper uses a language called MethodScript, which greatly extend the capabilities of the plugin, "
+ "and make the plugin a fully "
+ "Turing Complete language [http://en.wikipedia.org/wiki/Turing_Complete].\n"
+ "There are several functions defined, and they are grouped into \"classes\".\n");
}
List<Map.Entry<Class, ArrayList<FunctionBase>>> entrySet = new ArrayList<Map.Entry<Class, ArrayList<FunctionBase>>>(functionlist.entrySet());
Collections.sort(entrySet, new Comparator<Map.Entry<Class, ArrayList<FunctionBase>>>() {
@Override
public int compare(Map.Entry<Class, ArrayList<FunctionBase>> o1, Map.Entry<Class, ArrayList<FunctionBase>> o2) {
return o1.getKey().getName().compareTo(o2.getKey().getName());
}
});
int total = 0;
int workingExamples = 0;
for (Map.Entry<Class, ArrayList<FunctionBase>> entry : entrySet) {
Class apiClass = entry.getKey();
String className = apiClass.getName().split("\\.")[apiClass.getName().split("\\.").length - 1];
if (className.equals("Sandbox")) {
continue; //Skip Sandbox functions
}
String classDocs = null;
try {
Method m = apiClass.getMethod("docs", (Class[]) null);
Object o = null;
if ((m.getModifiers() & Modifier.STATIC) == 0) {
try {
o = apiClass.newInstance();
} catch (InstantiationException ex) {
}
}
classDocs = (String) m.invoke(o, (Object[]) null);
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
} catch (NoSuchMethodException e) {
} catch (Exception e){
e.printStackTrace(StreamUtils.GetSystemErr());
StreamUtils.GetSystemErr().println("Continuing however.");
}
StringBuilder intro = new StringBuilder();
if (type == MarkupType.HTML) {
if (className != null) {
intro.append("<h1>").append(className).append("</h1>" + "\n");
intro.append(classDocs == null ? "" : classDocs).append("\n");
} else {
intro.append("<h1>Other Functions</h1>" + "\n");
}
intro.append("<table>" + "\n");
} else if (type == MarkupType.WIKI) {
if (className != null) {
intro.append("===").append(className).append("===" + "\n");
intro.append(classDocs == null ? "" : classDocs).append("\n");
} else {
intro.append("===Other Functions===" + "\n");
}
intro.append("{| width=\"100%\" cellspacing=\"1\" cellpadding=\"1\" border=\"1\" class=\"wikitable\"\n"
+ "|-\n"
+ "! scope=\"col\" width=\"6%\" | Function Name\n"
+ "! scope=\"col\" width=\"5%\" | Returns\n"
+ "! scope=\"col\" width=\"10%\" | Arguments\n"
+ "! scope=\"col\" width=\"10%\" | Throws\n"
+ "! scope=\"col\" width=\"61%\" | Description\n"
+ "! scope=\"col\" width=\"3%\" | Since\n"
+ "! scope=\"col\" width=\"5%\" | Restricted" + "\n");
} else if (type == MarkupType.TEXT) {
intro.append("\n").append(className).append("\n");
intro.append("**********************************************************************************************" + "\n");
if (className != null) {
intro.append(classDocs == null ? "" : classDocs).append("\n");
} else {
intro.append("Other Functions" + "\n");
}
intro.append("**********************************************************************************************" + "\n");
}
List<FunctionBase> documentableFunctions = new ArrayList<FunctionBase>();
for(FunctionBase f : entry.getValue()){
if(f.appearInDocumentation()){
documentableFunctions.add(f);
}
}
if(!documentableFunctions.isEmpty()){
out.append(intro.toString() + "\n");
}
Collections.sort(documentableFunctions, new Comparator<FunctionBase>() {
@Override
public int compare(FunctionBase o1, FunctionBase o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (FunctionBase f : documentableFunctions) {
total++;
String doc = f.docs();
String restricted = (f instanceof Function && ((Function)f).isRestricted()) ? "<div style=\"background-color: red; font-weight: bold; text-align: center;\">Yes</div>"
: "<div style=\"background-color: green; font-weight: bold; text-align: center;\">No</div>";
StringBuilder thrown = new StringBuilder();
if (f instanceof Function && ((Function)f).thrown() != null) {
List<Class<? extends CREThrowable>> thrownList = Arrays.asList(((Function)f).thrown());
for (int i = 0; i < thrownList.size(); i++) {
String t = ((Class<? extends CREThrowable>) thrownList.get(i)).getAnnotation(typeof.class).value();
if (type == MarkupType.HTML || type == MarkupType.TEXT) {
if (i != 0) {
thrown.append((type == MarkupType.HTML ? "<br />\n" : " | "));
}
thrown.append(t);
} else {
if (i != 0) {
thrown.append("<br />\n");
}
thrown.append("[[CommandHelper/Exceptions#").append(t).append("|").append(t).append("]]");
}
}
}
String since = (f instanceof Documentation ?((Documentation)f).since().toString():"0.0.0");
DocInfo di = new DocInfo(doc);
boolean hasExample = false;
if(f instanceof Function && ((Function)f).examples() != null && ((Function)f).examples().length > 0){
hasExample = true;
workingExamples++;
}
if (di.ret == null || di.args == null || di.desc == null) {
out.append(f.getName() + "'s documentation is not correctly formatted. Please check it and try again.\n");
}
if (type == MarkupType.HTML) {
out.append("<tr><td>" + di.ret + "</td><td>" + di.args + "</td><td>" + thrown.toString() + "</td><td>" + di.desc + "</td><td>" + since + "</td><td>" + restricted + "</td></tr>\n");
} else if (type == MarkupType.WIKI) {
//Turn args into a prettified version
out.append("|- id=\"" + f.getName() + "\"\n"
+ "! scope=\"row\" | [[CommandHelper/" + (staged?"Staged/":"") + "API/" + f.getName() + "|" + f.getName() + "]]()\n"
+ "| " + di.ret + "\n"
+ "| " + di.args + "\n"
+ "| " + thrown.toString() + "\n"
+ "| " + (di.topDesc != null ? di.topDesc + " [[CommandHelper/" + (staged?"Staged/":"") + "API/" + f.getName() + "#Description|See More...]]" : di.desc)
+ (hasExample?"<br />([[CommandHelper/" + (staged?"Staged/":"") + "API/" + f.getName() + "#Examples|Examples...]])":"") + "\n"
+ "| " + since + "\n"
+ "| " + restricted + "\n");
} else if (type == MarkupType.TEXT) {
out.append(di.ret + " " + f.getName() + "(" + di.args + ")" + " {" + thrown.toString() + "}\n\t" + di.desc + "\n\t" + since + ((f instanceof Function?((Function)f).isRestricted():false) ? "\n\tThis function is restricted"
: "\n\tThis function is not restricted\n"));
}
}
if(!documentableFunctions.isEmpty()){
if (type == MarkupType.HTML) {
out.append("</table>\n");
} else if (type == MarkupType.WIKI) {
out.append("|}\n{{Back to top}}\n");
} else if (type == MarkupType.TEXT) {
out.append("\n");
}
}
}
if (type == MarkupType.HTML) {
out.append(""
+ "<h2>Errors in documentation</h2>\n"
+ "<em>Please note that this documentation is generated automatically,"
+ " if you notice an error in the documentation, please file a bug report for the"
+ " plugin itself!</em>"
+ "<div style='text-size:small; text-decoration:italics; color:grey'>There are " + total + " functions in this API page</div>\n");
} else if (type == MarkupType.WIKI) {
out.append(""
+ "===Errors in documentation===\n"
+ "''Please note that this documentation is generated automatically,"
+ " if you notice an error in the documentation, please file a bug report for the"
+ " plugin itself!'' For information on undocumented functions, see [[CommandHelper/Sandbox|this page]]"
+ "<div style='font-size:xx-small; font-style:italic; color:grey'>There are " + total + " functions in this API page, " + workingExamples + " of which"
+ " have examples.</div>\n\n{{Back to top}}\n{{LearningTrail}}\n");
}
return out.toString();
}
public static String Template(String template, boolean staged){
Map<String, String> customTemplates = new HashMap<String, String>();
customTemplates.put("staged", staged?"Staged/":"");
return DocGenTemplates.Generate(template, customTemplates);
}
public static String events(MarkupType type) {
Set<Class<?>> classes = ClassDiscovery.getDefaultInstance().loadClassesWithAnnotation(api.class);
Set<Documentation> list = new TreeSet<Documentation>();
for (Class<?> c : classes) {
if (Event.class.isAssignableFrom(c)
&& Documentation.class.isAssignableFrom(c)) {
try {
//First, we have to instatiate the event.
Constructor<Event> cons = (Constructor<Event>)c.getConstructor();
Documentation docs = cons.newInstance();
list.add(docs);
} catch (Exception ex) {
StreamUtils.GetSystemErr().println("Could not get documentation for " + c.getSimpleName());
}
}
}
StringBuilder doc = new StringBuilder();
if (type == MarkupType.HTML) {
doc.append("Events allow you to trigger scripts not just on commands, but also on other actions, such as"
+ " a player logging in, or a player breaking a block. See the documentation on events for"
+ " more information"
+ "<table><thead><tr><th>Name</th><th>Description</th><th>Prefilters</th>"
+ "<th>Event Data</th><th>Mutable Fields</th><th>Since</th></thead><tbody>");
} else if (type == MarkupType.WIKI) {
doc.append("Events allow you to trigger scripts not just on commands, but also on other actions, such as"
+ " a player logging in, or a player breaking a block. See the [[CommandHelper/Events|documentation on events]] for"
+ " more information<br />\n\n");
doc.append("{| width=\"100%\" cellspacing=\"1\" cellpadding=\"1\" border=\"1\" class=\"wikitable\"\n"
+ "|-\n"
+ "! scope=\"col\" width=\"7%\" | Event Name\n"
+ "! scope=\"col\" width=\"36%\" | Description\n"
+ "! scope=\"col\" width=\"18%\" | Prefilters\n"
+ "! scope=\"col\" width=\"18%\" | Event Data\n"
+ "! scope=\"col\" width=\"18%\" | Mutable Fields\n"
+ "! scope=\"col\" width=\"3%\" | Since\n");
} else if (type == MarkupType.TEXT) {
doc.append("Events allow you to trigger scripts not just on commands, but also on other actions, such as"
+ " a player logging in, or a player breaking a block. See the documentation on events for"
+ " more information\n\n\n");
}
Pattern p = Pattern.compile("\\{(.*?)\\} *?(.*?) *?\\{(.*?)\\} *?\\{(.*?)\\}");
for (Documentation d : list) {
Matcher m = p.matcher(d.docs());
if (m.find()) {
String name = d.getName();
String description = m.group(2).trim();
String prefilter = PrefilterData.Get(m.group(1).split("\\|"), type);
String eventData = EventData.Get(m.group(3).split("\\|"), type);
String mutability = MutabilityData.Get(m.group(4).split("\\|"), type);
//String manualTrigger = ManualTriggerData.Get(m.group(5).split("\\|"), type);
String since = d.since().toString();
if (type == MarkupType.HTML) {
doc.append("<tr><td style=\"vertical-align:top\">").append(name).append("</td><td style=\"vertical-align:top\">").append(description).append("</td><td style=\"vertical-align:top\">").append(prefilter).append("</td><td style=\"vertical-align:top\">").append(eventData).append("</td><td style=\"vertical-align:top\">").append(mutability).append("</td><td style=\"vertical-align:top\">").append(since).append("</td></tr>\n");
} else if (type == MarkupType.WIKI) {
doc.append("|-\n" + "! scope=\"row\" | [[CommandHelper/Event API/").append(name).append("|").append(name).append("]]\n" + "| ").append(description).append("\n" + "| ").append(prefilter).append("\n" + "| ").append(eventData).append("\n" + "| ").append(mutability).append("\n" + "| ").append(since).append("\n");
} else if (type == MarkupType.TEXT) {
doc.append("Name: ").append(name).append("\nDescription: ").append(description).append("\nPrefilters:\n").append(prefilter).append("\nEvent Data:\n").append(eventData).append("\nMutable Fields:\n").append(mutability).append("\nSince: ").append(since).append("\n\n");
}
}
}
if (type == MarkupType.HTML) {
doc.append("</tbody></table>\n");
} else if (type == MarkupType.WIKI) {
doc.append("|}\n");
}
if (type == MarkupType.HTML) {
doc.append(""
+ "<h2>Errors in documentation</h2>\n"
+ "<em>Please note that this documentation is generated automatically,"
+ " if you notice an error in the documentation, please file a bug report for the"
+ " plugin itself!</em>\n");
} else if (type == MarkupType.WIKI) {
doc.append(""
+ "===Errors in documentation===\n"
+ "''Please note that this documentation is generated automatically,"
+ " if you notice an error in the documentation, please file a bug report for the"
+ " plugin itself!'' For information on undocumented functions, see [[CommandHelper/Sandbox|this page]]\n\n{{LearningTrail}}\n");
}
return doc.toString();
}
public static class PrefilterData {
public static String Get(String[] data, MarkupType type) {
StringBuilder b = new StringBuilder();
boolean first = true;
if(data.length == 1 && "".equals(data[0].trim())){
return "";
}
for (String d : data) {
int split = d.indexOf(':');
String name;
String description;
if(split == -1){
name = d;
description = "";
} else {
name = d.substring(0, split).trim();
description = ExpandMacro(d.substring(split + 1).trim(), type);
}
if (type == MarkupType.HTML) {
b.append(first ? "" : "<br />").append("<strong>").append(name).append("</strong>: ").append(description);
} else if (type == MarkupType.WIKI) {
b.append(first ? "" : "<br />").append("'''").append(name).append("''': ").append(description);
} else if (type == MarkupType.TEXT) {
b.append(first ? "" : "\n").append("\t").append(name).append(": ").append(description);
} else if(type == MarkupType.MARKDOWN){
b.append(first ? "" : " \n").append("**").append(name).append("**: ").append(description);
}
first = false;
}
return b.toString();
}
private static String ExpandMacro(String macro, MarkupType type) {
if (type == MarkupType.HTML) {
return "<em>" + macro
.replaceAll("<string match>", "<String Match>")
.replaceAll("<boolean match>", "<Boolean Match>")
.replaceAll("<regex>", "<Regex>")
.replaceAll("<item match>", "<Item Match>")
.replaceAll("<location match>", "<Location Match>")
.replaceAll("<math match>", "<Math Match>")
.replaceAll("<macro>", "<Macro>")
.replaceAll("<expression>", "<Expression>") + "</em>";
} else if (type == MarkupType.WIKI) {
return macro
.replaceAll("<string match>", "[[CommandHelper/Events/Prefilters#String Match|String Match]]")
.replaceAll("<boolean match>", "[[CommandHelper/Events/Prefilters#Boolean Match|Boolean Match]]")
.replaceAll("<regex>", "[[CommandHelper/Events/Prefilters#Regex|Regex]]")
.replaceAll("<item match>", "[[CommandHelper/Events/Prefilters#Item Match|Item Match]]")
.replaceAll("<location match>", "[[CommandHelper/Events/Prefilters#Location Match|Location Match]]")
.replaceAll("<math match>", "[[CommandHelper/Events/Prefilters#Math Match|Math Match]]")
.replaceAll("<macro>", "[[CommandHelper/Events/Prefilters#Macro|Macro]]")
.replaceAll("<expression>", "[[CommandHelper/Events/Prefilters#Expression|Expression]]");
} else if (type == MarkupType.TEXT || type == MarkupType.MARKDOWN) {
return macro
.replaceAll("<string match>", "<String Match>")
.replaceAll("<boolean match>", "<Boolean Match>")
.replaceAll("<regex>", "<Regex>")
.replaceAll("<item match>", "<Item Match>")
.replaceAll("<location match>", "<Location Match>")
.replaceAll("<math match>", "<Math Match>")
.replaceAll("<macro>", "<Macro>")
.replaceAll("<expression>", "<Expression>");
}
return macro;
}
}
public static class EventData {
public static String Get(String[] data, MarkupType type) {
StringBuilder b = new StringBuilder();
boolean first = true;
if(data.length == 1 && "".equals(data[0].trim())){
return "";
}
for (String d : data) {
int split = d.indexOf(':');
String name;
String description;
if(split == -1){
name = d;
description = "";
} else {
name = d.substring(0, split).trim();
description = d.substring(split + 1).trim();
}
if (type == MarkupType.HTML) {
b.append(first ? "" : "<br />").append("<strong>").append(name).append("</strong>: ").append(description);
} else if (type == MarkupType.WIKI) {
b.append(first ? "" : "<br />").append("'''").append(name).append("''': ").append(description);
} else if (type == MarkupType.TEXT) {
b.append(first ? "" : "\n").append("\t").append(name).append(": ").append(description);
} else if (type == MarkupType.MARKDOWN){
b.append(first ? "" : " \n").append("**").append(name).append("**").append(": ").append(description);
}
first = false;
}
return b.toString();
}
}
public static class MutabilityData {
public static String Get(String[] data, MarkupType type) {
StringBuilder b = new StringBuilder();
boolean first = true;
if(data.length == 1 && "".equals(data[0].trim())){
return "";
}
for (String d : data) {
int split = d.indexOf(':');
if (split == -1) {
if (type == MarkupType.HTML) {
b.append(first ? "" : "<br />").append("<strong>").append(d.trim()).append("</strong>");
} else if (type == MarkupType.WIKI) {
b.append(first ? "" : "<br />").append("'''").append(d.trim()).append("'''");
} else if (type == MarkupType.TEXT) {
b.append(first ? "" : "\n").append("\t").append(d.trim());
} else if (type == MarkupType.MARKDOWN){
b.append(first ? "" : " \n").append("**").append(d.trim()).append("**");
}
} else {
String name = d.substring(0, split).trim();
String description = d.substring(split).trim();
if (type == MarkupType.HTML) {
b.append(first ? "" : "<br />").append("<strong>").append(name).append("</strong>: ").append(description);
} else if (type == MarkupType.WIKI) {
b.append(first ? "" : "<br />").append("'''").append(name).append("''': ").append(description);
} else if (type == MarkupType.TEXT) {
b.append(first ? "" : "\n").append("\t").append(name).append(": ").append(description);
} else if (type == MarkupType.MARKDOWN){
b.append(first ? "" : " \n").append("**").append(name).append("**: ").append(description);
}
}
first = false;
}
return b.toString();
}
}
public static class DocInfo{
/**
* The return type
*/
public String ret;
/**
* The args, with html styling in place
*/
public String args;
/**
* The args, without html styling in place (but with [ brackets ] to denote optional arguments
*/
public String originalArgs;
/**
* The full description, if the ---- separator isn't present, or
* the top description if not present.
*/
public String desc;
/**
* The top description, or null if the ---- separator isn't present.
*/
public String topDesc = null;
/**
* The extended description, or null if the ---- separator isn't present.
*/
public String extendedDesc = null;
public DocInfo(String doc){
Pattern p = Pattern.compile("(?s)\\s*(.*?)\\s*\\{(.*?)\\}\\s*(.*)\\s*");
Matcher m = p.matcher(doc);
if (m.find()) {
ret = m.group(1);
originalArgs = m.group(2);
desc = m.group(3);
if(desc.contains("----")){
String [] parts = desc.split("----", 2);
desc = topDesc = parts[0].trim();
extendedDesc = parts[1].trim();
}
}
args = originalArgs.replaceAll("\\|", "<hr />").replaceAll("\\[(.*?)\\]", "<strong>[</strong>$1<strong>]</strong>");
}
}
public static enum MarkupType {
HTML, WIKI, TEXT, MARKDOWN;
}
}