setup
to meet the formatting requirements of a journal, i need to make sure certain math symbols (=, >, ≥, <, ≤) are preceded and followed by a space. e.g. 2 > 1 instead of 2>1. i'd like to get that done by one click of a button.
solution
the plan
- write a macro for MS Word.
- search & locate, say, "≥".
- if there's a preceding space, move the selection start to immediately after the nearest non-space character.
- if there's a trailing space, move the selection end to immediately before the nearest non-space character.
- replace the text of the selected part with " ≥ ".
- iterate over the symbols to be re-formatted.
- assign a macro to a button to the Word toolbar. see how in here: https://support.microsoft.com/en-us/office/assign-a-macro-to-a-button-728c83ec-61d0-40bd-b6ba-927f84eb5d2c
programming language & module(s)
- VBA
file preps
make the doc to be processed the active document, i.e. the one where the cursor currently is in.
variables to customize
symbols
. no separator's needed since the symbols are just single characters, e.g."=>≥<≤±×"
.
the script
addSpacesBeforeAfter
Sub addSpacesBeforeAfter() | |
Dim doc As Document | |
Dim trkRevStatus As Boolean | |
Dim selStart, selEnd, safeCount As Long | |
Dim lan As String | |
Dim ret, matches As Object | |
Application.ScreenUpdating = False | |
System.Cursor = wdCursorWait | |
Set doc = ActiveDocument | |
trkRevStatus = doc.TrackRevisions | |
doc.TrackRevisions = False | |
selStart = Selection.Start | |
selEnd = Selection.End | |
clearFind | |
symbols = "=>≥<≤±×" | |
Set ret = CreateObject("VBScript.RegExp") | |
With ret | |
.pattern = "." | |
.Global = True | |
End With | |
Set matches = ret.Execute(symbols) | |
With Selection | |
For i = 0 To matches.Count - 1 | |
.HomeKey wdStory | |
symbol = matches(i) | |
With .Find | |
.Text = symbol | |
.Wrap = wdFindStop | |
End With | |
Do While .Find.Execute And safeCount < 10000 | |
safeCount = safeCount + 1 | |
If doc.Range(.Start - 1, .Start).Text = " " Then | |
.MoveStartWhile " ", wdBackward | |
End If | |
startIdx = .Start | |
If doc.Range(.End, .End + 1).Text = " " Then | |
.Collapse wdCollapseEnd | |
.MoveRight unit:=wdWord, Count:=1, Extend:=wdExtend | |
End If | |
endIdx = .End | |
doc.Range(startIdx, endIdx).Select | |
.Text = " " & symbol & " " | |
.Collapse wdCollapseEnd | |
Loop | |
Next i | |
.HomeKey wdStory | |
With .Find | |
.Text = "( " | |
.Replacement.Text = "(" | |
.Execute Replace:=wdReplaceAll | |
.Text = " )" | |
.Replacement.Text = ")" | |
.Execute Replace:=wdReplaceAll | |
End With | |
End With | |
clearFind | |
doc.Range(selStart, selEnd).Select | |
doc.TrackRevisions = trkRevStatus | |
System.Cursor = wdCursorNormal | |
Application.ScreenUpdating = True | |
End Sub | |
Sub clearFind() | |
With Selection.Find | |
.Text = "" | |
.Replacement.Text = "" | |
.Forward = True | |
.Wrap = wdFindContinue | |
.Format = False | |
.MatchCase = False | |
.MatchWholeWord = False | |
.MatchByte = True | |
.MatchWildcards = False | |
.MatchSoundsLike = False | |
.MatchAllWordForms = False | |
End With | |
End Sub |
output
the doc will resume the desired format on the specified symbols, e.g.
note to self
- use the
wdBackward
argument when using.MoveStartWhile
, or the start will go forward.