Dealing with Hash Marks (#) in Hotstrings (AutoHotkey Quick Tip)

When Using the Pound Sign (#) in Hotstring Replacement Text, We Must Take Special Steps to Prevent It from Going Missing…I Mean Disappearing

RobotHashtagCartoonSome would say that we should call the # character an octothorpe. Others insist upon using it in place of the pound weight (# not £). You’ll commonly find it used as the number sign—as in apartment #205 or #2 pencil. Editors use # to tell whomever to add space between two words. In some computer languages, the # sign precedes comments. In Web URLs, the # indicates a “jump to” link within the same page. On Twitter, people insert # to precede topic references as a hashtag (#jellybeans). (People often use the term “hashtag” to show off their technological smarts—#sarcasm.) In AutoHotkey, we use the # symbol as the Hotkey modifying character for the Windows key (microsoft_key).

Library Benefits

As discussed in “Adding Italics to Hotstrings in Word Processing Software (AutoHotkey Quick Tip)“, any time you include a Hotkey Modifier Symbol in a Hotstring, AutoHotkey interprets it as part of a Hotkey shortcut—activating the key combination while removing the characters. This works great for situations such as adding italics to text in word processing programs (^i) but causes a problem when you want the plain vanilla character to appear in a Hotstring replacement. Fortunately, you’ll find the manual fix fairly simple. If you want automatic correction in the InstantHotstring.ahk program, things get a little more complicated.

Converting Modifier Symbols into Raw Text

In order to prevent the # from acting as a Hotkey modifier and disappearing from a Hotstring statement, you need to convert it into raw text. AutoHotkey offers two basic methods for producing raw text in the replacement string:

  1. Use the Text Mode (T option) to convert the entire replacement string into raw text—thus disabling all Hotkey modifying characters (^!#+) plus the magical curly brackets (e.g. {Enter}). Note: Prior to a more recent release, AutoHotkey used the R option to convert the entire replacement text into raw text. While you can continue to use the R option, the newer T (Text) option may provide better reliability.
  2. Enclose any modifying symbols within curly brackets (e.g. {#}). By using this approach, you can mix raw characters with functional Hotkey combinations. (Note: If you put any Hotkey modifying characters in curly brackets, don’t use the Raw Text Mode.) With the T option mode active, all curly brackets will display in the replacement text.

Tip: Starting the replacement text with {raw} also sets the entire string to raw output. The {raw} parameter when preceding the replacement text does not display:

::abc::{raw}Shows modifiers ^,#,!, +, and curly brackets {}!

Each approach to generating raw text offers benefits but as a general rule use the Raw Text Mode (T) unless you need to mix active and inactive modifying characters.

Raw Text in the InstantHotstring.ahk Script

If you write your Hotstrings scripts by hand, then merely add the appropriate option or brackets directly to the Hotstring statement. When running the InstantHotstring.ahk script, you can do the same by either adding the curly brackets to the appropriate places of the Replacement Text or clicking the Raw Text Mode (T) checkbox control.

InstantHotstring Hashtag
Disable individual Hotkey modifying characters by placing curly brackets around the symbol. To disable all the active characters, implement the Raw Text Mode (T). Don’t do both!

As a new feature in the InstantHotstring.ahk script, I’ve added two new conditional routines as checks for Hotstrings containing Hotkey activation symbols:

  1. A pop-up MsgBox command window which displays whenever AutoHotkey detects Hotkey modifying symbols within the Replacement Text—then offering to implement the Raw Text Mode.
  2. An automatic setting of the Hotstring Raw Text Mode for any Web URL detected in the Replacement Text without any special formatting (i.e. {…}).

It all started with the # used for internal page jumps in Web URLs.

Disabling the # “Jump to” Character in URLs

The Hotkey modifying symbol problem surfaced when I attempted to add a Web URL with a page jump (#) to my list of AutoHotkey Command Hotstrings:

Since I didn’t add the T option, AutoHotkey attempted to activate the # character and removed it from the result:

Of course, the missing # prevented the URL from working properly.

It seems easiest to warn InstantHotstring.ahk script users about any special character(s) appearing in the Replacement Text and offer either to set the Hotstring to the raw mode or leave it alone. But first, the script must identify the troublesome characters.

Identifying Hotkey Modifying Symbols

If you want AutoHotkey to simultaneously look for separate characters in a line of text, you’ll find using a Regular Expression (RegExMatch() function) works better than the InStr() function. Although faster than the RegExMatch() function, the InStr() function only allows a search for a single group of characters. With the RegExMatch() function, we can locate any single instance from a set of characters in a string:

If RegExMatch(TextInsert, "[!+#^]", Modifier)

Cover 200In the above conditional, if any one of the characters between the square brackets exists in the variable TextInsert, the expression evaluates as true.

Note: The CTRL symbol (^) cannot appear at the beginning of the set of characters within the brackets because in Regular Expressions placing the up arrow (^) as the first token in the range tells RegExMatch() to match whenever each of the enclosed characters do not appear (e.g. [^…]) in the text—but it would not include ^ in the list of symbols.

However, if we have already enclosed a character or some text within curly brackets (e.g. {#} or {Return}), then we don’t want to disable those special effects:

RegExMatch(TextInsert, "{.*}") = 0

The RegEx {.*} matches any set of curly brackets within the text string which encloses zero or more (.*) characters. Evaluates false when none appear.

If the Hotstring already includes the Text Mode (T) option, then AutoHotkey has disabled all special effects:

 (InStr(Options,"T") = 0 or InStr(Options,"T0"))

The absence of the Text Mode option tells us to display the needed warning.

Notice that I enclosed the entire set of expressions in parentheses. I do this because AutoHotkey must evaluate these two conditions as a unit—either no T option or the T0 option—both mean no raw text option implemented.

Finally, I added a marker (the variable LoadHotstrings) to tell AutoHotkey when the InstantHotstring.ahk script adds Hotstrings from a file. I don’t want a multitude of MsgBox command warnings windows popping up while loading saved Hotstring code from a file:

LoadHotstrings = 0

The script sets LoadHotstring to 1 whenever loading and activating Hotstrings from a file, then resets LoadHotstring to 0 when done.

By chaining these conditions together in a group where each sub-expression must evaluate true, the script detects the appropriate instance for issuing a MsgBox command warning while ignoring other non-volatile Hotstrings:

If RegExMatch(TextInsert, "[!+#^{}]" , Modifier)
    and RegExMatch(TextInsert, "{.*}") = 0
    and (InStr(Options,"T") = 0 or InStr(Options,"T0"))
    and (LoadHotstrings = 0)
  MsgBox,3,Modifier Found, Hotkey modifier %modifier% found
      !`rSet Raw Text Mode?

(The above snippet uses line continuation techniques to wrap lines of code for display purposes. The code actually comprises only two continuous lines—the If conditional line and the MsgBox command line.)

The logical-AND operator (and) forces each sub-expression to evaluate true for the entire expression to return true.

The remainder of the code changes the Hotstring options settings based upon the user response to the MsgBox:

If RegExMatch(TextInsert, "[!+#^{}]" , Modifier)
    and RegExMatch(TextInsert, "{.*}") = 0
    and (InStr(Options,"T") = 0 or InStr(Options,"T0"))
    and (LoadHotstrings = 0)
  MsgBox,3,Modifier Found, Hotkey modifier %modifier% found
      !`rSet Raw Text Mode?
        IfMsgBox Yes
          If InStr(Options,"T0")
            Options := StrReplace(Options,"T0","T")
            Options := Options . "T"
          Control, Check, , Button7, A  ; Raw Text Mode

If responding “Yes” to the MsgBox, the script adds the T option to the Options string and checks the Raw Text Mode (T) CheckBox control.

If the Hotstring requires individual tailoring, the user clicks “No”, edits the text, adding curly brackets as necessary, then resets the Hotstring.

Dealing with Web URL Hotstrings

Since, in my mind, Hotstring activating characters (e.g. #) and other special features should appear only as raw text in Web URLs, I put together a conditional similar to the one above which turns all HTTP type replacement text into raw text—unless it contains a set of the magical curly paratheses:

If (InStr(TextInsert,"{#}") = 0 
    and InStr(TextInsert,"http") 
    and (InStr(Options,"T") = 0
    or InStr(Options,"T0")))
  If InStr(Options,"T0")
    Options := StrReplace(Options,"T0","T")
    Options := StrReplace(Options,"O0","O")
    Options := Options . "T"
    Options := Options . "O"
  Control, Check, , Button7, A  ; Raw Text Mode
  Control, Check, , Button6, A  ; Raw Text Mode

This snippet offers no MsgBox command warnings. If the Replacement Text contains “HTTP”, no jump-to mark ({#}), and no raw T option, it sets the Raw Text Mode (T) on and adds the No End Char (O) option—since, usually, you don’t want an extra character at the end of the URL. The disappearing # problem solved!

You could write more complicated code which cycles through the tainted Replacement Text fixing the individual issues detected but that runs beyond the scope of this blog. It could be overkill.

You can find both of snippets above in context in the InstantHotstring.ahk script.

*          *          *

The more I dig into these Hotstring issues, the more topics I find worth addressing—some on a beginner level and some more advanced. These subjects don’t always emphasize Hotstrings, but they all help develop a better understanding of the inner workings of AutoHotkey. While I have covered most of the items found on my original  InstantHotstring.ahk script list of issues, I have one remaining item and a couple of new ones:

  1. Loading Hotstrings from .ahk files (on the original list).
  2. Creating sample files without using the FileInstall command.
  3. Dealing with the peculiarities of the C Hotstring option.

But, next time, I’ll offer some beginning tips for how curly brackets work in Hotstrings and a couple of useful tricks which you can implement in one-line Hotstrings.

Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)


This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)


2 thoughts on “Dealing with Hash Marks (#) in Hotstrings (AutoHotkey Quick Tip)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s