Skip to content

Instantly share code, notes, and snippets.

@edvakf
Created February 22, 2009 21:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save edvakf/68624 to your computer and use it in GitHub Desktop.
Save edvakf/68624 to your computer and use it in GitHub Desktop.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Very Simple PukiWiki to MediaWiki Converter</title>
<style type="text/css">
textarea{
width:100%;
}
table, tr, th, td{
border: solid black 1px;
}
.footnote{
font-size:80%;
}
.w3{
float:right;
}
</style>
</head>
<body>
<h1>Very Simple PukiWiki to MediaWiki Converter</h1>
<h2>PukiWiki Format Text (input)</h2>
<p><textarea rows="20" cols="100" id="pukitext"></textarea></p>
<p><button onclick="convert()">Convert</button></p>
<h2>MediaWiki Format Text (output)</h2>
<p><textarea rows="20" cols="100" id="mediatext"></textarea></p>
<div>
<h3>Features</h3>
<p>This application is created in order to assist migration of <a href="http://opera-wiki.com/">http://opera-wiki.com/</a> from PukiWiki to MediaWiki.</p>
<p>Supported wiki formats are below.</p>
<table>
<tbody>
<tr><th>PukiWiki</th><th>MediaWiki</th><th>Comment</th></tr>
<tr><td>-/+ (start of line)</td><td>*/# (start of line)</td><td>lists (ordered/unordered, maximum depth of 3)</td></tr>
<tr><td>space (start of line)</td><td>space (start of line)</td><td>formatted text (&lt;pre&gt;)</td></tr>
<tr><td>* (start of line)</td><td>== ==</td><td>headings (maximum level of 5)</td></tr>
<tr><td>~ (end of line)</td><td>&lt;br /&gt;</td><td>line break<a id="annotation_for_br" href="#footnote_for_br">*1</a></td></tr>
<tr><td>'''/''</td><td>''/'''</td><td>emphases</td></tr>
<tr><td>%% %%</td><td>&lt;del&gt; &lt;/del&gt;</td><td>del</td></tr>
<tr><td>[[text:URL]]/[[text&gt;URL]]</td><td>[URL text]</td><td>links<a id="annotation_for_a" href="#footnote_for_a">*2</a></td></tr>
<tr><td>---- or more</td><td>----</td><td>horizontal line</td></tr>
<tr><td>#foobar</td><td></td><td>PukiWiki plugins (removed)</td></tr>
<tr><td>&gt; (start of line)</td><td>&lt;blockquote&gt; &lt;/blockquote&gt;</td><td>blockquote (maximum depth of 1)</td></tr>
<tr><td>// (start of line)</td><td>&lt;!-- --&gt;</td><td>comment</td></tr>
<tr><td>| | |</td><td>{|..|}</td><td>table (very limited support)</td></tr>
<tr><td>|~foo|</td><td>!foo</td><td>header cell (table)</td></tr>
<!-- table row template
<tr><td> </td><td> </td><td> </td></tr>
-->
</tbody>
</table>
<div class="footnote">
<p id="footnote_for_br"><a href="#annotation_for_br">*1</a> PukiWiki does not count line breaks of the source text as line breaks, but opera-wiki.com does. So this converter adds &lt;br /&gt; at the end of every line except for those followed by blockquote, table, list, heading or a blank line.</p>
<p id="footnote_for_a"><a href="#annotation_for_a">*2</a> I'm very sloppy here. I assume everything that is of type [[text:http*]] or [[text&gt;http*]] as an external link and make this conversion. Other links of type [[ ]] are kept unchanged.</p>
</div>
<h3>License, disclaimer, etc.</h3>
<p>This document, which encludes HTML, CSS and JavaScript source codes though DOES NOT include linked image(s), is distributed under <a href="http://en.wikipedia.org/wiki/Public_domain">public domain</a>.</p>
<p>The author of this document is not responsible for any damage/harm related to use of this document.</p>
</div>
<p class="w3"><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Strict" height="31" width="88"></a></p>
<script type="text/javascript">
<!--
function convert(){
text = getPuki();
lines = text.split(/\r?\n/);
for(var n=0;n<lines.length;n++){
lines[n] = convLine(lines[n]);
}
setMedia(finalize(lines.join('\r\n')));
}
// linewise conversion
var convLine = (function(){
var ENV = {'BLOCKQUOTE':false,'TABLE':false};
var breakableCheck = [
//pre
{'re' : /^[ \t]/, 'func' : function(line,re){return line}},
//horizontal line
{'re' : /^----+/, 'func' : function(line,re){return line.replace(re,'----')}},
//comment
{'re' : /^\/\//, 'func' : function(line,re){return line.replace(re,'<!-- ').replace(/$/,' -->')}},
//remove plugins
{'re' : /^#.*/, 'func' : function(line,re){return ''}},
//{'re' : /^#contents\(?.*\)?;?\s*/, 'func' : function(line,re){return ''}},
//{'re' : /^#navi\(?.*\)?;?\s*/, 'func' : function(line,re){return ''}},
//close block element
{'re' : /^$/, 'func' :
function(line,re){
if(ENV.BLOCKQUOTE){
ENV.BLOCKQUOTE=false;
return '<\/blockquote>\r\n'
}else if(ENV.TABLE){
ENV.TABLE=false;
return '|}\r\n'
}else{
return ''
}
}
}
];
var unbreakableCheck = [
//headings
{'re' : /^\*\*\*\*\*/, 'func' : function(line,re){return line.replace(re,'====== ').replace(/(\[#\w{8}\])?\s*$/,' ======')}},
{'re' : /^\*\*\*\*/, 'func' : function(line,re){return line.replace(re,'===== ').replace(/(\[#\w{8}\])?\s*$/,' =====')}},
{'re' : /^\*\*\*/, 'func' : function(line,re){return line.replace(re,'==== ').replace(/(\[#\w{8}\])?\s*$/,' ====')}},
{'re' : /^\*\*/, 'func' : function(line,re){return line.replace(re,'=== ').replace(/(\[#\w{8}\])?\s*$/,' ===')}},
{'re' : /^\*/, 'func' : function(line,re){return line.replace(re,'== ').replace(/(\[#\w{8}\])?\s*$/,' ==')}},
//unordered lists
{'re' : /^---/, 'func' : function(line,re){return line.replace(re,'***')}},
{'re' : /^--/, 'func' : function(line,re){return line.replace(re,'**')}},
{'re' : /^-/, 'func' : function(line,re){return line.replace(re,'*')}},
//ordered lists
{'re' : /^\+\+\+/, 'func' : function(line,re){return line.replace(re,'###')}},
{'re' : /^\+\+/, 'func' : function(line,re){return line.replace(re,'##')}},
{'re' : /^\+/, 'func' : function(line,re){return line.replace(re,'#')}},
//line break after each line in paragraph
{'re' : /^[^ =*#|]/, 'func' : function(line,re){return line.replace(/~?$/,'<br \/>')}},
//make double quotes to triple and triple to double (strong/italic)
{'re' : /\'\'\'/g, 'func' : function(line,re){return line.replace(re,"TWO_QUOTATIONS")}},
{'re' : /\'\'/g, 'func' : function(line,re){return line.replace(re,"'''")}},
{'re' : /TWO_QUOTATIONS/g, 'func' : function(line,re){return line.replace(re,"''")}},
//footer text (complecated, so I'll leave it as a comment)
//{'re' : /\(\((.+)\)\)/g, 'func' : function(line,re){return line.replace(re,"($1)")}},
//del
{'re' : /%%(.+)%%/g, 'func' : function(line,re){return line.replace(re,"<del>$1<\/del>")}},
//external links
{'re' : /\[\[([^:>]+?)[:>](http.+?)\]\]/g, 'func' : function(line,re){return line.replace(re,'[$2 $1]')}},
//blockquote
{'re' : /^> ?/, 'func' : function(line,re){if(ENV.BLOCKQUOTE){return line.replace(re,'')}else{ENV.BLOCKQUOTE=true;return line.replace(re,'<blockquote>\r\n')}}},
//table
{'re' : /^\|/, 'func' :
function(line,re){
if(ENV.TABLE){
return '|-'+line.replace(/\|[hf]?\s*$/,'').replace(/\|~/g,'\r\n!').replace(/\|/g,'\r\n|');
}else{
ENV.TABLE=true;
return '{|'+line.replace(/\|[hf]?\s*$/,'').replace(/\|~/g,'\r\n!').replace(/\|/g,'\r\n|');
}
}
},
//end of table
{'re' : /^[ =*#]/, 'func' : function(line,re){if(ENV.TABLE){ENV.TABLE=false;return '|}\r\n'+line;}return line}}
];
return function(line){
for(var i=0;i<breakableCheck.length;i++){
if(breakableCheck[i].re.test(line))
return breakableCheck[i].func(line,breakableCheck[i].re);
}
for(var i=0;i<unbreakableCheck.length;i++){
if(unbreakableCheck[i].re.test(line))
line = unbreakableCheck[i].func(line,unbreakableCheck[i].re);
}
return line;
}
})();
// whole text conversion
function finalize(text){
//remove line break right before next block/block end
return text.replace(/<br \/>(\r\n(?:<!--[^\n]*-->\r\n)*(?:[ =*#\r]|<\/blockquote>|{\|))/gm,"$1");
}
function getPuki(){
return $('pukitext').value;
}
function setMedia(text){
$('mediatext').value=text;
}
function $(id){
return document.getElementById(id);
}
// -->
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment