package AbiWord; use strict; require Exporter; require DynaLoader; @AbiWord::ISA = qw(Exporter DynaLoader); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use AbiWord ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. %AbiWord::EXPORT_TAGS = ( 'all' => [ qw( ) ] ); @AbiWord::EXPORT_OK = ( @{ $AbiWord::EXPORT_TAGS{'all'} } ); @AbiWord::EXPORT = qw( ); $AbiWord::VERSION = '0.01'; bootstrap AbiWord $AbiWord::VERSION; # Preloaded methods go here. 1; __END__ # Below is stub documentation for your module. You better edit it! =head1 NAME AbiWord - Perl extension for AbiWord =head1 SYNOPSIS $frame = AbiWord::XAP_Frame::getLastFocussed; $view = $frame->getCurrentView; $view->write("Hello world!"); 1; =head1 DESCRIPTION Perl bindings for AbiWord. =head2 INTRODUCTION Now, we're going to write out first script. I'm tired of "Hello World!", so we will just write a nice "X" into the current AbiWord document. Write the perl script: my $frame = AbiWord::XAP_Frame::getLastFocussed; my $view = $frame->getCurrentView; $view->write("X"); 1; Save it as "test_x.pl", execute abiword, and click on the Tools->Script menubar item (or in the blue arrow in the "extra" toolbar). Doing that will open a dialog box, select test_x.pl (and click "ok" ;) You should see now a sexy X in your current cursor position. If you don't see it, take a break, make sure that you're using the perl script enabled version of abiword, and if everything seems ok, but it's still not working send me (e98cuenc@yahoo.com) an email with a description of your problem. Now, how does this script write an X in your document? Let's analyse it. The first line: my $frame = AbiWord::XAP_Frame::getLastFocussed; creates a new local ("my") variable ($frame), and gives it the value of the last focussed frame that AbiWord knows about (ie, the frame in which you're working right now). Now you should get a "view" from this "frame" to be able to write something (if you find it awkward to "write" something in a "view" instead of writting in a "controller", then you're right). The second line does just that: my $view = $frame->getCurrentView; It gets the view associated with the frame that you're using, and stores it in the local variable "$view". Now, we will write something in our new view: $view->write("X"); No comments. The trailing "1;" is important. It's the return value of your script. If you forget about it, you will burn in hell, etc. Here we've just used 3 functions of the abiword's perl bindings, but with only these function we can already do plenty of cool things, for instance... =head2 ADVANCED EXAMPLE Now, we can pass to the interesting stuff (well, I'm not saying that inserting a X in your document is not interesting, but...) Let's study a script that will write in the current abiword document a serie of cards, with the following format: POBOX NAME STREET POSTAL_CODE CITY (REGION) COUNTRY The data that will be used to fill each card will be extracted from the default GnomeCard file. Here is the script: ############################## my $CARD; my $home = $ENV{'HOME'} || $ENV{'LOGDIR'} || (getpwuid($<))[7] || die "You're homeless!\n"; open CARD, "< $home/.gnome/GnomeCard.gcrd" or die "Sorry, could not open default card file: $!"; while () { read_card($CARD) if (/^BEGIN:VCARD/); } 1; sub read_card { my $CARD = shift; my ($name, $pobox, $extended, $street, $city, $region, $postalcode, $country); while () { if (/^END:VCARD/) { chomp($name); chomp($country); my $frame = AbiWord::XAP_Frame::getLastFocussed; my $view = $frame->getCurrentView; $view->write("$pobox\n") unless ($pobox eq ""); $view->write("$name\n"); $view->write("$street\n"); $view->write("$postalcode $city ($region)\n"); $view->write("$country\n"); return 0; } else { my ($type, $data) = split /:/; $name = $data if ($type eq "FN"); if ($type =~ /^ADR/) { ($pobox, $extended, $street, $city, $region, $postalcode, $country) = split(/;/, $data); } } } } ############################## ok, now that's a lot of code... but the abiword stuff is the same that we used in the last example. We get the current frame, the associated view, and then we write something. The key is in the "something". After that we parse the file generated by GnomeCard (just open GnomeCard, and fill some cards), and we write the contents of GnomeCard (formatting them a bit in the way). To understand how it works, take a navigator, go to google and search for "perl tutorial". This script is not rocket science, I'm sure that you can understand it without a glitch (if it's not the case, you can ask me whatever you want). Now, you can do more things than just write something in a view! You can do weird things, as saving documents, editing headers, etc. Here's a list of all the methods that you can use (you can always read the AbiWord.xs file, but I think that the whole point of this mini-tutorial is to show how to use the abiword perl bindings *without* having to take a look at the code): #################### $view->moveCursorAbs(target, where) $view->moveCursorRel(target, where) ex.: $view->moveCursorAbs("page", 3); $view->moveCursorAbs("line", 6); It will move your cursor to the page 3, line 6. ex.: $view->moveCursorRel("page", -2); $view->moveCursorRel("line", 4); It will advance your cursor 2 pages up, and 4 lines down. #################### $view->setCharFormat(format) ex.: $view->setCharFormat("font-weight" => "normal", "font-style" => "normal", "font-family" => "Times New Roman", "font-size" => "12pt", "text-decoration" => "normal"); It will change the current character format (if you write something after this call, it will show up in the selected format). The formats availables are: TODO #################### $view->setSectionFormat(format) ex.: $view->setSectionFormat("font-weight" => "normal", "font-style" => "normal", "font-family" => "Times New Roman", "font-size" => "12pt", "text-decoration" => "normal"); It will change the current character format (if you write something after this call, it will show up in the selected format). The formats availables are: TODO #################### $view->setBlockFormat(format) ex.: $view->setBlockFormat("font-weight" => "normal", "font-style" => "normal", "font-family" => "Times New Roman", "font-size" => "12pt", "text-decoration" => "normal"); It will change the current character format (if you write something after this call, it will show up in the selected format). The formats availables are: TODO #################### $view->changeNumColumns(ncols) ex.: $view->changeNumColumns(3); It will... well, you can guess it :) #################### $view->cmdCharDelete(forward, count) ex.: $view->cmdCharDelete(false, 3); It will delete backwards 3 characters #################### $page_nb = $view->getCurrentPageNumber It returns the current page number #################### $view->saveAs(filename, ieft, cpy) It saves the doc being edited in $view as "filename". It will be saved in the format specified by ieft, using the following table: 1 -> AbiWord 2 -> AbiWord gzipped 4 -> HTML 5 -> RTF 6 -> Text 7 -> UTF8 8 -> LaTeX 9 -> PalmDoc 10 -> RTF attic (somebody can explain me what's that?) 11 -> WML 12 -> XHTML 13 -> DocBook 16 -> Psion TextEd 17 -> Psion Word 19 -> Applix 21 -> XSL FO The last argument, cpy, says if the save will be "seen" by the user or if it will be "invisible". For instance, if you save a document named "blah.abw" as "foo.abw" and cpy is true (1), then the user will see as the filename of the document that (s)he is editing change from "blah.abw" to "foo.abw", and the '*' that marks the document as dirty will disappear. If you save the document and cpy is false (0), then the user will not see any visible change (besides the fact that there will be a new file in his hard disk). #################### $view->editHeader It changes the insertion point to the header. Next "write"'s will write in the header, and not in the body. #################### $view->editFooter It changes the insertion point to the footer. Next "write"'s will write in the footer, and not in the body. #################### $view->editBody It changes the insertion point to the body of the document. Useful after an edit{Header,Footer}. ** NOTE: It doesn't work right now. #################### $pos = $view->getPoint It returns the position of the insertion point. #################### $frame->getCurrentView It returns the view that is being used in the frame. #################### $frame->close It closes the frame. #################### $frame # openFile(filename) It opens a new frame, using the document "filename". #################### $frame # getLastFocussed It returns the last focused frame. #################### exit Quits the app =head2 FUTURE Now that we can dynamically add menu items to abiword, it should be a piece of cake to package some scripts with abiword, and bind them to new menu bar item's (a la gimp). So, if you write a script and you think that it may be of public interest, send us a copy and we will package it with abiword (once we enable the perl build by default). And that's all folks! =head1 AUTHOR J. Cuenca Abela, e98cuenc@yahoo.com =head1 SEE ALSO perl(1). =cut