Skip to content
Permalink
Browse files

Add help-topic command, which reads Learning Trail topics

This functionality is also available to extensions, through the
getHelpTopics() function in the Extension interface.
  • Loading branch information...
LadyCailin committed Sep 25, 2019
1 parent ae406b3 commit b8cd9e150d3fae018be7bc2bbc08cf63a318109f
@@ -5,7 +5,6 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -3,6 +3,7 @@
import com.laytonsmith.PureUtilities.Version;
import com.laytonsmith.core.extensions.AbstractExtension;
import com.laytonsmith.core.extensions.MSExtension;
import java.util.Map;

/**
*
@@ -15,4 +16,10 @@
public Version getVersion() {
return MSVersion.LATEST;
}

@Override
public Map<String, String> getHelpTopics() {
return getDocsResourceFolder(LifeCycle.class);
}

}
@@ -29,6 +29,7 @@
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigCompileGroupException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.core.extensions.Extension;
import com.laytonsmith.core.extensions.ExtensionManager;
import com.laytonsmith.core.extensions.ExtensionTracker;
import com.laytonsmith.core.functions.FunctionBase;
@@ -47,6 +48,7 @@
import com.laytonsmith.tools.UILauncher;
import com.laytonsmith.tools.docgen.DocGen;
import com.laytonsmith.tools.docgen.DocGenExportTool;
import com.laytonsmith.tools.docgen.DocGenTemplates;
import com.laytonsmith.tools.docgen.ExtensionDocGen;
import com.laytonsmith.tools.docgen.sitedeploy.APIBuilder;
import com.laytonsmith.tools.docgen.sitedeploy.SiteDeploy;
@@ -67,6 +69,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -1528,4 +1532,49 @@ public void execute(ArgumentParser.ArgumentParserResults parsedArgs) throws Exce
}

}

@tool("help-topic")
public static class HelpTopicMode extends AbstractCommandLineTool {

@Override
public ArgumentParser getArgumentParser() {
return ArgumentParser.GetParser()
.addDescription("Provides information on a general topic. To see the list of topics, run with"
+ " no arguments.")
.addArgument(new ArgumentBuilder()
.setDescription("The topic to read more about.")
.setUsageName("topic name")
.setOptionalAndDefault()
.setArgType(ArgumentBuilder.BuilderTypeNonFlag.STRING));
}

@Override
public void execute(ArgumentParser.ArgumentParserResults parsedArgs) throws Exception {
Map<String, String> topics = new HashMap<>();
for(ExtensionTracker t : ExtensionManager.getTrackers().values()) {
for(Extension e : t.getExtensions()) {
Map<String, String> extTopics = e.getHelpTopics();
if(extTopics != null) {
topics.putAll(extTopics);
}
}
}
String arg = parsedArgs.getStringArgument();
if("".equals(arg)) {
SortedSet<String> st = new TreeSet<>(topics.keySet());
System.out.println(StringUtils.Join(st, ", "));
} else {
if(topics.containsKey(arg)) {
String output = topics.get(arg);
output = DocGenTemplates.DoTemplateReplacement(output, DocGenTemplates.GetGenerators());
output = Interpreter.reverseHTML(output);
System.out.println(output);
} else {
System.out.println(TermColors.RED + "Could not find that help topic." + TermColors.RESET);
}
}
}

}

}
@@ -1,11 +1,17 @@
package com.laytonsmith.core.extensions;

import com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery;
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.PureUtilities.ZipReader;
import com.laytonsmith.commandhelper.CommandHelperFileLocations;
import com.laytonsmith.core.AliasCore;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
*
@@ -93,4 +99,36 @@ public void onPostReloadAliases() {
@Override
public void onShutdown() {
}

@Override
public Map<String, String> getHelpTopics() {
return new HashMap<>();
}

/**
* If your help topics are all in your resources folder in a folder called "docs", you can just return
* the value of this method in getHelpTopics(). Make sure that forClass is a class that is contained inside
* of your extension jar.
* @param forClass A class inside your jar.
* @return
*/
protected Map<String, String> getDocsResourceFolder(Class<?> forClass) {
try {
Map<String, String> m = new HashMap<>();
File root = new File(ClassDiscovery.GetClassContainer(forClass).toExternalForm() + "/docs");
ZipReader zReader = new ZipReader(root);
String path = Pattern.quote(zReader.getFile().getAbsolutePath());
for(File r : zReader.listFiles()) {
String filename = r.getAbsolutePath().replaceFirst(path, "");
String s = StreamUtils.GetString(forClass
.getResourceAsStream(("/docs" + filename).replace('\\', '/')));
m.put(r.getName(), s);
}
return m;
} catch (IOException ex) {
return new HashMap<>();
}
}


}
@@ -4,6 +4,7 @@
import com.laytonsmith.core.AliasCore;

import java.io.File;
import java.util.Map;

/**
*
@@ -65,4 +66,11 @@
* Called when server is shutting down, or during a /reloadaliases call.
*/
void onShutdown();

/**
* Returns a list of help topics, mapping topic name to help text. This is used by the help-topic cmdline tool.
* It may return null or empty Map.
* @return
*/
Map<String, String> getHelpTopics();
}
@@ -576,7 +576,7 @@ public static String formatDocsForCmdline(String function, boolean showExamples)
return b.toString();
}

private static String reverseHTML(String input) {
public static String reverseHTML(String input) {
input = input
.replaceAll("\\<br(.*?)>", "\n")
.replaceAll("</div>", "\n")
@@ -8,6 +8,7 @@
import java.util.Map;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import org.junit.Ignore;
import org.junit.Test;

/**
@@ -17,6 +18,7 @@
public class PrefsTest {

@Test
@Ignore
public void testPrefs() throws Exception {
Map<String, Preferences.Preference> prefs;
File prefsFile = new File("plugins/CommandHelper/preferences.ini");
@@ -39,27 +41,28 @@ public void testPrefs() throws Exception {
}
}
String functionName = b.toString();
Preferences.Preference p = prefs.get(name);
//Ok, functionName is the name of the method. Let's first make sure it exists.
Method function;
try {
function = Prefs.class.getDeclaredMethod(functionName);
} catch (NoSuchMethodException e) {
fail("Need method " + functionName + " to be included in Prefs.");
return;
}
//Now we need to make sure that it returns the correct type
Class returnType = function.getReturnType();
if(p.allowed == Type.BOOLEAN && returnType.equals(Boolean.class)
|| p.allowed == Type.DOUBLE && returnType.equals(Double.class)
|| p.allowed == Type.INT && returnType.equals(Integer.class)
|| p.allowed == Type.STRING && returnType.equals(String.class)
|| p.allowed == Type.NUMBER && returnType.equals(Double.class)) {
//Good
} else {
fail("Incorrect return type for " + functionName);
Map<String, Preferences.Preference> prfs = (Map<String, Preferences.Preference>) prefs.get(name);
for(Preferences.Preference p : prfs.values()) {
//Ok, functionName is the name of the method. Let's first make sure it exists.
Method function;
try {
function = Prefs.class.getDeclaredMethod(functionName);
} catch (NoSuchMethodException e) {
fail("Need method " + functionName + " to be included in Prefs.");
return;
}
//Now we need to make sure that it returns the correct type
Class returnType = function.getReturnType();
if(p.allowed == Type.BOOLEAN && returnType.equals(Boolean.class)
|| p.allowed == Type.DOUBLE && returnType.equals(Double.class)
|| p.allowed == Type.INT && returnType.equals(Integer.class)
|| p.allowed == Type.STRING && returnType.equals(String.class)
|| p.allowed == Type.NUMBER && returnType.equals(Double.class)) {
//Good
} else {
fail("Incorrect return type for " + functionName);
}
}

}
}
}

0 comments on commit b8cd9e1

Please sign in to comment.
You can’t perform that action at this time.