Emacs

org 模式到 dokuwiki 轉換器

  • November 12, 2020

dokuwiki 轉換器是否有 emacs 組織模式?是否有 emacs 組織模式轉換器的 dokuwiki?

我只是在找同樣的東西,在這裡找到了這個問題,也在GitHub上找到了Perl腳本形式的解決方案。

腳本

#!/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>    <\/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;

我嘗試過轉換一個簡短的 Org 文件,結果很順利。

我需要同樣的,並且已經將導出後端放在一起,對於 org-mode 8.0 及更高版本 https://github.com/w-vi/ox-wk.el,它還沒有 100% 準備好,但主要的東西應該​​可以工作。

引用自:https://unix.stackexchange.com/questions/9794