Wiki called WikiDoc: http://sourceforge.net/projects/wikidoc/ The following Microsoft Word 97 macros make a single word document into a mini wiki database. Sort of "wiki for one". WHAT?! If you hook the subroutime Wiki''''''Doc up to Alt-W (or whatever), whenever you press Alt-W, all wiki names (called "page names" in the code) at the beginning of pages become bookmarks (hyperlink targets) of style "heading 2". All page names not at the beginning of pages become underlined hyperlinks. If you hook the subroutine Wiki''''''Un''''''Page up to Alt-U (or whatever), you can press Alt-U to remove all the page breaks. This is useful if you want to print the document. The rule used for page names is: start with uppercase and contain at least two uppercase and one lowercase. [To copy these macros without the ?'s, click on Edit Text, then select text from the edit text box]. -- StanSilver What a WikiDoc looks like: ---------- Topic''''''One Blah blah blah Topic''''''Two ---------- Topic''''''Two Blah blah Topic''''''Three ---------- Topic''''''Three Blah blah Topic''''''One and Topic''''''Two blah blah Topic''''''Four ---------- Sub Wiki''''''Doc() '=================================' ' Delete bookmarks and hyperlinks ' '=================================' For i = Active''''''Document.Bookmarks.Count To 1 Step -1 Active''''''Document.Bookmarks(i).Delete Next i For i = Active''''''Document.Hyperlinks.Count To 1 Step -1 Active''''''Document.Hyperlinks(i).Delete Next i '====================================' ' Set target page names as bookmarks ' '====================================' Dim myRange As Range For Each myRange In Active''''''Document.Words If Wiki''''''Is''''''Page''''''Name(myRange) Then If Wiki''''''Is''''''Target(myRange) Then '=======' ' Taget ' '=======' myName = Trim(myRange.Text) With Active''''''Document.Bookmarks .Add Range:=myRange, Name:=myName .Default''''''Sorting = wdSortByName .Show''''''Hidden = False End With myRange.Style = wdStyle''''''Heading2 End If End If Next '=================================================' ' Set link page names with targets as hyperlinks ' ' Underline link page names without targets ' '=================================================' For Each myRange In Active''''''Document.Words If Wiki''''''Is''''''Page''''''Name(myRange) Then If Not Wiki''''''Is''''''Target(myRange) Then '======' ' Link ' '======' myRange.Bold = False myRange.Underline = False myName = Trim(myRange.Text) If Active''''''Document.Bookmarks.Exists(myName) = True Then Active''''''Document.Hyperlinks.Add Anchor:=myRange, Address:="", Sub''''''Address:=myName Else myRange.Underline = True myRange.Font.Color''''''Index = wdRed End If End If End If Next Active''''''Document.Save Msg''''''Box ("Done") End Sub Function Wiki''''''Is''''''Page''''''Name(myRange As Range) As Boolean '==============================================================' ' Page name must start with an uppercase, and contain at least ' ' two uppercase and one lowercase characters ' '==============================================================' Wiki''''''Is''''''Page''''''Name = False If (myRange.Characters(1) > "Z") Then Exit Function myUpperCaseCount = 0 myLowerCaseCount = 0 For Each myCharRange In myRange.Characters If ((myCharRange <= "Z") And (myCharRange >= "A")) Then myUpperCaseCount = myUpperCaseCount + 1 End If If ((myCharRange <= "z") And (myCharRange >= "a")) Then myLowerCaseCount = myLowerCaseCount + 1 End If Next If ((myUpperCaseCount > 1) And (myLowerCaseCount > 0)) Then Wiki''''''Is''''''Page''''''Name = True End If End Function Function Wiki''''''Is''''''Target(myRange As Range) As Boolean '============================================' ' Assume myRange is a page name. Target must ' ' appear directly after a new page character ' '============================================' Wiki''''''Is''''''Target = False myStart = myRange.Start - 1 myEnd = myRange.Start Set myPreviousRange = Active''''''Document.Range(Start:=myStart, End:=myEnd) myPreviousChar = myPreviousRange.Characters(1).Text If Asc(myPreviousChar) = 12 Then Wiki''''''Is''''''Target = True End Function Sub Wiki''''''Un''''''Page() '===============================' ' Remove all manual page breaks ' '===============================' Selection.Home''''''Key Unit:=wdStory Selection.Find.Clear''''''Formatting Selection.Find.Replacement.Clear''''''Formatting With Selection.Find .Text = "^m" .Replacement.Text = "" .Forward = True .Wrap = wdFindContinue .Format = False .Match''''''Case = False .Match''''''Whole''''''Word = False .Match''''''Wildcards = False .Match''''''Sounds''''''Like = False .Match''''''All''''''Word''''''Forms = False End With Selection.Find.Execute Replace:=wdReplaceAll End Sub ---- Suggestion for Speedup: I removed the lowercase part: If ((myCharRange <= "z") And (myCharRange >= "a")) Then myLowerCaseCount = myLowerCaseCount + 1 End If and replaced the Wiki''''''Page''''''Name criterion: If ((myUpperCaseCount > 1) And (myLowerCaseCount > 0)) Then Wiki''''''Is''''''Page''''''Name = True End If By: If (myUpperCaseCount > 1) Then Wiki''''''Is''''''Page''''''Name = True End If The MicrosoftWord interpreter thanks it with greater speed and we have more flexible Wiki''''''Page''''''Names. See http://www.data-music.com for useful samples. -- FridemarPache ---- I found the above code to take greater than 15 seconds to execute even for a small document. The following code is much faster by allowing links to be created on demand, instead of processing the entire document each time. If the macro Wiki''''''Create''''''Link is executed (I have a key bound to this) after typing a Wiki Word, then a link is created to the bookmark with the same name as the Wiki Word. If that bookmark doesn't exist, then the WikiWord is made into a Macro Button field. When this macro button field is double clicked, a page break, along with a page title and a new bookmark is inserted at the end of the current page. I like to set the value of the ''Field Shading'' dropdown in the Tools->Options->View Tab to Always so the links to the nonexisting pages stand out. The following code also requires the Wiki''''''Is''''''Page''''''Name macro from the above code. -- BrianTheado Sub Wiki''''''Create''''''Link() ' ' Create a Wiki link out of the nearest word to the left ' Selection.Move''''''Left Unit:=wdWord, Count:=1, Extend:=wdExtend If Wiki''''''Is''''''Page''''''Name(Selection.Words.First) Then myName = Trim(Selection.Words.First) If Active''''''Document.Bookmarks.Exists(myName) = True Then ' Page already exists - add a hyperlink Active''''''Document.Hyperlinks.Add Anchor:=Selection.Words.First, Address:="", Sub''''''Address:=myName Else ' ' Page doesn't exist turn the word into a macrobutton ' field that will create a new page when double clicked ' Selection.Words.First.underline = True Selection.Words.First.Font.Color''''''Index = wdRed Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldMacroButton, Text:= _ "Wiki''''''Add''''''New''''''Page " + myName, Preserve''''''Formatting:=False End If End If End Sub Sub Wiki''''''Add''''''New''''''Page() ' Remove the macrobutton field Selection.Fields.Unlink ' Hyperlink the word to the about to be created page Selection.Move''''''Left Unit:=wdWord, Count:=1, Extend:=wdExtend myName = Selection.Words.First.Text Active''''''Document.Hyperlinks.Add Anchor:=Selection.Words.First, Address:="", Sub''''''Address:=myName If Active''''''Document.Bookmarks.Exists(myName) = False Then ' Move to just beyond the next page break and create the new page Find''''''Page''''''Break Selection.Move''''''Right Wiki''''''Create''''''Page (myName) End If End Sub Sub Wiki''''''Create''''''Page(myName As String) Selection.Type''''''Text Text:=myName Selection.Style = wdStyleHeading1 Active''''''Document.Bookmarks.Add Range:=Selection.Words.First, Name:=myName Selection.Type''''''Paragraph Selection.Insert''''''Break Type:=wdPageBreak Selection.Move''''''Up End Sub Sub Find''''''Page''''''Break() Selection.Find.Clear''''''Formatting With Selection.Find .Text = "^m" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .Match''''''Case = False .Match''''''Whole''''''Word = False .Match''''''Wildcards = False .Match''''''Sounds''''''Like = False .Match''''''All''''''Word''''''Forms = False End With Selection.Find.Execute End Sub ---- on my Word97 SR2 installation, I had to add one line of code: Sub WikiCreateP''''''age(myName As String) myName = RTrim(myName) ... -- TimmDanker This quick linking feature is very helpful. I adapted the WikiDoc routine to also insert macro button fields for unknown Wiki Words, but describing this as changes to the code above would become unreadable, so if anyone is interested, please send me an email. -- RalfHandl ''Alas, I wasn't able to get any of these macros to work on my Word97 setup. Ralf, where is your email address? -- MichaelBrown ---- Function Wiki''''''Is''''''Page''''''Name(myRange As Range) As Boolean Wiki''''''Is''''''Page''''''Name = (myRange.Case = wdToggleCase) End Function ... seems to do what we want (and quickly). Now one can inline the function. -- FalkBruegmann Well, at least on my machine (WinNT, Office97) this is much slower than the original function. -- RalfHandl ---- Does this work with OfficeXP, too? I tried and it didn't work. Any improvement suggestions? -- PeterHenning ---- So, here's my preliminary version based on BrianTheado's. Name restrictions are only given by Word. Why use WikiNames if the Wiki doesn't automatically detect them? I tried to install a routine that converts illegal WikiWord''''''s into legal ones (in my sense). Unfortunately, I never used VBA with Word before... -- GüntherLehnert ' Word''''''Wiki ' Tested with Office XP Sub WikiLink() ' Hyperlink the word to the about to be created page Selection.Move''''''Left Unit:=wdWord, Count:=1, Extend:=wdExtend myName = Selection.Words.First.Text ' Begin Word with a letter Do While Number''''''Range(Asc(Left(myName, 1))) < 2 myName = Right(myName, Len(myName) - 1) Loop ' End with the last allowed character Do While Number''''''Range(Asc(Right(myName, 1))) < 1 myName = Left(myName, Len(myName) - 1) Loop ' Delete characters not allowed in Links i = 1 Do While i < Len(myName) If Number''''''Range(Asc(Mid(myName, i, 1))) = 0 Then myName = Left(myName, i - 1) & Right(myName, Len(myName) - i) Else i = i + 1 End If Loop Active''''''Document.Hyperlinks.Add Anchor:=Selection.Words.First, Address:="", Sub''''''Address:=myName If Active''''''Document.Bookmarks.Exists(myName) = False Then ' Move to just beyond the next page break and create the new page FindPageB''''''reak Selection.Move''''''Right WikiCreateP''''''age (myName) End If End Sub ' Checks for allowed characters ' How could you do this easier? Function Number''''''Range(Number As Byte) As Integer Number''''''Range = 0 If Number > 47 And Number < 58 Then Number''''''Range = 1 If Number > 64 And Number < 91 Then Number''''''Range = 2 If Number > 96 And Number < 123 Then Number''''''Range = 2 If Number > 191 And Number < 215 Then Number''''''Range = 2 If Number > 215 And Number < 247 Then Number''''''Range = 2 If Number > 248 And Number < 256 Then Number''''''Range = 2 If Number = 95 Then Number''''''Range = 1 End Function Sub WikiCreateP''''''age(myName As String) Selection.Type''''''Text Text:=myName Selection.Style = wdStyleHeading1 Active''''''Document.Bookmarks.Add Range:=Selection.Words.First, Name:=myName Selection.Type''''''Paragraph Selection.Insert''''''Break Type:=wdPageBreak Selection.Move''''''Up End Sub Sub FindPageB''''''reak(Optional joke As Boolean) '<- so it is not displayed as a separate macro Selection.Find.Clear''''''Formatting With Selection.Find .Text = "^m" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .Match''''''Case = False .MatchWholeW''''''ord = False .Match''''''Wildcards = False .MatchSoundsL''''''ike = False .MatchAllWordF''''''orms = False End With Selection.Find.Execute End Sub ---- Please see my site at http://www.SuperThinking.com. I have a Word Addin there. Could use some de-klugeing, but addresses many of the aspirations of some of these macros. --RichVanSchaik This link/domain is gone/expired. -- John Godin ----