Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm looking for a tool or script to convert Markdown files to Dokuwiki format, that will run on a PC.

This is so that I can use MarkdownPad on a PC to create initial drafts of documents, and then convert them to Dokuwiki format, to upload to a Dokuwiki installation that I have no control over. (This means that the Markdown plugin is no use to me.)

I could spend time writing a Python script to do the conversion myself, but I'd like to avoid spending time on this, if such a thing exists already.

The Markdown tags I'd like to have supported/converted are:

  • Heading levels 1 - 5
  • Bold, italic, underline, fixed width font
  • Numbered and unnumbered lists
  • Hyperlinks
  • Horizontal rules

Does such a tool exist, or is there a good starting point available?


Things I've found and considered

share|improve this question
    
Add filter to pandoc for DW output?! And, btw, for requested small subset you can try to start with pure Markdown in DW (did your read DW syntax rules?!) –  Lazy Badger Mar 19 '12 at 1:42
    
@LazyBadger Thanks. I just read johnmacfarlane.net/pandoc/scripting.html, and as far as I can see, it is about changing the Pandoc AST. I want to keep the AST unchanged, but change the output format. Or have I misunderstood? –  Clare Macrae Mar 19 '12 at 6:53
    
@LazyBadger Re your second suggestion, yes, I (believe I) know DW syntax very well! However, even if DW supported Markdown, I wish to convert the text to conventional DW syntax, for the sake of my colleagues who may edit it. –  Clare Macrae Mar 19 '12 at 6:57
    
I've just discovered there is a very brief Pandoc Issue requesting DokuWiki support. –  Clare Macrae Mar 19 '12 at 7:21
    
When I speak about pandoc integration, I have in mind "add additional writer", which, AFAICS, doesn't change core as MoinMoin reader shows - it's just additional Haskell script –  Lazy Badger Mar 19 '12 at 7:26
show 1 more comment

2 Answers

up vote 5 down vote accepted

Having originally said I didn't want to write a Python script to do the conversion, I ended up doing just that.

The real time-saving step was to use Pandoc to parse the Markdown text, and write out a JSON representation of the document. This JSON file was then mostly fairly easy to parse, and write out in DokuWiki format.

Below is the script, which implements the bits of Markdown and DokuWiki that I cared about - and a few more. (I've not uploaded the corresponding testuite that I wrote)

Requirements to use it:

  • Python (I was using 2.7 on Windows)
  • Pandoc insatlled, and pandoc.exe in your PATH (or edit the script to put in the full path to Pandoc instead)

I hope this saves someone else some time too...

Edit 2: 2013-06-26: I've now put this code into github, at https://github.com/claremacrae/markdown_to_dokuwiki.py. Note that the code there adds support for more formats, and also contains testsuite.

Edit 1: adjusted to add code for parsing code samples in Markdown's backtick style:

# -*- coding: latin-1 -*-

import sys
import os
import json

__doc__ = """This script will read a text file in Markdown format,
and convert it to DokuWiki format.

The basic approach is to run pandoc to convert the markdown to JSON,
and then to parse the JSON output, and convert it to dokuwiki, which
is written to standard output

Requirements:
 - pandoc is in the user's PATH
"""

# TODOs
# underlined, fixed-width
# Code quotes

list_depth = 0
list_depth_increment = 2

def process_list( list_marker, value ):
    global list_depth
    list_depth += list_depth_increment
    result = ""
    for item in value:
        result += '\n' + list_depth * unicode( ' ' ) + list_marker + process_container( item )
    list_depth -= list_depth_increment
    if list_depth == 0:
        result += '\n'
    return result

def process_container( container ):
    if isinstance( container, dict ):
        assert( len(container) == 1 )
        key = container.keys()[ 0 ]
        value = container.values()[ 0 ]
        if key == 'Para':
            return process_container( value ) + '\n\n'
        if key == 'Str':
            return value
        elif key == 'Header':
            level = value[0]
            marker = ( 7 - level ) * unicode( '=' )
            return marker + unicode(' ') + process_container( value[1] ) + unicode(' ') + marker + unicode('\n\n')
        elif key == 'Strong':
            return unicode('**') + process_container( value ) + unicode('**')
        elif key == 'Emph':
            return unicode('//') + process_container( value ) + unicode('//')
        elif key == 'Code':
            return unicode("''") + value[1] + unicode("''")
        elif key == "Link":
            url = value[1][0]
            return unicode('[[') + url + unicode('|') + process_container( value[0] ) + unicode(']]')
        elif key == "BulletList":
            return process_list( unicode( '* ' ), value)
        elif key == "OrderedList":
            return process_list( unicode( '- ' ), value[1])
        elif key == "Plain":
            return process_container( value )
        elif key == "BlockQuote":
            # There is no representation of blockquotes in DokuWiki - we'll just
            # have to spit out the unmodified text
            return '\n' + process_container( value ) + '\n'

        #elif key == 'Code':
        #    return unicode("''") + process_container( value ) + unicode("''")
        else:
            return unicode("unknown map key: ") + key + unicode( " value: " ) + str( value )

    if isinstance( container, list ):
        result = unicode("")
        for value in container:
            result += process_container( value )
        return result

    if isinstance( container, unicode ):
        if container == unicode( "Space" ):
            return unicode( " " )
        elif container == unicode( "HorizontalRule" ):
            return unicode( "----\n\n" )

    return unicode("unknown") + str( container )

def process_pandoc_jason( data ):
    assert( len(data) == 2 )
    result = unicode('')
    for values in data[1]:
        result += process_container( values )
    print result

def convert_file( filename ):
    # Use pandoc to parse the input file, and write it out as json
    tempfile = "temp_script_output.json"
    command = "pandoc --to=json \"%s\" --output=%s" % ( filename, tempfile )
    #print command
    os.system( command )

    input_file = open(tempfile, 'r' )
    input_text = input_file.readline()
    input_file.close()

    ## Parse the data
    data = json.loads( input_text )
    process_pandoc_jason( data )

def main( files ):
    for filename in files:
        convert_file( filename )

if __name__ == "__main__":
    files = sys.argv[1:]

    if len( files ) == 0:
        sys.stderr.write( "Supply one or more filenames to convert on the command line\n" )
        return_code = 1
    else:
        main( files )
        return_code = 0

    sys.exit( return_code )
share|improve this answer
    
Awesome! Thanks –  Oliver Salzburg Apr 3 '12 at 9:33
    
@OliverSalzburg You're welcome. (BTW, I just noticed a cosmetic typo: s/jason/json/ in several places... :-) ) –  Clare Macrae Apr 3 '12 at 13:24
    
This made my day so much easier, thanks for writing this. :-) –  DSimon Jun 18 '13 at 17:19
add comment

Not ideal, but functional solution

Markdown -> HTML -> Dokuwiki

First conversion done by pandoc

Second - HTML-WikiConverter-DokuWiki Perl module

Hint: Reversing actions of existing code

silverstripe-doc-restructuring git-repo contain code (PHP) for converting from Dokuwiki to Markdown

share|improve this answer
    
Thank you. I'll try it out. –  Clare Macrae Mar 19 '12 at 8:12
    
I tried this out, but, not being familiar with Perl, I didn't come close to getting the module to work. –  Clare Macrae Apr 2 '12 at 15:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.