The Long Wiki Odyssey: From Woas to MoinMoin

Over the years I've been using a cool Wiki called Wiki on a Stick (WoAS) that was based on a self modifying XHTML / Java Script web page to store my notes that do not end up on this blog. The advantage of using a Wiki over other forms of notes taking for me is the search functionality and fast accessibility. All was well until Mozilla decided at some point with Firefox 16 or 17 that they no longer support self modifying pages. So one day after innocently upgrading Firefox, WoAS suddenly stopped working. There we go, the pleasures of updating. But I've accumulated a lot of useful notes in the Wiki so I had to find a solution. This is how the following Odyssey began:

There seems to be a workaround by using Java functionality to store changes to the WoAS file. This was out of the question for me as Java is so riddled with security issues that I decided long ago to uninstall it. Also I thought about using an old Firefox version in a virtual machine for the Wiki but decided that this is not practicable in the long run to always have a VM running for just this application. For some time I hoped a fix would be found or the functionality would be put back in Firefox, perhaps disabled by default. But to the best of my knowledge this didn't happen even to this day and I needed another solution quickly anyway.

The first solution I used was to convert the WoAS Wiki into HTML pages and from there to a Word Document. This worked rather well but left me with a 350 page word document. For some time this worked to some degree. However, only being able to search linearly compared to page searches in a Wiki with a results page for multiple hits became too limiting so I set out to find another solution.

There are a number of good Wiki platforms out there but most of them focus on providing public services to more than one person. What I wanted was a simple to install solution for personal use and no access from the outside. Then I remembered that a long time ago I experimented with MoinMoin Wiki, a file and directory based platform that is easy to configure and to back up. While it can run on an Apache web server to serve as a public Wiki it also brings its own built in web server that can be restricted to localhost, i.e. no data is accessible over the network. So I checked out MoinMoin and found that it is still maintained and developed. Great!

Obviously a 350 page word document with about 250 Wiki entries can't be copied and pasted by hand into individual Wiki pages, so a different solution was required. Fortunately, the WoAS to HTML to Word conversion (!) left the original formatting intact so each page started with the page name in a specific style and indentation. Also, font formatting (bold, italics, etc.) and code snippets were all there as well. So I decided to program a Visual Basic Macro in Word to go through the document and create a MoinMoin compatible directory structure with pages for each entry. Obviously I also wanted to preserve the formatting in  the entries as well so I had to figure out how to analyze the formatting of each paragraph in Visual Basic and convert that to MoinMoin Wiki commands. Also it turned out that MoinMoin is quite picky on the characters used for filenames and the text contained in the files. Special characters used by word for quotation marks, dashes, etc. needed to be converted to plain ASCII characters as otherwise MoinMoin would just refuse to display a page and crash during a full search operation if even only one of those characters was encountered during the search. Quite an adventure but eventually I managed to convert almost everything with a Visual Basic script to the liking of MoinMoin and only had to manually convert characters in a few pages.

I cold have put that into the program as well but converting the 350 page document took well over half an hour. The process starts quite quickly but for some reason Visual Basic slows down significantly the further it went into the document. At some point I was wondering if it would ever finish. But it did and I am glad I have a fully working personal Wiki again with all my WoAS content and everything I added in Word afterward preserved.

As I am sure I'm not the only one with this problem, I've attached the code to this post. I am not sure how many people it will help due to the many conversion steps I did between WoAS and MoinMoin. However, even for a direct conversion from the WoAS file or HTML export to MoinMoin the script should contain good information on how MoinMoin expects the directory structure to be created and how the text formatting needs to be changed. If you give it a try, good luck and have fun!

Sub convertmoinmoin()

Dim sDirectory As String
Dim bIsFileOpen As Boolean
Dim bInCourierNewBlock As Boolean

sDirectory = "C:Dokumente und EinstellungenmDesktopwiki-export"
bIsFileOpen = False
bInCourierNewBlock = False

'find first new page paragraph
For iFirst = 1 To ActiveDocument.Paragraphs.Count
  If ActiveDocument.Paragraphs(iFirst).Range.Style = "Überschrift 1" Then Exit For

