AutoHotKey
Lookup Table to Abbreviation Expansion via AutoHotKey Hotstring
Below is an example that is based on Summation but could be applied to a number of different applications, as long as the abbreviation & expanded full-text data is somehow
retrievable. The first part is the script that would be run in the Scripting window of Summation, followed later by the code that would be put into an .ahk script.
The code is only in draft form, without any of them there declared varibles and whatnot. Even as a draft the script wound up taking siginficantly longer to create than I
had originally estimated, though in large part the additional work was testing-related and had to do with hinkiness particular to
the AutoHotKey HotString replacement behavior. The only line in the script that should need to be customized before a given run would be
lookupTableName = "_Names" where the lookup table name needs to be appropriate for a particular database:
The general steps performed by the vs code:
- assign the code that will limit the character(s) that trigger a hotstring expansion, via #Hotstring EndChars declaration
- create arrays of the values in the Code Column (arrShort) and Expansion Column (arrLong)
- for each item pair in the arrays, create the appropriate hotstring snippet
- where some of the snippet code will involve manually removing the initial abbreviation characters and for that we need to know how many characters to remove
via the backspace key
- get the string text that will represent the ahk function for checking to see if the hotstring text is actually being typed into Summation, and that the 'correct' case
is open
- write the final ahk script to a text file and display in a Summation HTML view
VBScript
Call Main
Sub Main
lookupTableName = "_Names"
delim = "%"
blazeType = SystemInfo.BlazeType()
thisCase = CurrentCase.Name
hotstringEndCharCode = ";restrict hotstring activation to colon character" & vbCrLf & _
"#Hotstring EndChars :" & vbCrLf
code = hotstringEndCharCode
newCode = ""
lookupShort = db.GetLkupEntries(lookupTableName, 1, delim)
lookupLong = db.GetLkupEntries(lookupTableName, 2, delim)
arrShort = Split(lookupShort, delim)
arrLong = Split(lookupLong, delim)
If (UBound(arrShort ) = UBound(arrLong )) Then
For i = 0 To UBound(arrShort)
newCode = AssembleHotString(arrShort(i), arrLong(i))
code = code & vbCrLf & newCode
If i = 500 Then
Exit For 'escape hatch
End If
Next
Else
Alert "Mismatch between codecol and expansioncol in lookup table"
End If
SummFunctionCode = GetSummationIsActiveText(blazeType, thisCase)
code = code & vbCrLf & SummFunctionCode
Set fso = CreateObject("Scripting.FileSystemObject")
codeFilePath = CurrentCase.CaseDir & "AHK" & lookupTableName & ".txt"
Set codeFile = fso.CreateTextFile(codeFilePath, True)
codeFile.Write code
codeFile.Close
AddHTMLView "AutoHotKey code for lookup table: " & lookupTableName, codeFilePath
Set codeFile = Nothing
Set fso = Nothing
End Sub
Function AssembleHotString(abbr, expand)
'thisCode = ""
backspaceString = GetBackSpaces(abbr)
thisCode = ":B0:" & abbr & "::" & vbCrLf & "If (SummationIsActive())" & vbCrLf & vbTab & _
"Send " & backspaceString & expand & vbCrLf & "return" & vbCrLf
AssembleHotString = thisCode
End Function
Function GetBackSpaces(abbr)
stringLength = Len(abbr)
returnString = "{BS}"
For x = 1 To stringLength
returnString = returnString & "{BS}"
Next
GetBackSpaces = returnString
End Function
Function GetSummationIsActiveText(productName, currentCase)
functionText = "SummationIsActive()" & vbCrLf & "{" & vbCrLf & _
vbTab & "local status ;declare variable" & vbCrLf & _
vbTab & "SetTitleMatchMode, 1 ;window title must begin with selected string" & vbCrLf & _
vbTab & "IfWinActive " & productName & " ;match product name" & vbCrLf & _
vbTab & vbTab & "SetTitleMatchMode, 2 ;window title must contain string somewhere" & vbCrLf & _
vbTab & vbTab & "IfWinActive '" & currentCase & "' ;match current case name" & vbCrLf & _
vbTab & vbTab & vbTab & ";optionally could have assembled full window title using sw's " & _
"SystemInfo and CurrentCase object" & vbCrLf & _
vbTab & vbTab & vbTab & "status = true" & vbCrLf & _
vbTab & "return status" & vbCrLf & "}" & vbCrLf
GetSummationIsActiveText= functionText
End Function
When the .vs script above is executed in the P. Franc demo case of Summation, something like the following text should appear in a new HTML view:
ahk
;restrict hotstring activation to colon character
#Hotstring EndChars :
:B0:BCO::
If (SummationIsActive())
Send {BS}{BS}{BS}{BS}Beth Cook
return
:B0:BED::
If (SummationIsActive())
Send {BS}{BS}{BS}{BS}Bruce Edwards
return
... (bunch more hotstring snippets) ...
:B0:WJA::
If (SummationIsActive())
Send {BS}{BS}{BS}{BS}William Jackson
return
SummationIsActive()
{
local status ;declare variable
SetTitleMatchMode, 1 ;window title must begin with selected string
IfWinActive CT Summation iBlaze® ;match product name
SetTitleMatchMode, 2 ;window title must contain string somewhere
IfWinActive 'CopyCase P. Franc' ;match current case name
;optionally could have assembled full window title using sw's SystemInfo
;and CurrentCase object
status = true
return status
}
And then you might notice that something moderately unpleasant has happened and that there are a few hundred hotstring snippets even though this particular _Names table
only has 31 records. Looks like db.GetLkupEntries could use some fixin', where it appears to be returning all occurrences/references of a Lookup
table on the current form - presumably there are 13 fields on the e-form that link to _Names since the method returned the same 31 values 13 times. I'm sure there is a workaround
(at the least, if in iBlaze, a SELECT via a direct ADO connection would be cleaner) but this is a one-time kind of need so it is easier to first just lop off the '#Hotstring EndChars :'
string. To that add the 31 correct snippets (WARNING: last & first of 31 abbreviations were concatenating as a single string) + code for SummationIsActive function and paste
those into a text file with a .ahk extension.
The first line of the generated ahk script relates to the triggering of any hotstring. By default there are a number of 'ending characters' and codes
( -()[]{}':;"/\,.?!`n `t) that, when typed after the abbreviation characters, result in expansion. Those default trigger characters might
work OK here but there were enough _Names entries, most quite short, that they could have been easily triggered by mistake. Simply type the word 'bed' followed by hitting the space
bar and that word would always be replaced with 'Bruce Edwards', perhaps totally out of context. Instead we tell AutoHotKey that the hotstrings should only act as hotstrings
if they are suffixed with a colon, now need to type 'bed:' in order to get the full 'Bruce Edwards' response.
ahk
#Hotstring EndChars :
Looking at the specifics of a given hotstring:
ahk
:B0:BCO::
If (SummationIsActive())
Send {BS}{BS}{BS}{BS}Beth Cook
return
The first line represents the abbreviation that will trigger the expanded replacement string and we can compare that entire snippet to a hotstring using the default
AutoHotKey syntax:
ahk
::BCO::Beth Cook
In the standard hotstring syntax, type the characters 'BCO' (case-insensitive by default, which can be changed) pretty much anywhere in any program, and they will
be instantly replaced with the characters 'Beth Cook'. In our version the first difference is the 'B0' (letter B followed by zero) between the first two colons, which
relates 'Automatic Backspacing' behavior. Automatic Backspacing = true is the default behavior - type the shortcut and the shortcut characters are removed and replaced
with the expansion. In our case we don't want to do that since the hotstrings should only trigger when the text is being typed into Summation. With automatic backspacing,
the expansion would occur before we had the chance to check what the active window is.
After the hotstring declaration, there is a check to see if Summation is the currently active window and then a series of characters is sent to the screen:
C#
If (SummationIsActive())
Send {BS}{BS}{BS}{BS}Beth Cook
return
The '{BS}' reference is an AutoHotKey constant representing the Backspace key. In this example, there are four backspaces sent, one for the ':' colon character that triggered
the expansion + three for the number of characters in 'BCO' (calculated in the Summation script by the GetBackSpaces function). After the abbreviation is cleared out,
the expansion text is delivered and the hotstring function is complete. In theory, the multiple backspaces could have been replaced with by sending keystrokes that would
represent 'Shift+Ctrl+LeftArrow', 'LeftArrow', thereby highlighting the 'BCO:' text. Sending keystrokes after that would delete the highlighted text. However, if the
'select left' keystroke combo spec'd out above is executed in the Column view of Summation, the result will be unhelpful - cursor focus will move left by a couple of cells
and that's all.
The SummationIsActive function is responsible for checking to see if the Summation is the application currently receiving UI input. The design here is only one approach,
where we first see if the title of active window begins with 'CT Summation iBlaze®' and if so, check to see if the designated case name (determined by the initial .vs script
when it is run) is part of that window title. If both those conditions are true, the status return variable is set to true.
ahk
SummationIsActive()
{
local status ;declare variable
SetTitleMatchMode, 1 ;window title must begin with selected string
IfWinActive CT Summation iBlaze® ;match product name
SetTitleMatchMode, 2 ;window title must contain string somewhere
IfWinActive 'P. Franc Vs. K. Morris (version 2.5)' ;match current case name
;optionally could have assembled full window title using sw's SystemInfo
;and CurrentCase object
status = true
return status
}
One area for improvement in the SummationIsActive function would be with the product name check, where the .vs script could have used SystemInfo.BlazeName
in order to dynamically set the correct window prefix. That way the Enterprise product line would be covered also. Another alternative would have been to use the
ahk_class of the main Summation window, e.g. SummationBlazeClass, in place of the window title. Using the ahk_class, which can be discovered via the Window Spy utility that
ships with AutoHotKey,is particular helpful in scenarios where the title of the target window is dynamic and can't be matched extactly. Also helpful in scenarios where
the section of the title that remains constant could conceivably appear as part of another program's title. As an example, the IfWinActive search could look for the
string 'Mozilla Firefox' but be tricked if it finds an already open IE tab that contains 'Mozilla Firefox' in its title. Substituting Firefox's ahk_class,
_MozillaUIWindowClass, would get around that problem.
Now some of the caveats: