#!/usr/bin/perl
#-----------------------------------------------------------------------------
#	$Id : odf2pod 0.3 2008-05-04 JMG$
#-----------------------------------------------------------------------------

=head1	NAME

odf2pod - POD generation from an OpenDocument file

=head1	SYNOPSIS

Usage : odf2pod <filename>

=head1	DESCRIPTION

This demo script exports the content of a given OpenDocument file
to POD on the standard output. In the present form, it's quite limited
and not flexible, in order to remain easily readable. It should be
considered as an example of text extraction using OpenOffice::OODoc
and not as the 'definitive' odf2pod filter, knowing that complex
document structures are not properly rendered.

Before extraction, some transformations are done in the document
in order to make it more convenient for a POD presentation. Some
pieces of metadata (title, subject, description), if defined, are
reported in the beginning of the POD. The footnotes are removed from
the content and reported in a special section at the end.

This script needs Text::Wrapper (that is not necessarily required
by the OpenOffice::OODoc installation). To implement more sophisicated
presentation rules, you could use Text::Format instead.

=cut

use OpenOffice::OODoc	2.101;
use Text::Wrapper;

#-----------------------------------------------------------------------------
my $meta;	# will be the metadata object
my $doc;	# will be the document content object
#-----------------------------------------------------------------------------
# text output utilities (using Text::Wrapper)

my $paragraph_wrapper;
my $list_wrapper;

sub	BEGIN	# wrappers initialisation
	{
	# It's just an example; in a real application, the formatting rules
	# should be more flexibles and variables according to the style
	# of each source text element
	# Here, we prepair two kinds of wrappers, in order to have
	# a larger left margin for item lists than for ordinary paragraphs
	$paragraph_wrapper	= Text::Wrapper->new
			(
			columns		=> 76,
			par_start	=> '        ',
			body_start	=> '        '
			);
	$list_wrapper		= Text::Wrapper->new
			(
			columns		=> 76,
			par_start	=> '            ',
			body_start	=> '            '
			);
	}

sub	heading_output
	{
	my ($level, $text) = @_;
	$text && print "=head$level\t$text\n\n";
	}

# output the content according to the type of text object
sub	content_output
	{
	my $element = shift; # it's an OOo text object (not a flat string)
	my $text = $doc->getText($element);

	# choose an output format according to the type
	if ($element->isItemList)
		{
		print $list_wrapper->wrap($text) . "\n";
		}
		# we use the paragraph output rule for any element
		# that is not a list
	else
		{
		print $paragraph_wrapper->wrap($text) . "\n";
		}
		# in a more specialised script, we could select another
		# alternative wrapper according to the style (using the
		# getStyle() method of OpenOffice::OODoc::Text)
	}

#-----------------------------------------------------------------------------

# initialise the OOo file object
my $ooarchive	= odfContainer($ARGV[0])
	or die "No regular OpenOffice.org file\n";

# extract the metadata
$meta	= odfMeta(container => $ooarchive)
	or warn "This file has not standard ODF properties. Looks strange.\n";

# extract the content
$doc	= odfDocument(container => $ooarchive, part => 'content')
	or die "No standard ODF content ! I give up !\n";

# attempt to use some metadata to begin the output
if ($meta)
	{
	my $title = $meta->title;
	if ($title)
		{
		heading_output(1, "NAME");
		print $paragraph_wrapper->wrap($title) . "\n";
		}
	my $subject = $meta->subject;
	if ($subject)
		{
		heading_output(1, "SUBJECT");
		print $paragraph_wrapper->wrap($subject) . "\n";
		}
	my $description = $meta->description;
	if ($description)
		{
		heading_output(1, "DESCRIPTION");
		print $paragraph_wrapper->wrap($description) . "\n";
		}
	# we could dump other metadata here...
	}

# the strange 2 next lines prevent the getText() method of
# OpenOffice::OODoc::Text (see the corresponding man page) from using
# its default tags for spans and footnotes
delete $doc->{'delimiters'}->{'text:span'};
delete $doc->{'delimiters'}->{'text:footnote-body'};

# here we select the tab as field separator for table field output
# (the default is ";" as for CSV output)
$doc->{'field_separator'} = "\t";

# in the next sequence, we will extract all the footnotes, store them for
# later processing and remove them from the content
my @notes = $doc->getFootnoteList;
$doc->removeElement($_) for @notes;

# get the full list of text objects (without the previously removed footnotes)
my @content = $doc->getTextElementList;

# if the first text element is not a heading, we create a leading
# heading here, using the title or an arbitrary name
heading_output(1, $meta->title || "INTRODUCTION")
	unless ($content[0]->isHeading);
foreach my $element (@content)
	{
	my $level = $doc->getLevel($element); 	# get the hierarchical level
	if ($level)	# if an element has a 'level', it's a heading
		{
		heading_output($level, $doc->getText($element));
		}
	else
		{
		content_output($element);	
		}
	}

# all the document body is processed

if (@notes)
	{
	# OK, we have some footnotes in store
	# create a special section
	heading_output(1, "NOTES");
	my $count = 0;
	while (@notes)
		{
		$count++;
		my $element = shift @notes;
		my $text = "[$count] " . $doc->getText($element);
		print	$paragraph_wrapper->wrap($text) . "\n";
		}
	}

# end of POD output
print "=cut\n";

exit;

#-----------------------------------------------------------------------------