Ag uses an embedded Lua interpreter (version 5.4.6) to execute scripts. This lets you extend Ag's capabilities in lots of interesting ways.

Example scripts
Console window
Scripting functions
Scripting differences in agc
String arrays
Lua copyright notice

 
Example scripts

The supplied Scripts folder contains a number of example scripts:

conundrums.lua — generates 9-letter anagrams made from 2 words
crossword.lua — creates a random crossword puzzle
escape-codes.lua — shows the console's supported escape sequences
ladders.lua — finds word ladders
lexstats.lua — displays statistics about the current lexicon
monotonic.lua — finds longest monotonic words in the current lexicon
palindromes.lua — finds all palindromes in the current lexicon
wordle.lua — a simple version of the Wordle game

To run one of these scripts you can select the "Run Script" item in the File menu, or click on the file name in the "Show Files" panel, or simply click on one of the above links. If you'd like to open the script in your preferred text editor then right-click or control-click on the file name or link.

 
Console window

A console window will automatically appear whenever you run a script. This window displays output generated by Lua's print and io.write functions, as well as any error messages. The console text can't be modified but it can be selected and copied to the clipboard. The text is automatically cleared when you run another script.

Note that a script can clear the console by calling io.write("\27c"). This is an example of an ANSI escape sequence. To see the full set of escape sequences supported by the console, run escape-codes.lua.

The "+" and "-" keys can be used to change the size of text in the console window. Any styling or coloring caused by escape sequences will be lost, so you'll need to hit the Run button to display that information at the new text size.

There are a number of ways to abort a long-running script. Hit the escape key or the return/enter keys, or click on the Stop button in the console window. When the script finishes the Stop button changes to a Run button so you can easily run the script again. Closing the console window will also abort a running script.

 
Scripting functions

This section describes all the Ag-specific functions that can be used in a script. (Note that Ag and agc can both run scripts and both support the same set of functions, but a few functions behave differently in agc. The following descriptions assume Ag is running the script.)

ag.adjacent
ag.anagrams
ag.check
ag.clear
ag.exit
ag.getchars
ag.getdir
ag.getstring
ag.gui
ag.help
ag.lexiconpath
ag.lexiconwords
ag.loadlexicon
ag.lower
ag.note
ag.numchars
ag.numeric
ag.savelexicon
ag.setoption
ag.upper
ag.usablewords
ag.wordfound

ag.adjacent(word1, word2)
Returns true if the given lexicon words differ by only 1 letter. It assumes the words have the same number of letters (note that they might not have the same number of bytes if they contain non-ASCII letters). This function is used to speed up the creation of adjacency graphs in ladders.lua.
Example: if ag.adjacent("dog","dig") then print(true) end

ag.anagrams(text)
Returns an array of anagrams for the given text. Each anagram is a single string, where multiple words are separated by spaces. See the description of ag.setoption for how to change various options used by this function.
Example: local a = ag.anagrams("andrewtrevorrow")

ag.check()
This function does nothing other than check for user events (such as a click in the Stop button). You only need to call this function when doing some lengthy task that doesn't call print() or any other ag.* functions.
Example: for i = 1, 1000000 do ag.check() dostuff() end

ag.clear(numlines)
Deletes the given number of lines from the end of the console text, or the entire text if no number is supplied. The function also returns the current number of lines in the console after the deletion (if any). Useful for displaying progress information without filling the console with lots of lines.
Example: if ag.clear(0) > 1000 then ag.clear() end

ag.exit(message)
Exits the script with an optional error message. If a message is supplied then it will be displayed in the console along with a beep. If no message is supplied then there is no beep and nothing will appear in the console.
Example: if i < 0 then ag.exit("Oops") end

ag.getchars(text)
Returns an array containing each character (possibly non-ASCII) in the given text.
Example: local chars = ag.getchars(word)

ag.getdir(dirname)
Returns the path of the specified directory:

"app" — the directory containing the Ag application.

"data" — the directory for user-specific data:
On Linux: ~/.ag/
On Mac: ~/Library/Application Support/Ag/
On Windows: C:\Users\username\AppData\Roaming\Ag\

"temp" — a directory for storing temporary files. All these files are deleted when Ag quits.

In each case a full path is returned, terminated by the appropriate path separator for the current platform.
Example: local f = io.open(ag.getdir("data").."mydata.txt", "w")

ag.getstring(prompt, default, title)
Displays a dialog box and returns a string entered by the user. If the default string is supplied it will be shown and selected. If the title string is supplied it will be used in the dialog's title bar. The script will be aborted if the user hits the dialog's Cancel button.
Example: local n = tonumber(ag.getstring("Enter a number:","100"))

