#!/usr/bin/perl -w -I/data/perl/Node
# Copyright (C) 2004 by Steve Litt # Licensed with the GNU General Public License, Version 2 # ABSOLUTELY NO WARRANTY, USE AT YOUR OWN RISK # See http://www.gnu.org/licenses/gpl.txt
use strict;
use Node;
package Callbacks; # {{{1 sub new() #{{{2 { my($type) = $_[0]; my($self) = {}; bless($self, $type); $self->{'bt_break_var'} = 'no'; $self->{'bt_indicator_var'} = '^\t*: '; $self->{'output_data'} = undef; $self->{'level_mapping'} = undef; # shaky $self->{'in_body_text'} = 0; $self->{'this_body_text_node'} = undef; return($self); }
sub getOutputData($) { return $_[0]->{'output_data'};} #{{{2
sub hasOutputData($) { return defined $_[0]->{'output_data'};} #{{{2
sub setOutputData($) { $_[0]->{'output_data'} = $_[1];} #{{{2
sub getLevelMapping($) { return $_[0]->{'level_mapping'};} #{{{2
sub hasLevelMapping($) { return defined $_[0]->{'level_mapping'};} #{{{2
sub setLevelMapping($) { $_[0]->{'level_mapping'} = $_[1];} #{{{2
sub getBtIndicatorVar($) { return $_[0]->{'bt_indicator_var'};} #{{{2
sub hasBtIndicatorVar($) { return defined $_[0]->{'bt_indicator_var'};} #{{{2
sub setBtIndicatorVar($$) { $_[0]->{'bt_indicator_var'} = $_[1];} #{{{2
sub getBtBreakVar($) { return $_[0]->{'bt_break_var'};} #{{{2
sub hasBtBreakVar($) { return defined $_[0]->{'bt_break_var'};} #{{{2
sub setBtBreakVar($$) #{{{2 { my $state = lc($_[1]); if($state eq 'no') { $_[0]->{'bt_break_var'} = 'no'; } elsif($state eq 'yes') { $_[0]->{'bt_break_var'} = 'yes'; } elsif($state eq 'new') { $_[0]->{'bt_break_var'} = 'new'; } else { die "Invalid value (" . $state . ") given to setBtBreakVar(), aborting...\n"; } }
sub cbCountChildren() #{{{2 { my($self, $checker, $level) = @_; unless (defined($checker)) {return;} my $childCount=0; if($checker->hasFirstChild()) { $childCount++; my $checker2 = $checker->getFirstChild(); while($checker2->hasNextSibling()) { $childCount++; $checker2 = $checker2->getNextSibling(); } $checker->setAttribute("children", $childCount); } }
sub cbPrintNode() #{{{2 { my($self, $checker, $level) = @_; unless (defined($checker)) {return;}
#### PRINT NODE'S VALUE for(my $n=0; $n < $level; $n++) {print "\t";} print "* "; print $checker->getValue(); print "\n";
#### PRINT NODE'S ATTRIBUTES for(my $n=0; $n <= $level; $n++) {print "\t";} print "(";
my %attribs = (); %attribs = $checker->getAttributes() if $checker->hasAttributes();
my @keys = keys(%attribs); foreach my $key (sort @keys) { print $key, "=", $attribs{$key}, "; "; }
print ")\n"; }
sub cbLevel2paragraphType($) #{{{2 { my($self, $checker, $level) = @_; unless (defined($checker)) {return;} $checker->setAttribute('paragraphType', $level); }
sub cbCollectBodyTextParagraphs() #{{{2 { my($self, $checker, $level) = @_; unless (defined($checker)) {return;}
my $lineType = 'nobt'; my $lineValue = ''; my $lookfor = $self->getBtIndicatorVar();
if($checker->getValue() =~ m/($lookfor)\s*(\S)(.*)\s*/) { $lineType = 'bt'; $lineValue = $2 . $3; } else { $lineType = 'nobt'; } if($self->{'in_body_text'} == 0) { if($lineType eq 'bt') { my $newnode = Node->new( '', 'bodytext', $lineValue); $newnode->setAttribute('paragraphType', 'bodytext'); $checker->insertSiblingBeforeYou($newnode); $self->{'this_body_text_node'} = $checker->getPrevSibling(); $checker->deleteSelf(); } } else { if($lineType eq 'bt') { $checker->getValue() =~ m/($lookfor)\s*(.*)(\S)/; my $newtext = $2 . $3;
my $currtext = $self->{'this_body_text_node'}->getValue(); $newtext = $currtext . ' ' . $newtext; $self->{'this_body_text_node'}->setValue($newtext); $checker->deleteSelf(); } } $self->{'in_body_text'} = 1 if $lineType eq 'bt'; $self->{'in_body_text'} = 0 if $lineType eq 'nobt'; }
sub cbOutputLyx($) #{{{2 { my($self, $checker, $level) = @_; unless (defined($checker)) {return;} return if $level < 1;
$self->{'output_data'}->setOutputValue($checker->getValue()); my $key = $checker->getAttribute('paragraphType'); my $startTag = $self->{'level_mapping'}->getStartTag($key); $self->{'output_data'}->setOutputStartTag($startTag); $self->{'output_data'}->write(); }
package OutputData; #{{{1
sub new() #{{{2 { my($type) = $_[0]; my($self) = {}; bless($self, $type); $self->{'output_start_tag'} = ''; $self->{'output_value'} = ''; $self->{'output_end_tag'} = ''; $self->{'output_line_length'} = 78;
return($self); }
sub setOutputLineLength($$) { $_[0]->{'output_line_length'} = $_[1]; } #{{{2
sub getOutputLineLength($$) { return $_[0]->{'output_line_length'}; } #{{{2
sub hasOutputLineLength($$) { return defined $_[0]->{'output_line_length'}; } #{{{2
sub setOutputStartTag($$) { $_[0]->{'output_start_tag'} = $_[1]; } #{{{2
sub getOutputStartTag($) { return $_[0]->{'output_start_tag'}; } #{{{2
sub hasOutputStartTag($) { return defined($_[0]->{'output_start_tag'}); } #{{{2
sub setOutputValue($$) { $_[0]->{'output_value'} = $_[1]; } #{{{2
sub getOutputValue($) { return $_[0]->{'output_value'}; } #{{{2
sub hasOutputValue($) { return defined($_[0]->{'output_value'}); } #{{{2
sub setOutputEndTag($$) { $_[0]->{'output_end_tag'} = $_[1]; } #{{{2
sub getOutputEndTag($) { return $_[0]->{'output_end_tag'}; } #{{{2
sub hasOutputEndTag($) { return defined($_[0]->{'output_end_tag'}); } #{{{2
sub clear() #{{{2 { $_[0]->setOutputStartTag(''); $_[0]->setOutputValue(''); $_[0]->setOutputEndTag(''); }
sub write() #{{{2 { my $self = shift; print $self->getOutputStartTag(); my @words = split(/ /, $self->getOutputValue()); my $lineLength=0; for my $word (@words) { my $wordLength = length($word); if($lineLength + 1 + $wordLength > $self->getOutputLineLength()) { print "\n"; $lineLength=0; } if($lineLength > 0) { print ' '; $lineLength++; } print $word; $lineLength += $wordLength; } print $self->getOutputEndTag(); print "\n"; }
package LevelMapping; #{{{1 sub new($) #{{{2 { my($type) = $_[0]; my($self) = {}; bless($self, $type); $self->{'map_filename'} = 'o2l.conf'; my %starttags = (); $self->{'starttags'} = \%starttags; my %environments = (); $self->{'environments'} = \%environments; $self->{'output_end_tag'} = ''; return($self); }
sub getEndTag($$){return $_[0]->{'endtags'}->[$_[1]];} #{{{2
sub hasEndTag($$){return defined $_[0]->{'endtags'}->[$_[1]];} #{{{2
sub setEndTag($$$){;} ### NO END TAG FOR CURRENT LYX #{{{2
sub getStartTag($$){return $_[0]->{'starttags'}->{$_[1]};} #{{{2
sub hasStartTag($$){return defined $_[0]->{'starttags'}->{$_[1]};} #{{{2
sub setStartTag($$$){$_[0]->{'starttags'}->{$_[1]} = $_[2];} #{{{2
sub getEnvironment($$){return $_[0]->{'environments'}->{$_[1]};} #{{{2
sub hasEnvironment($$){return defined $_[0]->{'environments'}->{$_[1]};} #{{{2
sub setEnvironment($$$){$_[0]->{'environments'}->{$_[1]} = $_[2];} #{{{2
sub getEnvironmentChecked($$) #{{{2 { my $self = shift; my $key = shift; if(!$self->hasEnvironment($key)) { return('ERROR_' . $key . '_ERROR'); } return($self->getEnvironment($key)); }
sub setMapFilename($$) { $_[0]->{'map_filename'} = $_[1]; } #{{{2
sub getMapFilename($) { return $_[0]->{'map_filename'}; } #{{{2
sub hasMapFilename($) { return defined($_[0]->{'map_filename'}); } #{{{2
sub lrtrim($$) #{{{2 { shift; my $string = shift; return '' if $string =~ m/^\s*$/; $string =~ m/^\s*(.*)(\S)\s*/; $string = $1 . $2; return $string; }
sub readMapping($) #{{{2 { my $self = shift; my $inf; #input file descriptor open($inf, "<" . $self->getMapFilename()) or die "Could not read map file (" . $self->getMapFilename() . "), aborting ...\n"; my(@lines) = <$inf>; foreach my $line (@lines) { my($key, $value) = split(/:/, $line, 2); $key = $self->lrtrim($key); $value = $self->lrtrim($value); $self->setEnvironment($key, $value); } close($inf); }
sub adjustMapping($) #{{{2 { my $self = shift; my @keys = keys %{$self->{'environments'}}; foreach my $key (@keys) { my $value = $self->getEnvironmentChecked($key); $value = "\\layout " . $value . "\n\n"; $self->setStartTag($key, $value); } }
package Main; #{{{1 sub main() #{{{2 { #### HANDLE PARAGRAPH TYPE MAPPING my $levelMap = LevelMapping->new(); $levelMap->setMapFilename($ARGV[1]) if defined $ARGV[1]; $levelMap->readMapping(); $levelMap->adjustMapping();
#### CREATE AN OUTPUT OBJECT my $outputObject = OutputData->new(); $outputObject->setOutputLineLength(70);
#### DIAGNOSTIC: PRINT level/bodytext to environment to StartTag map # my %st; # %st = %{$levelMap->{'starttags'}}; # %st = %{$levelMap->{'environments'}}; # my @keys = sort keys %st; # for my $key (@keys) # { # print ']' . $key . '[ '; # print ">"; # print $levelMap->getStartTag($key); # print "<\n"; # } # exit(1); #### PARSE FROM STDIN my $parser = OutlineParser->new(); $parser->setCommentChar("#"); $parser->fromStdin(); my $topNode=$parser->parse();
#### INSTANTIATE THE Callbacks OBJECT my $callbacks = Callbacks->new(); $callbacks->setLevelMapping($levelMap); $callbacks->setOutputData($outputObject);
#### SET paragraphType attribute my $walker; $walker = Walker->new ( $topNode, [\&Callbacks::cbLevel2paragraphType, $callbacks] ); $walker->walk();
#### COLLECT BODY TEXT PARAGRAPHS $walker = Walker->new ( $topNode, [\&Callbacks::cbCollectBodyTextParagraphs, $callbacks] ); $walker->walk();
#### OUTPUT LYX $walker = Walker->new ( $topNode, [\&Callbacks::cbOutputLyx, $callbacks] ); $walker->walk();
#### DIAGNOSTIC: PRINTING EACH NODE'S VALUE, #### ATTRIBUTE LIST AND CHILD MESSAGE # $walker = Walker->new # ( # $topNode, # [\&Callbacks::cbPrintNode, $callbacks] # ); # $walker->walk(); }
# }}}1 main();
# vim600: set foldmethod=marker foldlevel=1:
|