For i = iFirst To ActiveDocument.Paragraphs.Count
    'select the next paragraph and then get all properties for it
    'The paragraph text is here
    sText = ActiveDocument.Paragraphs(i).Range.Text
    'Style indicates new topic – new page "Überschrift 1"
    Style = ActiveDocument.Paragraphs(i).Range.Style
    'formatting of the whole line, 99999 if several formats are used…
    Bold = ActiveDocument.Paragraphs(i).Range.Bold
    Italic = ActiveDocument.Paragraphs(i).Range.Italic
    'Font name courier new hints at program code to be treated specially
    Font = ActiveDocument.Paragraphs(i).Range.Font.Name

    '0 if not a list, other if list
    ListType = ActiveDocument.Paragraphs(i).Range.ListFormat.ListType

    'Indent is >0 if the paragraph is indented! (NOTE: also for bulleted lists!)
    Indent = ActiveDocument.Paragraphs(i).Range.ParagraphFormat.LeftIndent
    'now analyze the paragraph
    'If a new entry is found, create a new subdirectory and topic file
    If ActiveDocument.Paragraphs(i).Range.Style = "Überschrift 1" Then
        'remove trailing line feed'
        sText = Left(sText, Len(sText) – 1)
        'replace a number of characters in the filename as MoinMoin
        'does not accept them
        sText = Replace(sText, Chr(147), "x")
        sText = Replace(sText, Chr(148), "x")
        sText = Replace(sText, Chr(150), "x")
        sText = Replace(sText, "-", "x")
        sText = Replace(sText, "/", "x")
        sText = Replace(sText, ",", "x")
        'Filename must not contain blanks, replace with "(20)"
        sText = Replace(sText, " ", "(20)")
        'only create a wiki page if line is not empty
        If Len(sText) > 1 Then
            'close the previous wiki page file
            If bIsFileOpen = True Then
              'if the previous wiki page file ended with a coding section
              If bInCourierNewBlock = True Then
                 Print #1, "}}}"
                 bInCourierNewBlock = False
              End If
              Close #1
            End If
            FileSystem.MkDir (sDirectory & sText)
            FileSystem.MkDir (sDirectory & sText & "revisions")
            Open sDirectory & sText & "current" For Output As #1
            Print #1, "00000001"
            Close #1
            Open sDirectory & sText & "revisions0000001" For Output As #1
            bIsFileOpen = True
        End If
    Else 'the paragraph belongs to the current file
       'remove trailing line feed'
       sText = Left(sText, Len(sText) – 1)
       'Word uses special quotation marks, replace them with the ASCII character
       sText = Replace(sText, Chr(147), """")
       sText = Replace(sText, Chr(148), """")
       'Word uses special – sign, convert to ASCII character
       sText = Replace(sText, Chr(150), "-")

       'Treat blocks in Courier New first (program code, no formatting to be applied)
       If ActiveDocument.Paragraphs(i).Range.Font.Name <> "Courier New" Then
          If bInCourierNewBlock = True Then
             Print #1, "}}}"
             bInCourierNewBlock = False
          End If
       End If
       If ActiveDocument.Paragraphs(i).Range.Font.Name = "Courier New" Then
          If bInCourierNewBlock = False Then
             Print #1, "{{{"
             Print #1, sText
             bInCourierNewBlock = True
             Print #1, sText
          End If
       '…And now the rest of the formatting
       ElseIf ListType > 0 Then
          'paragraph is a bulleted list
          Print #1, " * " & sText
       ElseIf Bold = True Then
          Print #1, "'''" & sText & "'''"
       ElseIf Indent > 0 Then
          'if indent and italic
          If Italic = True Then
             Print #1, " . ''" & sText & "''"
             Print #1, " . " & sText
          End If
       Else 'just put the paragraph in the wiki file as it is
          Print #1, sText
       End If
    End If 'paragraph belongs to current file

If bIsFileOpen = True Then Close #1

End Sub

3 thoughts on “The Long Wiki Odyssey: From Woas to MoinMoin”

  1. Drat. You have me thinking about the wiki that I use (TiddlyWiki) and the inevitable time that I will have to move on from its Java-based save component. What you’ve done is going to require me to reread this a few times, but I think I get what you have had to do.

    Thankfully, the next wiki platform that I use will take more advantage of HTML5 for main use, and OPML for archiving, so that I don’t run into something like this as harshly.

  2. Martin,

    What is it that you store there for your blog and what kind of searches do you make on it?

    I tend to use the calendar scheduling plugin for WordPress and then a bit of Evernote (and Google Reader search…)

Comments are closed.