ag.gui()
Returns true if Ag is running the script, or false if agc is running the script.
Example: if ag.gui() then print("this is Ag") end

ag.help(htmlfile)
Displays the given HTML file in the help window. A non-absolute path is relative to the location of the script.
Example: ag.help("results.html")

ag.lexiconpath()
Returns the full path of the current lexicon.
Example: print("Current lexicon is", ag.lexiconpath())

ag.lexiconwords(pattern="*")
Returns an array of words from the current lexicon that match the given pattern. If no pattern is supplied then the table contains all the words in the lexicon. See the description of ag.setoption for how to change a couple of options used by this function.
Example: local zwords = ag.lexiconwords("z*")

ag.loadlexicon(filepath)
Loads the given file and sets the current lexicon used by future calls of ag.lexiconwords, ag.anagrams and ag.usablewords. Note that it does not change the lexicon used by Ag's main window. A non-absolute path is relative to the location of the script. If the given file is not an Ag lexicon file then it's assumed to be a text file and the unique words or numbers will be extracted, as described here.
Example: ag.loadlexicon(ag.getdir("app").."Lexicons/Words.lex")

ag.lower(string)
Returns the lowercase version of the given string. Unlike Lua's string.lower function, ag.lower will correctly convert any uppercase non-ASCII letters in the string, as long as they are valid lexicon letters.
Example: print(ag.lower("ÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÆØŒŸ"))

ag.note(message)
Pauses the script and displays the given string in a modal dialog.
Example: ag.note("Line 1\nLine 2\nLine 3")

ag.numchars(text)
Returns the number of characters (possibly non-ASCII) in the given text.
Example: if ag.numchars(word) == 3 then print(word) end

ag.numeric()
Returns true if the current lexicon is a numeric lexicon.
Example: if ag.numeric() then print("lexicon is numeric") end

ag.savelexicon(filepath)
Saves the current lexicon in the given file. A non-absolute path is relative to the location of the script.
Example: ag.savelexicon("mylexicon.lex")

ag.setoption(name, value)
When a script starts up it inherits the current options used by the main Ag window (along with the current lexicon). Scripts can use ag.setoption to override those options and change the behavior of later ag.* calls. Here are all the option names, their possible values, and the ag.* functions they affect:

"minlength" minimum word length (1 to 30)
used by ag.anagrams, ag.usablewords
 
"maxlength" maximum word length (1 to 30)
used by ag.anagrams, ag.usablewords
 
"minwords" minimum words in an anagram (1 to 50)
used by ag.anagrams
 
"maxwords" maximum words in an anagram (1 to 50)
used by ag.anagrams
 
"maxanagrams" maximum number of anagrams (0 = no limit)
used by ag.anagrams
 
"increase" anagram words increase in length (true or false)
used by ag.anagrams
 
"alphabetic" return words in alphabetical order (true or false)
used by ag.lexiconwords, ag.usablewords
 
"uppercase" return words in uppercase (true or false)
used by ag.anagrams, ag.lexiconwords, ag.usablewords

Example: ag.setoption("maxanagrams", 1000)

ag.upper(string)
Returns the uppercase version of the given string. Unlike Lua's string.upper function, ag.upper will correctly convert any lowercase non-ASCII letters in the string, as long as they are valid lexicon letters.
Example: print(ag.upper("ááâäãåçéèêëíìîïñóòôöõúùûüæøœÿ"))

ag.usablewords(text)
Returns an array of all the words that can be made from the letters in the given text. See the description of ag.setoption for how to change various options used by this function.
Example: local u = ag.usablewords("retsina")

ag.wordfound(word)
Returns true if the given word exists in the current lexicon.
Example: if ag.wordfound("cat") then patcat() end

 
Scripting differences in agc

The agc command can also run Lua scripts (using the -r option). All of the above functions can be used but there are some minor differences:

 
String arrays

A number of ag.* functions return arrays containing strings. These are standard Lua arrays — that is, tables indexed by integers where the first string has index 1. All the strings use the UTF-8 encoding and might contain non-ASCII characters, so to count the characters in a string you should avoid using the standard Lua length operator "#" as it returns the number of bytes. Instead, use ag.numchars to return the number of characters:

if ag.numchars(word) > 2 then print(word) end

And to extract each character in a UTF-8 string you can use ag.getchars:

for _, ch in ipairs(ag.getchars(word)) do print(ch) end

Note that the Lua functions string.lower and string.upper don't convert non-ASCII characters correctly, so use ag.lower and ag.upper instead.

 
Lua copyright notice

Copyright © 1994–2023 Lua.org, PUC-Rio.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.