将LibreOffice文档转换为豆瓣日记

豆瓣日记的编辑器一直以来都只支持纯文本的,因此无法将原先在LibreOffice中写的带有简单格式的文章导出。由于我在豆瓣主要写一些随笔性的内容,所以它们在LibreOffice中排版时也并未用到什么复杂的格式,充其量就是粗体、斜体、加亮等字符样式,以及章节标题、多级有序和无序列表的段落样式。接下来,我的想法就是先将LibreOffice中选中的文章导出成MediaWiki的markup格式,然后再写一个脚本程序对这个纯文本文件过滤处理一下,变成适合在豆瓣日记编辑器中粘贴的样式即可。该脚本程序最终用Perl来编写。对于字符样式,其直接将相应的样式标识符删除,例如在MediaWiki中:

  • 粗体用'''...'''标识;
  • 斜体用''...''标识;
  • 粗斜体用'''''...'''''标识。

对于多级有序列表,经Perl脚本转换后,采用不同的序号编号以及缩进进行区分,如:

  • 一级列表用阿拉伯数字:1.、2.、3. ...;
  • 二级列表用加右括号的小写字母:a)、b)、c)、...;
  • 三级列表用带圈的阿拉伯数字:①、②、③、...它们可以在特殊字符中找到;
  • 四级列表用小写罗马数字:i.、ii.、iii.、...。

对于多级无序列表,则采用特殊符号与缩进来区分。一至四级的编辑分别为:• ◦ ▪ ▫。

对于章节标题,则保留MediaWiki的格式,分别用=、==、===等表示一、二、三级标题。

Perl脚本源码如下。其命令行第一个参数为由LibreOffice导出的MediaWiki文本文件名。转换后的文本直接输出到控制台。

#!/usr/bin/perl

use warnings;
use strict;

our @level_counters = (0, 0, 0, 0);

our @unordered_list_symbols = qw/ • ◦ ▪ ▫ /;
our @level0_symbols = qw/ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. /;
our @level1_symbols = qw/ a) b) c) d) e) f) g) h) i) j) /;
our @level2_symbols = qw/ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ /;
our @level3_symbols = qw/ i. ii. iii. iv. v. vi. vii. viii. ix. x. /;

# Symmetric typeface markers
our $bold_marker = "'''";
our $italic_marker = "''";
our $bold_italic_marker = "'''''";

sub ProcessListBr {
    my $current_list_level = $_[0];
    my $first_line_spacings = "   " x $current_list_level;
    s/<br\/>/\n$first_line_spacings/g;
}

sub ProcessLists {
    if (s/^\* +/$unordered_list_symbols[0] /) {
    ProcessListBr(1);
    return;
    }
    
    if (s/^\*\* +/    $unordered_list_symbols[1] /) {
    ProcessListBr(2);
    return;
    }

    if (s/^\*\*\* +/      $unordered_list_symbols[2] /) {
    ProcessListBr(3);
    return;
    }

    if (s/^\*\*\*\* +/        $unordered_list_symbols[3] /) {
    ProcessListBr(4);
    return;
    }

    my $clear_level_numbering_index = 0;

    if (s/^# +/$level0_symbols[$level_counters[0]] /) {
    $clear_level_numbering_index = 1;
    $level_counters[0]++;
    ProcessListBr(1);
    }

    if (s/^## +/   $level1_symbols[$level_counters[1]] /) {
    $clear_level_numbering_index = 2;
    $level_counters[1]++;
    ProcessListBr(2);
    }

    if (s/^### +/      $level2_symbols[$level_counters[2]] /) {
    $clear_level_numbering_index = 3;
    $level_counters[2]++;
    ProcessListBr(3);
    }

    if (s/^#### +/        $level3_symbols[$level_counters[3]] /) {
    $clear_level_numbering_index = 4;
    $level_counters[3]++;
    ProcessListBr(4);
    }

    if ($clear_level_numbering_index != 0) {
    for (my $i = $clear_level_numbering_index; $i <= $#level_counters; $i++) {
        $level_counters[$i] = 0;
    }

    return;
    }
    
    @level_counters = (0, 0, 0, 0);
}

sub ProcessURL {
    s/\[(http[^\s]+)\s+([^\s]+)\]/<a href=\"$1\">$2<\/a>/g;
}

sub RemoveFormat {
    s/$bold_italic_marker(.+?)$bold_italic_marker/$1/g;
    s/$bold_marker(.+?)$bold_marker/$1/g;
    s/$italic_marker(.+?)$italic_marker/$1/g;
    s/<u>(.+?)<\/u>/$1/g;
}

my $wiki_file = shift;

if (defined($wiki_file)) {
    open INPUT, "<$wiki_file" or die "Cannot open the file $wiki_file!\n";

    while(<INPUT>) {
    ProcessLists;
    ProcessURL;
    RemoveFormat;
    print;
    }
    
    close INPUT;
}
else {
    print "Please specify the input file!\n";
}

 

posted @ 2017-02-12 22:57  皮波迪先生  阅读(747)  评论(0编辑  收藏  举报