Heading

This is some text inside of a div block.
This is some text inside of a div block.
This is some text inside of a div block.
min read

Toggle quotes around paragraph or sentence

Word • Macros • Editing • Functions
Peter Ronhovde
18
min read

You might have some quick notes about a conversation between characters or while editing decide some inner dialog should be spoken instead. Having a quick toggle for the double quotes would be convenient. Let the computer do computer stuff and save your human brain and fingers for author stuff.

Thanks for your interest

This content is part of a paid plan.

Toggle Quotes around a Paragraph or Sentence

Even though I’ve used quotes thousands of times, I don’t like typing them. I just find the mechanics of the keypress a little awkward (also part of the reason I started using a bunch of AutoCorrect abbreviations).

Why not automate it? Tiny improvements add up over time.

These macros are related to previous selection or navigation by punctuation macros, but here we’re adding or removing double quotes around a paragraph or sentence. We further add an intuitive option to apply double quotes specifically around an initial selection.

The resulting macros will also trivially extend to toggling parentheses (upcoming), and a more general member version applies quotes independently to multiple paragraphs.

Put on our thinkin' cap ...

We should probably think about a couple things before we get started.

Aren’t the paragraph and sentence macros similar?

Yeah, they’re so similar, in fact, it’s a great example of why we create separate functions to handle some tasks a little more generally. Then we get two or three macros for the price of one, and all of them are useful.

With this in mind, we previously created a function that toggles the quotes around any document range. That way, we don’t have to copy the same macro steps without only trivial changes between a sentence or a paragraph. If you want to also allow for parentheses or single quotes, then check out the upcoming more general toggle quotes function instead since the articles overlap.

What if there is a starting selection?

We should definitely consider any starting selection for most Word macros.

I like to assume the user selected the text on purpose, but the specific implementation of what to do with it depends on your preferences. There are two main options when deciding what is most convenient and useful in the context of the current task.

What then?

We can interpret an initial user selection literally (do not change it) or take it as a suggestion (interpret the meaning of the user selection) allowing users to make a “sloppy selection.”

Literal selection

We could just apply the double quotes function directly without any changes to the range other than any modifications made within the toggle quotes function we’re using.

We’ll use this approach in the first two macros today.

Sloppy selection

It’s often convenient to implement sloppy selections where we allow a user to make imprecise text selections.

Word does something like this when automatically extending a selection across words during a mouse drag selection. You can control this setting if you don’t like it (see Word → Settings → Edit in Word for Mac and File → Options → Advanced in Windows), but it was implemented because it’s often convenient. While it can be frustrating at times, I tend to leave it since it does make most text selection easier.

See the extended content below for this variation.

Why worry about this?

Convenience.

With one macro, you improve the efficiency of related tasks while also allowing the macro to work more intuitively. That’s a win in my book.

What’s the verdict?

Both options have merit when creating our own macros. I think sloppy selections are more convenient overall, but we’ll stick with the former approach initially because sometimes we do want quotes around specific text rather than what the macro thinks we mean. We also implement the sloppy selections option in the extended content below.

What’s the plan?

This is an example of a macro that is easy to generalize between sentences and paragraphs, and both versions are useful. Given the previous questions, what’s the plan?

  • Set a working range equal to the current selection, so we don’t alter the user’s selection if any.
  • If a selection exists, don’t change it.
  • If no text is selected, set the working range to the entire paragraph or sentence.
  • Run the toggle quotes function with the range.
  • End with the text selected as a visual indicator of the changes.

If you prefer a paragraph version that adds double quotes individually to each paragraph in the initial selection, see the more general version.

Create macro skeletons

Open the VBA editor (Option+ or Alt+F11) and create two empty macros.

Sub ToggleQuotesParagraph()
' Insert macro steps ...

End Sub
Sub ToggleQuotesSentence()
' Insert macro steps ...

End Sub

Macros we assign to a keyboard shortcut can’t have any parameters or return values. They also won’t appear in the macro list to run independently (accessed via the ribbon View → Macros → View Macros to open the macros dialog).

Define the working range

We define a working range using a brief range name r just to shorten the assignment and later commands.

Dim r As Range

We can get away without doing this much of the time, but we need to explicitly define the range using a Dim command since we're passing it to a function below.

Set the working range

The command is almost the same between paragraphs or sentences, but pay attention to the subtle difference below.

If we’re being extra concise, we can actually skip this steps (I tend to prefer concise macros), but they make the macro clearer for instructional purposes.

For initial selection

I prefer for my macros to handle common cases naturally, so what if a user wants quotes around specific text? To apply the quotes to the user selection, Set the working range to the current Selection’s Range.

Set r = Selection.Range

For paragraphs?

If we want the current paragraph, we can access it through the Paragraphs collection of the Selection.

Set r = Selection.Paragraphs.First.Range

We want the paragraph immediately at the insertion point, so this does the job quickly in one step. We’ve used other methods in the past, such as a Selection collapse followed by an Expand command, but they accomplish the same task for the most part (multi-paragraph selections change things some).

We access the First member of the Paragraphs collection, but this gives us a Paragraph (with a capital "P"). Paragraphs are specific objects in Word with their own properties (data) and methods (actions), so we need to tell VBA we want the Range for the referenced paragraph instead.

For sentences?

For sentences, we use the Sentences collection of the Selection instead.

Set r = Selection.Sentences.First

The difference is the Sentences collection contains a collection of Ranges. Unlike Paragraphs, Sentences are not their own object type in Word.

Collection types …

Unfortunately, there is some ambiguity in referencing elements of these two different collections.

Assuming we’re dealing with a collection that involves text in some way, any of the First, Last, or general Item references when retrieving elements of a collection sometimes return a specific object type. For other collections it can return a document range instead. It just depends on the collection type.

Technically a Range is an object also, but in terms of our document, a Range is a more general content reference than a Paragraph.

Collections that contain specific object types include Paragraphs, Sections, Bookmarks, and more. When you access a specific Item from one of these collections, you’ll get that object type not a Range. If we need the range of spanned document content, we can reference a corresponding Range property like we did with the Paragraph reference above.

Ranges are common variables since they represent a generic span of content in a document. Ranges have their own associated properties and methods (see brief introductory article). The main examples of collections where the elements are just document ranges are Sentences, Characters, and Words. These collections always return a corresponding range because they are not their own object type in Word.

Detecting the Selection Type

In our quest to make these macros more intuitive, we want to detect any current selection and apply quotes directly to the corresponding document range (see extended content for sloppy selections option). However, there are some details the worry about.

Detecting a normal selection

The obvious way to handle an initial user selection is to check whether it exists using the Selection’s Type property (see previous article for a brief explanation).

' Okay but could get us in trouble ...
If Selection.Type = wdSelectionNormal Then
' Normal selection, so directly apply quotes ...
Else
' No selection? Apply quotes to paragraph or sentence ...
End If

The basic logic attempted above is: if it’s a “normal” selection as indicated by the Selection Type wdSelectionNormal. Then apply quotes to it, but if not, then “it must be no selection.”

Nope.

We can’t just assume “no selection” if we don’t have a normal selection.

This conditional statement opens us up to a gotcha if the user has selected something besides text such as part of a table, a shape, or even a block selection. We can’t ignore the possibility if we’re slapping quotes around whatever is selected.

Ughhh.

Detecting no selection

We need to further clarify the Type of the selection before running any additional steps, so we add an extra conditional statement using an ElseIf to check for no selection.

If Selection.Type = wdSelectionNormal Then
' Normal selection, so directly apply quotes ...
ElseIf Selection.Type = wdSelectionIP Then
' No selection, so apply quotes to paragraph or sentence ...
End If

This is a little messier with the Else-If condition, but the advantage of this approach is it is specific.

See this previous article if you want a brief review of conditional statements and this article for a quick explanation of why we use wdSelectionIP to detect “no selection.”

But we're not quite done ...

Otherwise just exit

The above would be okay if we didn't have any steps after the conditional statement, but we do. We don’t want to act on any other Type of Selection, so we further add catchall Else.

If Selection.Type = wdSelectionNormal Then
' Normal selection, so directly apply quotes ...
ElseIf Selection.Type = wdSelectionIP Then
' No selection, apply quotes to paragraph or sentence ...
Else
' Another Selection Type detected, so just exit ...
End If

This way, nothing happens if the selection is not “normal” or one doesn’t exist. If the current selection isn’t one we “recognize” then we just exit the macro.

Exit Sub

Call range quotes function

The advantage of creating the more general toggle quotes function is we can just quickly call it for our newly determined range.

Set r = ToggleQuotesRange(r)

We reuse the same working range r in the Set command since we don’t care about the initial state.

If you want to finish the macro without selecting the modified text (see below), we could just Call the function instead.

' Alternative that ignores any returned range
Call ToggleQuotesRange(r) ' Not used here

This version ignores the returned range from the ToggleQuotesRange function if you we do nothing with it, but we needed to use a “Call” command since the function has an argument, specifically the range variable r in this case.

Select changed range

Finally select the changed text range.

r.Select ' Finish with text selected

This is optional, but I often like the visual indicator of what changed.

And … done.

Gotchas

Where could all this go wrong?

These macros are relatively safe since we’re only adding or removing specific individual characters. Probably the worst thing that could happen would be if the user types some text immediately after the macro finishes and accidentally deletes the selected text, but that should be relatively obvious at the time.

Final Macros with Literal Selection

The two macros below have an option to place double quotes around the specific selection. Otherwise, they will place double quotes around the current paragraph or sentence.

Toggle quotes around a paragraph

Putting all the commands together, the macro to toggle quotes around the current selection or paragraph is:

Sub ToggleQuotesParagraph()
' Toggle double quotes around current paragraph or selection

' Set range based on Selection Type
Dim r As Range
If Selection.Type = wdSelectionNormal Then
' Normal selection, so directly apply quotes
Set r = Selection.Range
ElseIf Selection.Type = wdSelectionIP Then
' No selection, so apply quotes to current paragraph
Set r = Selection.Paragraphs.First.Range
Else
' Another Selection Type, so just exit
Exit Sub
End If

' Apply quotes to detected range
Set r = ToggleQuotesRange(r)
r.Select ' Finish with text selected
End Sub

The ToggleQuotesRange function allows us to easily apply double quotes to either range.

I’ve assigned my version of this macros to Command+Q or Control+Q on Mac or Windows, respectively.

Common commands

The If statement in this macro decides the range to which we’re applying double quotes, but the other commands at the bottom are used either way. Collecting common commands together after a conditional statement like this is … common.

The Else statement above to exit the macro is important. Without it the common commands at the bottom would run even if an unrecognized Selection Type was detected.

Toggle quotes around a sentence

The macro to toggle quotes around the current sentence is very similar:

Sub ToggleQuotesSentence()
' Toggle double quotes around current sentence or selection

' Set range based on Selection Type
Dim r As Range
If Selection.Type = wdSelectionNormal Then
' Normal selection, so directly apply quotes
Set r = Selection.Range
ElseIf Selection.Type = wdSelectionIP Then
' No selection, so apply quotes to current sentence
Set r = Selection.Sentences.First
Else
' Another Selection Type, so just exit
Exit Sub
End If

' Apply quotes to detected range
Set r = ToggleQuotesRange(r)
r.Select ' Finish with text selected
End Sub

I’ve assigned Option+Q in Word for Mac and Alt+Q Windows as keyboard shortcuts for my version of this macro.

There is a little overlap in functionality between the paragraph and sentence versions where both macros directly apply quotes to any currently selected text, but that is just to provide the intuitive behavior with the initially selected text. The rest of the steps are also very similar, but there's just enough difference with the paragraph or sentence selection that it would be annoying and probably overkill to extract a common function to use.

See the extended content below if you’re interested in a variation that instead allows for sloppy selections letting the macro detect the sentence extent.

Final Macros with Sloppy Selections

This is definitely a macro where you might tailor it to your personal preferences. For example, I implement some macros where I allow “sloppy selections” for convenience. That is, I allow myself to select only part of the relevant paragraphs (or whatever document element), but the quotes are still correctly placed around the paragraphs.

