NewFunctionsScript

From Kolmafia
Jump to navigation Jump to search

Guide To Add New Functions To Wiki Via Script

1. Gather Ashref Functions

  • Open KoLmafia and sign-in.
  • Type the following in the CLI
debug on
ashref
debug off
  • Create a file called "AshRef Function List.txt" in the KoLmafia folder.
  • Locate the "DEBUG_####.txt" file in KoLmafia folder and open it.
  • Copy paste all the functions found between the two debugs into the "AshRef Function List.txt" text file.
  • See below as an example:
    void <a href='https://wiki.kolmafia.us/index.php?title=abort'>abort</a>( string )
    void <a href='https://wiki.kolmafia.us/index.php?title=abort'>abort</a>(  )
    boolean [monster] <a href='https://wiki.kolmafia.us/index.php?title=absorbed_monsters'>absorbed_monsters</a>(  )
    void <a href='https://wiki.kolmafia.us/index.php?title=add_item_condition'>add_item_condition</a>( int, item )
    void <a href='https://wiki.kolmafia.us/index.php?title=add_item_condition'>add_item_condition</a>( item, int )
    boolean <a href='https://wiki.kolmafia.us/index.php?title=adv1'>adv1</a>( location, int, string )

2. Gather Current Wiki Functions

  • Create a file called "WikiPage.txt" in the KoLmafia folder.
  • Go to the wiki page Ash Functions and click "Edit Source" https://wiki.kolmafia.us/index.php?title=Ash_Functions&action=edit
  • Copy paste the entire edit page into the created "WikiPage.txt".
  • See below as an example:
    {{TOCright}}
    Master list of all ASH functions. All functions as of r27333 are listed; this list is intended to be kept current, but it is possible that some functions added since the above revision may be missing. (Please feel free to add in any you notice.)
    The CLI command "[[ashref]]" shows every implemented ash function for your mafia version.
    
    ===a===
    {{FunctionEmbed|abort|format=signature}}
    {{Flink|boolean [monster]|absorbed_monsters}}
    ...etc

