So you’d think there’d be a million Rich Text solutions for editing Wiki markup, right? Hmm… Not so lucky. Google was not my friend.

But if you’re aware of textile-j cool library for rendering textile markup… and your pretty motivated (say, cause the project your working on needs one for client facing wiki content editing), you can probably leverage of the totally sensational YUI Rich Editor along with some funky Grails backend Ajax tom-foolery to come up with a screencast to show off… (1.1mb - sorry for the dodgy sound, next time I’ll use my real mic)

wiki editor in action

I’ve been using the using the uber cool Grails YUI Plugin to handle the imports of all the necessary YUI files, and getting myself lost in a fairly foreign world of Javascript.

Turns out the recipe for making all this work is pretty straighforward:

  • When switching from Wiki markup to HTML, do an Ajax call to a backend Grails controller that uses [textile-j](https://textile-j.dev.java.net/) to convert from textile markup to html. Feed the result of the AJAX call to the YUI Rich Editor and you're in business.
  • To support switching from RichText to Textile, again do an Ajax call back to the Grails controller to the do the conversion. This time you're on your own in regexp land, but you can trim the amount of work you've got to do by what you expose in the Rich editor. Return the results and inject into the Wiki textarea.
  • To get the underlying html from the editor just use `myEditor.getEditorHTML()`. Awesome!
    • And how does textile-j do it’s thing? Well my MarkupService is pretty tight (a service is probably overkill, I could probably wrap this up in a Grails encoder):

      def textileToHtml = { textile ->
      
              StringWriter sw = new StringWriter();
      
              HtmlDocumentBuilder builder = new HtmlDocumentBuilder(sw)
              builder.emitAsDocument = false
              MarkupParser parser = new MarkupParser(new ConfluenceDialect())
              parser.setBuilder(builder)
      
              parser.parse(textile)
              return sw.toString()
      
          }
      

      Very tidy. Going back the other way requires a little bit of Regexp Ninja antics… but given that the basic markup I’m supporting is lists, headings, bold, italics, images and links, the search scope is narrowed down significantly from “anything goes” html.

      It’s not a perfect solution. Regular expressions are really terrible for this sort of thing since the nested cases get impossible to express. A real grammar is the only way to handle it properly. But for the 90% case (and until I read the Antlr book sitting on my shelf), the above should get me home for v1. Whilst this work if for another project, you can bet the source will end up in Gravl for editing once the feature set is done..

      YUI is just awesome… (and props to Marcel for packaging it up in a sweet Grails plugin)…