Skip to content

Instantly share code, notes, and snippets.

@bobye
Forked from takaxp/org2doku
Created March 9, 2012 09:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bobye/2005868 to your computer and use it in GitHub Desktop.
Save bobye/2005868 to your computer and use it in GitHub Desktop.
Convert Emacs org-mode formatted text to Dokuwiki formatted one.
#!/opt/local/bin/perl
#
# Modified by @takaxp
# Last Update: 2012-01-09@22:13
# 2012-01-09: support date([YYYY-MM-DD XX]) insertion
# 2012-01-09: support #+BEGIN_SRC
# 2011-11-16: use strict and warnings
# 2011-11-16: Add conversion from numeric items to ` - '.
# 2011-11-16: Skip headers, if #+TITLE: is, use it as the top headline.
# 2011-11-17: Add DISQUS comment
# 2011-11-30: Add TODO/DONE color in items
# cat hoge.org | perl org2doku.pl > title.txt
# Usage
#
# cat <<EOF | ./org2doku
# * heading
#
# - item
# - sub item
#
# ** sub heading
# EOF
# ===== heading =====
#
# * item
# * sub item
#
# ==== sub heading ====
#
# Todo
#
# * font style
#
# Copyright
#
# Copyright (c) 2011 Takumi KINJO
#
# License
#
# The MIT License. See http://www.opensource.org/licenses/mit-license.php
#
use strict;
use warnings;
sub next_item_level {
my ($len, $level, $last_item_indents) = @_;
my $index = $#$last_item_indents;
if ($index >= 0) {
if ($len == $$last_item_indents[$index]) {
return $level;
} else {
for (my $i = $index; $i >= 0; $i--) {
my $last_item_indent = $$last_item_indents[$i];
if ($len > $last_item_indent) {
push @$last_item_indents, $len;
return $level + 1;
} elsif ($len == $last_item_indent) {
return $level - ($index - $i);
}
pop @$last_item_indents;
}
return $level;
}
} else {
push @$last_item_indents, $len;
return $level + 1;
}
}
sub doku_link {
my $org_hlink = shift;
while ($org_hlink =~ s/\[\[(.*?)\]\[(.*?)\]\]/[[$1|$2]]/g) {}
return $org_hlink;
}
sub shallowest_indent {
my $last_item_indents = shift;
my $shallowest_indent = 128;
foreach my $code_line (@$last_item_indents) {
if ($code_line =~ /^(\s+).*/) {
my $len = length($1);
if ($len < $shallowest_indent) {
$shallowest_indent = $len;
}
} else {
$shallowest_indent = 0;
}
}
return $shallowest_indent;
}
sub disqus_comment {
my $title_of_document = shift;
if($title_of_document){
print "===== Comments =====\n";
}else{
print "====== Comments ======\n";
}
print "~~DISQUS~~\n";
}
# Replace TODO in items with colored TODO
sub replace_todo_color {
my $line = shift;
$$line =~
s/TODO/<html><span style="color: red">TODO<\/span><\/html>/;
$$line =~
s/DONE/<html><span style="color: ForestGreen">DONE<\/span><\/html>/;
}
my $is_code_block = 0;
my $is_published = 1;
my $is_table = 0;
my $current_block_type = "";
my $item_level = 0;
my $last_head_indent = 0;
my @code_block_buf = ();
my @last_item_indents = ();
my $title_of_document = "";
while (<>) {
chomp;
my $line = $_;
# skip headers
if($line =~ /^#\+([^\s]+):\s*(.+)/){
if($1 eq "TITLE"){
$title_of_document = $2;
print "====== ".$title_of_document." ======\n";
}
next;
}
# Replace TAB at the head of lines
$line =~ s/^\t/<html>&nbsp;&nbsp;&nbsp;&nbsp;<\/html>/;
if($line =~ /^\[\d\d\d\d-\d\d-\d\d/){
$line =
"<html><span style=\"color: #666666\">Date: ".$line."<\/span><\/html>\n";
}
# use github style
$line =~ s/\=(.+?)\=/<html><span style=\"margin:0 2px;padding:2px 5px;white-space:nowrap;border:1px solid #ccc;background-color:#f8f8f8;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">$1<\/span><\/html>/g;
retry:
if ($is_published) {
if (/^=\ (.*)/) {
# howm header
$line = $1;
$line =~ s/<<<//g;
$line =~ s/^/====== /g;
$line =~ s/$/ ======/g;
$item_level = 0;
@last_item_indents = ();
} elsif (/^(\*+)\ (.*)/) {
# org heading
$last_head_indent = length($1);
if ($2 =~ /^!/) {
$is_published = 0;
next;
}
my $max_headline = 6;
if($title_of_document eq ""){
$max_headline = 7;
}
my $doku_heading = ("=" x ($max_headline - length($1)));
$line = $doku_heading." $2 ".$doku_heading;
$item_level = 0;
@last_item_indents = ();
} elsif (/^(\s+)[-+*]\ (.*)/) {
# org item
$item_level =
&next_item_level(length($1), $item_level, \@last_item_indents);
my $content = $2;
&replace_todo_color(\$content);
$line = (" " x $item_level)."* ".$content;
} elsif (/^\s*(\d+)\.\s*(.+)$/) {
# numerical item
$line = " - ".$2;
$item_level = 0;
@last_item_indents = ();
} elsif (/^#\+begin_src\s(.+)$|#\+begin_example(.*)/i) {
my $lang = $1;
my $option = "";
if($lang =~ /(.+?)\s(.+)$/){
$lang = $1;
$option = $2;
}
if($lang eq "emacs-lisp"){
$current_block_type = "lisp";
}else{
$current_block_type = $lang;
}
# org code block begin
$item_level = 0;
@last_item_indents = ();
$is_code_block = 1;
next;
} elsif (/^#\+end_src|^#\+end_example/i) {
# org code block end
$item_level = 0;
@last_item_indents = ();
$is_code_block = 0;
print "<code ".$current_block_type.">\n";
my $shallowest_indent = &shallowest_indent(\@code_block_buf);
foreach my $line (@code_block_buf) {
my $regex = "\ " x $shallowest_indent;
$line =~ s/^$regex//g;
$line =~ s/^,\*/*/g;
print $line."\n";
}
print "</code>\n";
@code_block_buf = ();
next;
} else {
# paragraph
if (!$is_code_block) {
if ($line =~ /(.*?)\ \*([^\s]+)\*\ (.*)/) {
# bold
$line = $1." **".$2."** ".$3;
}
if ($line =~ /(.*?)\ _([^\s]+)_\ (.*)/) {
# under line
$line = $1." __".$2."__ ".$3;
}
# table
if($line =~ /[^\|]*\|--/){
$line = "";
chomp($line);
}elsif($line =~ /[^\|]*|/){
$line =~ s/\|/\^/g;
}else{
$line = "?";
}
}
$line =~ s/^\s+//g;
if ($line) {
$item_level = 0;
@last_item_indents = ();
}
}
if ($is_code_block) {
push @code_block_buf, $_;
} else {
print &doku_link($line)."\n";
}
} else {
if (/^(\*+)\ (.*)/) {
my $head_indent = length($1);
if (!($2 =~ /^!/)) {
if ($head_indent <= $last_head_indent) {
$is_published = 1;
goto retry;
}
}
}
}
}
&disqus_comment($title_of_document);
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment