本を読む

読書やコンピュータなどに関するメモ

テキストからOpenOffice.org Impressファイルを作るツール

 アウトライン形式のプレーンテキストから、OpenOffice.org Impress(PowerPoint互換のソフト)の.odpファイルを生成するツールを、Perlで試作した。OpenOffice::OODocモジュールを使っている。

背景

 私がプレゼン資料とか作るときには、まずテキストファイルにアウトライン形式で構成を下書きしている。それをPowerPointやOpenOffice.orgのアウトラインモードに貼りつけてから、仕上げる。

 貼りつけるとき、PowerPointでは、こんな(↓)感じのテキストにしておくと、構造付けができる(<tab>とある部分はタブ)。

ページタイトル1
<tab>箇条書き項目1
<tab><tab>箇条書き小項目1-1
<tab><tab>箇条書き小項目1-2
<tab>箇条書き項目2
ページタイトル2

 しかし、OpenOffice.org Impressだと、タブによる構造づけが効かない。そこで、変換ツールを作ってみた。

入力形式

 PukiWikiやYukiWiki、はてなダイアリーなどで使われている形式をベースにしている。

  • 1項目1行
  • ページのタイトルは、行頭に「*」
  • 箇条書き項目は、行頭に「-」。「-」の数でレベルを表わす
  • それ以外の行は無視(空行など)

 実例はこんな(↓)感じ。

*ページタイトル1
-箇条書き項目1
--箇条書き小項目1-1
--箇条書き小項目1-2
-箇条書き項目2
*ページタイトル2

事前に必要なもの

 雛形になるOpenOffice.org Impressのファイルを用意しておく。

  • ファイル名は「template.odp」
  • 全1ページ
  • 箇条書きスタイルを選んえ、内容を適当に入れておく

 あともちろん、PerlとOpenOffice::OODocモジュール、その依存モジュールは必要。

決めうちなもの

 手抜きのため、以下の点は決めうちにしている。

  • 入力テキストは標準入力のみで、文字コードはUTF-8
  • 雛形ファイルは、カレントディレクトリの「template.odp」
  • 出力ファイルは、カレントディレクトリの「output.odp」

 実行はこんな(↓)感じ。

$ perl outline2odp.pl < sample.txt

outline2odp.plのスクリプト実物

#!/usr/bin/perl
use strict;
use warnings;
use OpenOffice::OODoc;

our $VERSION = '0.01';

localEncoding 'utf-8';

my $tmplfile = 'template.odp';
my $outfile = 'out.odp';
my $tmplpage = 1;

my $doc = MyOdp->new(file => $tmplfile);

$doc->clear_title_text($tmplpage);
$doc->clear_list_element($tmplpage);

my $page = $tmplpage;
while (<>) {
    chomp;
    if (my ($title) = m/^\*\s*(.*)$/) {
	$doc->copy_page($tmplpage, ++$page);
	$doc->set_title($page, $title);
    } elsif (my ($level, $text) = m/^(-+)\s*(.*)$/) {
	$doc->append_list_element($page, $text, length($level));
    }
}

$doc->save($outfile);


package MyOdp;
use base qw( OpenOffice::OODoc::Document );

sub copy_page {
    my $self = shift;
    my ($source, $dest) = @_;

    my $p = $self->getElement(page_xpath($source)) or die;
    my $p2 = $p->copy();
    $p2->paste(last_child => $self->getElement('//office:presentation'));
    $self->setAttributes($p2, 'draw:name' => "page$dest");
}

sub set_title {
    my $self = shift;
    my ($page, $text) = @_;

    my $t = $self->getElement(title_xpath($page)) or die;
    my $e = $self->createParagraph($text, 'P1');
    $e->paste(last_child => $t);
}

sub clear_title_text {
    my $self = shift;
    my ($page) = @_;
    $self->replaceElement(title_xpath($page), 0,
                         $self->createElement('<draw:text-box />'));
}

sub clear_list_element {
    my $self = shift;
    my ($page) = @_;
    $self->replaceElement(list_xpath($page), 0,
                         $self->createElement('<draw:text-box />'));
}

sub append_list_element {
    my $self = shift;
    my ($page, $text, $level) = @_;

    my $t = $self->getElement(list_xpath($page)) or die;
    my $list = create_list_element($self, $text, $level);
    $list->paste(last_child => $t);
}

sub create_list_element {
    my $self = shift;
    my ($text, $level) = @_;

    my $e = $self->createParagraph($text, ('P' . ($level + 2)));
    while ($level--) {
	my $li = $self->createElement('text:list-item');
	$e->paste(last_child => $li);
	my $ul = $self->createElement('text:list');
	$li->paste(last_child => $ul);
	$e = $ul;
    }
    $self->setAttribute($e, 'text:style-name' => 'L1');
    $e;
}

sub page_xpath {
    my ($page) = @_;
    sprintf('//draw:page[@draw:name="page%d"]', $page);
}

sub title_xpath {
    my ($page) = @_;
    page_xpath($page) .
	'/draw:frame[@presentation:class="title"]/draw:text-box';
}

sub list_xpath {
    my ($page) = @_;
    page_xpath($page) .
	'/draw:frame[@presentation:class="outline"]/draw:text-box';
}

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://emasaka.blog65.fc2.com/tb.php/224-f0bbf3d5

 | HOME | 

Categories

Recent Entries

Recent Comments

Recent Trackbacks

Appendix

emasaka

emasaka

フリーター。
連絡先はこのへん

Monthly


FC2Ad