3. Running the Script

  • Create a new .ash file in the KoLmafia folder (can be named anything)
  • Copy paste the following code into it and run it.
  • It will output a new text file called "NewWikiPage.txt" with the added functions from the ashref function list.
    # Turns the file into a map but keeps any newlines / comments
    string[int] fileToMap (string file) {
    	string[int] out;
    	int ct = 1;
    	matcher finder = create_matcher("[^\\n]+\\n|[^\\n]+", file_to_buffer(file));
    	while (find (finder)) {
    		out[ct] = group(finder);
    		ct = ct+1;
    	}
    	return out;
    }
    
    # Turns a map of strings into a buffer
    buffer mapToBuffer (string[int] map) {
    	buffer o;
    	foreach k, v in map {
    		o = append(o, v);
    	}
    	return o;
    }
    
    # Returns the first capture group found
     string regexCapture (string regex, string text) {
    	matcher f = create_matcher(regex, text);
    	string o = "";
    	if (find(f)) {
    		for i from 1 to group_count(f) {
    			o = group(f, i);
    			if (o != "")
    				return o;
    		}
    	}
    	return o;
     }
    	
    //Copy Paste the wiki into text file and then call this function, Creates a list of all the functions on the wiki
    string[int] createFunctionListFromWikiPage(string textFile) {
    	buffer file = file_to_buffer (textFile);
    	string[int] wiki; //Wiki is list of functions on wiki while ash is functions from ashref
    	string regex = "(?:Flink\\|[^\\|]+\\|)([\\w\\d]+)|(?:FunctionEmbed\\|)([\\w\\d]+)";
    	matcher finder = create_matcher(regex, file);
    	int ct = 1;
    	
    	# print(file);
    	while (find (finder)) {
    		if (group(finder, 1) != "")
    			wiki[ct] = group(finder, 1);
    		else
    			wiki[ct] = group(finder, 2);
    		ct = ct + 1;
    	}
    	# foreach i, func in wiki {print(func, "blue");}
    	return wiki;
    }
    
    //Copy Paste the wiki into text file and then call this function, Creates a list of all the functions on the wiki
    string createFunctionListFromWikiText (string test) {
    	string wiki; //Wiki is functions on wiki 
    	string regex = "(?:Flink\\|[^\\|]+\\|)([\\w\\d]+)|(?:FunctionEmbed\\|)([\\w\\d]+)";
    	matcher finder = create_matcher(regex, test);
    	while (find (finder)) {
    		if (group(finder, 1) != "")
    			wiki = group(finder, 1);
    		else
    			wiki = group(finder, 2);
    	}
    	return wiki;
    }
    
    # Turn debug on and run ashref. Turn debug off and copy paste the ashrefs from the debug file.
    string[int] createFunctionListFromAshRef(string textFile) {	
    	# Creating a list of wiki acceptable functions using the flink notation
    	buffer file = file_to_buffer (textFile);
    	matcher finder = create_matcher("([\\w\\d]+)\\(", file);
    	int ct = 1;
    	string[int] ashFuncs;
    	while (find (finder)) {
    		if (group(finder, 1) != "")
    			ashFuncs[ct] = group(finder, 1);
    		else
    			ashFuncs[ct] = group(finder, 2);
    		ct = ct + 1;
    	}
    	# foreach i, func in ashFuncs {print(func, "blue");}
    	return ashFuncs;
    }
    
    //Use function on ashref textfile (that has had its links replaced)
    string[string] createWikiFlinkFunctions (string textFile){
    	buffer file = file_to_buffer (textFile);
    	string[string] ash; #Map will be key of flinkInfo, val of functionName
    	string regex = "(\\[[^\\]]+\\])|([\\w\\[\\]]+)|([\\(\\)])";
    	matcher finder = create_matcher(regex, file);
    	string temp = "{{Flink";
    	string text, capture;
    	while (find (finder)) {
    		text = group(finder);
    		if(contains_text(text, "[")) #Map parameters
    			temp = temp + " " + text;
    		else if (text == ")") { #End of function
    			temp = temp + "}}";
    			capture = regexCapture("(?:Flink[^\\]]+(?=\\]))\\]\\|([\\w\\d]+)|(?:Flink\\|[^\\|]+\\|)([\\w\\d]+)", temp);
    			ash[temp] = capture;
    			temp = "{{Flink"; #Prep for next function
    		}
    		else if (text == "(") {} #Start of inputs
    		else 
    			temp = temp + "|" + text; #everything else
    		# foreach i, func in ash {print(func, "blue");}
    	}
    	# foreach key, val in ash {print ("Key: " + key + ". Val: " + val);}
    	# buffer_to_file(mapToBuffer(mapBufferFile ("WikiPageTest.txt")), "WikiPageTest2.txt");
    	
    	return ash;
    }
     
    buffer regexBufferReplace (string regex, string newText, buffer text) {
    	matcher m = create_matcher(regex, text);
    	buffer b;
    	while (m.find()) {
    		append_replacement(m,b , newText);
    	}
    	return append_tail(m, b);
    }
     
     void main() {
    	print ("Starting to generate the new wiki page from the ashref function list!", "blue");
    	string wikiTextFile = "WikiPage.txt";
    	string ashRefFile = "AshRef Function List.txt";
    	string newWikiFile = "NewWikiPage.txt";
    	buffer newWiki, ashRefs, file;
    	record wikiInfo { 
    		 string func;
    		 string flink;
    	};
    	wikiInfo[int] wikiFunctions;
    	string temp;
    	string[int] wikiFuncs, wikiFile;
    	boolean[string] ashFuncs;
    	string[string] ashrefFlinkFuncs, completedFuncs;
    	ashRefs = file_to_buffer(ashRefFile);
    	if (contains_text (ashRefs, "<")) { # Contains hyper links, remove them
    		ashRefs = regexBufferReplace("<[^\>]+>", "", ashRefs);
    		buffer_to_file(ashRefs, ashRefFile);
    	}
    	ashrefFlinkFuncs = createWikiFlinkFunctions(ashRefFile);
    	wikiFile = fileToMap ("WikiPage.txt");
    
    	# Comb the existing wiki to keep any of the already updated functions. I.e. functions that have FunctionEmbed, opt, /, or any 
    	foreach i, line in wikiFile {
    		if (contains_text(line, "FunctionEmbed") || contains_text(line, "{{opt") || contains_text(line, "/") || contains_text(line, "any")) { #Remove existing entries that have been completed
    			temp = createFunctionListFromWikiText(line);
    			foreach key, func in ashrefFlinkFuncs {		#Also skipping any {{opt functions as I don't know that info so better to not mess with
    				if(temp == func) {
    					remove ashrefFlinkFuncs[key]; #Remove the current iteration
    					completedFuncs[line] = func; #Replace it with the embed or opt
    					ashFuncs[func] = true;
    				}
    			}
    		}
    	}
    	
    	# Make sure we didn't skip/miss any functions that had multiple entries but with different input parameters
    	foreach i, line in wikiFile {
    		temp = createFunctionListFromWikiText(line);
    		if (ashFuncs[temp]) 
    			completedFuncs[line] = temp;
    	}
    		
    	# Add the remainning new functions to the completed list
    	foreach key, func in ashrefFlinkFuncs {completedFuncs[key] = func;}
    	
    	# Set the completed list to the new record for ease of sorting
    	foreach k, v in completedFuncs { 
    		wikiFunctions[count(wikiFunctions)] = new wikiInfo(v, k);
    	}
    	
    	# Sort the record by alphabetical
    	sort wikiFunctions by value.flink;	
    	sort wikiFunctions by value.func;
    	
    	# foreach k, v in wikiFunctions { print ("Key: " + v.flink + ". Val: " + v.func);}
    	
    	# Copy text from wikiFile until "==="
    	foreach i, line in wikiFile {
    		if (contains_text(line, "==="))
    			break;
    		else 
    			append(newWiki, line);
    	}
    	
    	# Start adding our alphabetical designations
    	append(newWiki, "===a===");
    	string alpha = "a";
    	string wikiText;
    	
    	# Now loop through our wikiFunctions, building the new wiki page
    	foreach k, v in wikiFunctions {
    		append(newWiki, "\n");
    		temp = substring(v.func, 0, 1);
    		wikiText = regexCapture("([^\\n]+)", v.flink);
    		if (temp == alpha)
    			append(newWiki, wikiText);
    		else {
    			append(newWiki, "\n");
    			append(newWiki, "===" + temp + "===\n");
    			append(newWiki, wikiText);
    			alpha = temp;
    		}
    	}
    	
    	#Tack on the existing wiki page ending, everything after the last function
    	int ct = count(wikiFile);
    	while (!contains_text(wikiFile[ct], "{{")) {
    		ct = ct - 1;
    	}
    	ct = ct + 1;
    	for i from ct to count(wikiFile){
    		append(newWiki, wikiFile[i]);
    	}
    	
    	#Replace any "null" with type of "any"
    	newWiki = regexBufferReplace("\\|null", "|any", newWiki);
    	
    	#Write the newWiki
    	buffer_to_file(newWiki, newWikiFile);
    	print ("Ended. The new wiki page can be found in: " + newWikiFile, "green");
     }

4. Sanity Check & Committing

  • Open the text file "NewWikiPage.txt" found in the KoLMafia folder.
  • Copy paste it into a diff checker (I use https://www.diffchecker.com/)
  • Copy paste the text from the "WikiPage.txt" as the original and the "NewWikiPage.txt" as the new.
  • Review results to make sure it didn't go crazy.
  • Commit the updated function page to the wiki once everything looks good.
  • Remember to change the revision number to the kolmafia number you used!