Sub HyphenAlyse() ' Paul Beverley - Version 07.12.24 ' Creates a frequency list of all possible hyphenations myList = "anti,cross,eigen,hyper,inter,meta,mid,multi," _ & "non,over,post,pre,pseudo,quasi,semi,sub,super,un" myList = "anti,cross,eigen,hyper,inter,meta,mid,multi," _ & "non,over,post,pre,pseudo,quasi,semi,sub,super,un" includeNumbers = True tableBorders = True lighterColour = wdGray25 ' lighterColour = wdColor50 Dim myResult As String myList = "," & myList myList = Replace(myList, ",,", ",") pref = Split(myList, ",") Set FUT = ActiveDocument doingSeveralMacros = (InStr(FUT.Name, "zzTestFile") > 0) sp = ChrW(160) sp = sp & sp & sp sp = sp & sp & sp sp = sp & sp & sp If doingSeveralMacros = False Then myResponse = MsgBox(" HyphenAlyse" & vbCr & vbCr & _ "Analyse hyphenated words?", vbQuestion _ + vbYesNoCancel, "HyphenAlyse") If myResponse <> vbYes Then Exit Sub End If Dim pr(8000) As String strttime = Timer Set rng = ActiveDocument.Content Documents.Add Set myDoc = ActiveDocument Selection.FormattedText = rng.FormattedText Selection.EndKey Unit:=wdStory Application.ScreenUpdating = False On Error GoTo ReportIt If myDoc.Endnotes.Count > 0 Then Selection.FormattedText = _ myDoc.StoryRanges(wdEndnotesStory).FormattedText If myDoc.Footnotes.Count > 0 Then Selection.FormattedText = _ myDoc.StoryRanges(wdFootnotesStory).FormattedText Set rng = ActiveDocument.Content With rng.Find .ClearFormatting .Replacement.ClearFormatting .Text = "" .Font.StrikeThrough = True .Wrap = wdFindContinue .Replacement.Text = "" .MatchWildcards = True .Execute Replace:=wdReplaceAll DoEvents End With allTheText = myDoc.Content.Text myDoc.Content.Text = LCase(allTheText) Set rng = ActiveDocument.Content With rng.Find .ClearFormatting .Replacement.ClearFormatting .Text = ChrW(8217) & "[!a-z]" .Wrap = wdFindContinue .Replacement.Text = "!!" .MatchWildcards = True .Execute Replace:=wdReplaceAll DoEvents End With If includeNumbers = True Then schStr = "[a-z0-9]{1,}[-^=][0-9a-z-]{1,}" Else schStr = "[a-z]{1,}[-^=][a-z-]{1,}" End If Set rng = ActiveDocument.Content With rng.Find .ClearFormatting .Replacement.ClearFormatting .Text = schStr .Wrap = wdFindStop .Replacement.Text = "" .Forward = True .MatchWildcards = True .Execute End With ' Find all hyphenated/dashed word pairs myPairs = 0 allWords = "," Do While rng.Find.Found = True wdPair = Replace(rng.Text, ChrW(8211), "-") If InStr(allWords, "," & wdPair & ",") = 0 _ And (UCase(wdPair) <> wdPair) Then myPairs = myPairs + 1 pr(myPairs) = wdPair allWords = allWords & wdPair & "," If myPairs Mod 20 = 0 Then If doingSeveralMacros = False Then _ Debug.Print rng.Text & " " & myPairs StatusBar = sp & rng.Text & " " & myPairs End If End If If Right(wdPair, 1) <> "s" Then wdPairs = wdPair & "s" If InStr(allWords, "," & wdPairs & ",") = 0 Then myPairs = myPairs + 1 pr(myPairs) = wdPairs allWords = allWords & wdPairs & "," If myPairs Mod 20 = 0 Then If doingSeveralMacros = False Then _ Debug.Print rng.Text, myPairs StatusBar = sp & rng.Text & " " & myPairs DoEvents End If End If End If rng.Find.Execute Loop ' Collect words with each prefix For i = 1 To UBound(pref) hPos = Len(pref(i)) allPreWords = "," If includeNumbers = True Then schStr = "<" & pref(i) & "[0-9a-z]{2,}" Else schStr = "<" & pref(i) & "[a-z]{2,}" End If Set rng = ActiveDocument.Content With rng.Find .ClearFormatting .Replacement.ClearFormatting .Text = schStr .Wrap = wdFindStop .Replacement.Text = "" .Forward = True .MatchWildcards = True .Execute End With Do While rng.Find.Found = True wd = rng.Text If InStr(wd, "-") = 0 Then wd = Left(wd, hPos) _ & "-" & Mid(wd, hPos + 1) If InStr(allPreWords, "," & wd & ",") = 0 And _ InStr(allWords, "," & wd & ",") = 0 Then myPairs = myPairs + 1 pr(myPairs) = wd allPreWords = allPreWords & wd & "," allWords = allWords & wd & "," If myPairs Mod 20 = 0 Then If doingSeveralMacros = False Then _ Debug.Print wd & " " & myPairs StatusBar = sp & wd & " " & myPairs DoEvents End If End If rng.Collapse wdCollapseEnd rng.Find.Execute Loop Next i ' Collect word pairs with each prefix, e.g. "mid height" For i = 1 To UBound(pref) hPos = Len(pref(i)) If includeNumbers = True Then schStr = "<" & pref(i) & " [0-9a-z]{2,}" Else schStr = "<" & pref(i) & " [a-z]{2,}" End If Set rng = ActiveDocument.Content With rng.Find .ClearFormatting .Replacement.ClearFormatting .Text = "<" & pref(i) & " [0-9a-z]{2,}" .Wrap = wdFindStop .Replacement.Text = "" .Forward = True .MatchWildcards = True .Execute End With Do While rng.Find.Found = True wd = rng.Text If InStr(wd, " ") = 0 Then wd = Left(wd, hPos) _ & " " & Mid(wd, hPos + 1) wd = Replace(wd, " ", "-") If InStr(allPreWords, "," & wd & ",") = 0 And _ InStr(allWords, "," & wd & ",") = 0 Then myPairs = myPairs + 1 pr(myPairs) = wd allPreWords = allPreWords & wd & "," If myPairs Mod 20 = 0 Then If doingSeveralMacros = False Then _ Debug.Print wd & " " & myPairs StatusBar = sp & wd & " " & myPairs DoEvents End If End If rng.Collapse wdCollapseEnd rng.Find.Execute Loop Next i halfTime = Timer ' Count the frequencies Selection.HomeKey Unit:=wdStory Selection.TypeText vbCr & vbCr Selection.HomeKey Unit:=wdStory ActiveDocument.Paragraphs(1).Style = _ ActiveDocument.Styles(wdStyleHeading1) allText = " " & ActiveDocument.Range.Text & " " ' At this point, change all "^p" to "^p " ' all punctuation to " " chs = " , . ! : ; [ ] { } ( ) / \ + " chs = chs & ChrW(8220) & " " chs = chs & ChrW(8221) & " " chs = chs & ChrW(8201) & " " chs = chs & ChrW(8222) & " " chs = chs & ChrW(8217) & " " chs = chs & ChrW(8216) & " " chs = chs & ChrW(8212) & " " chs = chs & ChrW(8722) & " " chs = chs & vbCr & " " chs = chs & vbTab & " " ' To force space at start; no space at end ' i.e. one space for each character that ' needs changing to a space chs = " " & chs & " " chs = Replace(chs, " ", " ") chs = Replace(chs, " ", " ") chs = Left(chs, Len(chs) - 1) chars = Split(chs, " ") For i = 1 To UBound(chars) allText = Replace(allText, chars(i), " ") Next i allText = Replace(allText, " ", " ") cnt = Len(allText) For i = 1 To myPairs totFinds = 0 thisFind = "" Set rng = ActiveDocument.Content myTot = rng.End wdHyph = pr(i) wd = Replace(wdHyph, "-", "") For j = 1 To 4 Select Case j Case 1: schWd = wdHyph Case 2: schWd = Replace(wdHyph, "-", " ") Case 3: schWd = wd Case 4: schWd = Replace(wdHyph, "-", ChrW(8211)) End Select sc = " " & schWd & " " myCount = Len(Replace(allText, sc, sc & "!")) - cnt If myCount > 0 Then totFinds = totFinds + 1 Selection.HomeKey Unit:=wdStory thisFind = thisFind & schWd & " . ." & _ Str(myCount) & ":" Else thisFind = thisFind & ":" End If DoEvents Next j If (myPairs - i) Mod 20 = 0 Then If doingSeveralMacros = False Then _ Debug.Print "To go: ", myPairs - i StatusBar = sp & "To go: " & myPairs - i End If If Len(thisFind) > 8 Then myResult = myResult & "%" & _ wd & "%" & thisFind & "!" Next i myResult = Replace(myResult, ":!", vbCr) myResult = Replace(myResult, ":", vbTab) Selection.WholeStory Selection.Delete Set rng = ActiveDocument.Content rng.InsertAfter myResult Set rng = ActiveDocument.Content rng.Sort SortOrder:=wdSortOrderAscending Selection.HomeKey Unit:=wdStory With rng.Find .ClearFormatting .Replacement.ClearFormatting .Text = "%[a-z0-9]@%" .Wrap = wdFindContinue .Replacement.Text = "" .Forward = True .MatchCase = False .MatchWildcards = True .Execute Replace:=wdReplaceAll End With Selection.HomeKey Unit:=wdStory Selection.TypeText "Hyphenation use" startTable = Selection.End + 1 ActiveDocument.Paragraphs(1).Style = _ ActiveDocument.Styles(wdStyleHeading1) Selection.start = startTable Selection.End = ActiveDocument.Range.End Selection.ConvertToTable Separator:=wdSeparateByTabs Set TB = ActiveDocument.Tables(1) If tableBorders = True Then TB.Style = "Table Grid" ' TB.AutoFitBehavior (wdAutoFitContent) For i = 1 To TB.Rows.Count q = q + 1 If q Mod 20 = 0 Then Debug.Print "Formatting results: " & q StatusBar = sp & "Formatting results: " & q DoEvents End If q = 0 num = 0 For j = 1 To 4 If Len(TB.Cell(i, j).Range.Text) > 2 Then num = num + 1 Next j If num = 1 Then For j = 1 To 4 TB.Cell(i, j).Range.Font.ColorIndex = lighterColour Next j End If Next i Set TB = ActiveDocument.Tables(1) For i = 1 To TB.Rows.Count q = q + 1 If q Mod 20 = 0 Then Debug.Print "Formatting results: " & q StatusBar = sp & "Formatting results: " & q DoEvents End If q = 0 For j = 1 To 4 hyphPos = 0 Txt = TB.Cell(i, j).Range.Text hyphPos = InStr(Txt, "-") dashPos = InStr(Txt, ChrW(8211)) tstText = Txt If hyphPos + dashPos > 0 Then tstText = "," & Left(Txt, hyphPos + dashPos _ - 1) & "," If InStr(myList, tstText) > 0 Then TB.Cell(i, j).Range.Font.ColorIndex = wdBlue End If Else For k = 1 To UBound(pref) If InStr("," & Txt, "," & pref(k)) > 0 Then TB.Cell(i, j).Range.Font.ColorIndex = wdBlue End If Next k End If Next j Next i For i = 1 To TB.Rows.Count q = q + 1 If q Mod 20 = 0 Then Debug.Print "Formatting results: " & q StatusBar = sp & "Formatting results: " & q DoEvents End If q = 0 s = 0 If Len(TB.Cell(i, 1).Range.Text) > 2 Then s = s + 1 If Len(TB.Cell(i, 3).Range.Text) > 2 Then s = s + 1 If Len(TB.Cell(i, 4).Range.Text) > 2 Then s = s + 1 If Len(TB.Cell(i, 2).Range.Text) > 2 And _ Len(TB.Cell(i, 4).Range.Text) > 2 Then s = 2 If s > 1 Then For j = 1 To 4 TB.Cell(i, j).Range.Font.ColorIndex = wdRed Next j End If If InStr(TB.Cell(i, 1).Range.Text, "ly-") > 0 And _ Len(TB.Cell(i, 2).Range.Text) > 2 Then For j = 1 To 4 TB.Cell(i, j).Range.Font.ColorIndex = wdRed Next j End If Next i StatusBar = sp & "Formatting results" allText = ActiveDocument.Content For Each myCell In TB.Range.Cells q = q + 1 If q Mod 20 = 0 Then Debug.Print "Formatting results: " & q StatusBar = sp & "Formatting results: " & q DoEvents End If myText = myCell.Range.Text Set rng = myCell.Range.Duplicate rng.End = rng.start + 1 myColour = rng.Font.ColorIndex i = InStr(myText, " . .") If myColour = lighterColour And i > 2 Then myWord = Left(myText, i - 1) If Right(myWord, 1) = "s" Then mySingular = Left(myText, i - 2) If InStr(allText, mySingular & " . .") > 0 Then _ myCell.Range.Font.color = wdColorAutomatic myTest = Replace(mySingular, "-", "") If InStr(allText, mySingular & " . .") > 0 Then _ myCell.Range.Font.color = wdColorAutomatic myTest = Replace(mySingular, "-", " ") If InStr(allText, myTest & " . .") > 0 Then _ myCell.Range.Font.color = wdColorAutomatic End If If InStr(allText, myWord & "s . .") > 0 Then _ myCell.Range.Font.color = wdColorAutomatic myTest = Replace(myWord, "-", "") If InStr(allText, myTest & "s . .") > 0 Then _ myCell.Range.Font.color = wdColorAutomatic myTest = Replace(myText, "-", " ") If InStr(allText, myWord & "s . .") > 0 Then _ myCell.Range.Font.color = wdColorAutomatic End If Next myCell Selection.HomeKey Unit:=wdStory timNow = Timer Application.ScreenUpdating = True If doingSeveralMacros = False Then timGone = timNow - strttime Beep myTime = Timer Do Loop Until Timer > myTime + 0.2 Beep m = Int(timGone / 60) s = Int(timGone) - m * 60 timeAll = "Time: " & Trim(Str(m)) & " m " & _ Trim(Str(s)) & " s" Selection.HomeKey Unit:=wdStory numPairs = ActiveDocument.Tables(1).Rows.Count MsgBox "Items: " & Trim(Str(numPairs)) & vbCr & vbCr _ & timeAll Else FUT.Activate End If Exit Sub ReportIt: Application.ScreenUpdating = True On Error GoTo 0 Resume End Sub