Of course, we sometimes sacrifice other option(s) when implementing such a variation. After all, a selection can only mean “this exact text” or “all paragraphs or sentences I’m partially selecting.” It can’t mean both at the same time.

What changes?

So what changes compared to the previous versions above?

Interestingly, the sloppy selection process negates the need for detecting the current selection type (unless you want to keep a failsafe check) because it automatically expands the working range over the current sentence or paragraph even if we start with an insertion point. It just happens to also work for multiple contiguous sentences or paragraphs.

Getting the whole sentence or paragraph

After we define the initial working range, we want to extend it backward in the document to the beginning of the sentence.

r.StartOf Unit:=wdParagraph, Extend:=wdExtend

StartOf with the Extend option set to wdExtend moves the Start position of the range to the beginning of the given Unit without changing the End position. Without Extend, the command would collapse the range and move it to the same location. The difference between StartOf and a regular Move command is StartOf will not keep moving if the range is already at the beginning of the given Unit.

The corresponding EndOf command moves the End position of the range to the end of the given Unit.

r.EndOf Unit:=wdParagraph, Extend:=wdExtend

Of course, swap out the wdParagraph Unit constant for wdSentence in the sentence variation of the macro.

What about Expand?

Technically, the Expand command would do this in one step.

r.Expand Unit:=wdParagraph ' Not quite sure ...

While this seems to work the same as the above two commands, the documentation for Expand unfortunately doesn’t specifically state how it works or whether it is intended to work with more than one paragraph (or whatever document Unit) or not. The documentation page is rather terse, and it uses singular references to the Expand Unit consistently. I’m not a fan of taking advantage of a possible side effect rather than an intended action. The former commands are clear and specific even if they use two steps, and I don’t have to wonder what will happen.

Toggle quotes around a paragraph

A macro to toggle quotes around the current paragraph or around the entirety of several paragraphs is:

Sub ToggleQuotesParagraphSloppy()
' Toggle double quotes around current paragraph(s) as a group
' Allows for initially incomplete paragraph selection

' Just use initial selection even if an insertion point
Dim r As Range
Set r = Selection.Range

' Extend range to include full paragraph(s) both directions
r.StartOf Unit:=wdParagraph, Extend:=wdExtend
r.EndOf Unit:= wdParagraph, Extend:=wdExtend

' Toggle double quotes and select result
Set r = ToggleQuotesRange(r)
r.Select ' Finish with text selected
End Sub

This sloppy version applies double quotes across one or even multiple paragraphs as a group as opposed to being individually applied to each paragraph. Both versions have merit, but the latter case is also covered in a separate member article.

I’ve assigned my versions of this macro to Command+Q or Control+Q on Mac or Windows, respectively.

Toggle quotes around a sentence

A macro to toggle quotes around the current sentence or all partially selected consecutive sentences as a group is:

Sub ToggleQuotesSentenceSloppy()
' Toggle double quotes around current sentence(s) as a group
' Allows for initially incomplete sentence selection

' Just use initial selection even if an insertion point
Dim r As Range
Set r = Selection.Range

' Extend range to include full sentence(s) both directions
r.StartOf Unit:=wdSentence, Extend:=wdExtend
r.EndOf Unit:=wdSentence, Extend:=wdExtend

' Toggle double quotes and select result
Set r = ToggleQuotesRange(r)
r.Select ' Finish with text selected
End Sub

I’ve assigned my versions of these macros to Option+Q in Word for Mac and Alt+Q Windows.

These two macros are very similar except for the Unit given, so it would be easy enough to create a generalized function to use. This is often a good idea, but in this case, these are the only two I need, so they're good enough. Sometimes you just need to recognize when the lawn is mowed and go inside to take a shower.

Affiliate Links

If you're interested in using Word or another tool related to the article, check out these affiliate links. I may make a small commission if you purchase when using them, but there is no increase in cost for you, and it helps to support this site and associated content.

I've been using Microsoft for Business for commercial use (that's us writers) on one of the lower pricing tiers for years. I get to use my macros, have online storage, and don't have to worry about software updates.