My program is supposed to accept MSWord .doc files, convert them to
RTF, split them into separate files at each hard page break, and
create a visible header for each of those files using data mined from
the body of each document.  So far so good: I have a program that is
perfect at using OLE to convert the files with Word.  It's pretty good
at doing all of the rest of this as well, but it can be broken at any
time by useless (at least *I* think it's useless, the folks at
Microsoft evidently don't agree) format-command garbage that MSWord
will arbitrarily stick into the converted RTF documents.

For instance, one of the key pieces of data is a date.  My program
uses this date in a couple of different ways: (1) the date is a kind
of anchor point that my program uses as it is carving up the single
file and shuffling document parts around to rebuild them into the
individual output files; (2) the date is one of the pieces of data
that has to appear in the header.  So the germane section of my
program looks like this:

# Separate the header from the body
( $header = $whole )  =~
s#\{\\b\\insrsid\d+\s?\d{1,2}[-_/.]\d{1,2}[-_/.]\d.*##gs;
# Remove the header from the body
            $whole    =~
s#^.*?(?=\{\\b\\insrsid\d+\s?\d{1,2}[-_/.]\d{1,2}[-_/.]\d)##gs;
# Separate the table row definition from the header
( $trowd  = $header ) =~ s#^.*?(?=\\trowd)##gs;
# Remove the table row definition from the header
            $header   =~ s#\\trowd.*##gs;
# Split the body into documents by page
@pages    = split( /\\page/s, $whole );
# Turn each page into its own document
for ( @pages ) {
    # Remove everything before the beginning of the first cell
    s#^.*?(?=\{\\b\\insrsid\d+\s?\d{1,2}[-_/.]\d{1,2}[-_/.]\d)##gs;
    # Remove double right-curlies from end on last document
    s#\}\}\s*$##gs;
    # Make an easily searchable string, get rid of the RTF commands
    ( my $searchable  = $_ ) =~ s#(?:\\cell)x?-?\d*#     #gs;
    # ...and more...
         $searchable  =~ s#\\[a-zA-Z'*]+-?\d*\s?##gs;
    # Get rid of the curly braces as well
         $searchable  =~ s#[{}]##gs;
    # ...and all spaces more than one at a time
         $searchable  =~ s#\s+# #gs;
    # Grab the date and Person Number from $searchable
    my ( $month, $dom, $year, $pnbr ) = $searchable =~
      m<^\s*(\d{1,2})[-_/.](\d{1,2})[-_/.](\d+).*?MR#\s*(\d+)\s+>;


As you can see, that date figures prominently in my code -- it appears
four times in the snippet above.  Imagine my consternation when I
found out that this date can appear any one of several ways (this is
the actual text from RTF files):

{\b\insrsid15483745 08/02/2005\cell }
{\b\insrsid15483745 08/02/05\cell }
{\b\insrsid15483745 08/02/}{\b\insrsid16739478 2005\cell }
{\b\insrsid15483745 08/02/}{\b\insrsid16739478 05\cell }
{\b\insrsid15483745 08/}{\b\insrsid16739478 02/2005\cell }
{\b\insrsid15483745 08/}{\b\insrsid16739478 02/05\cell }
{\b\insrsid15483745 08/}{\b\insrsid16492297 02/}{\b\insrsid16739478
2005\cell }
{\b\insrsid15483745 08/}{\b\insrsid16492297 02/}{\b\insrsid16739478
05\cell }


My program works fine with the first two formats (it's built to handle
two- or four-digit years) but breaks on any of the latter six formats.
And these aren't even all of the possibilities, Word will sometimes go
so far as to split up each character into its own curly-brace group...
not to mention shuffling the slashes around.

I want to avoid coding a separate regex for each possible case --
dynamic searching is kind of the point of regexes, after all.  But I
can't figure out a way to make the regexes in my program simply
disregard any potential Microsoft garbage.  I've tried removing all of
those garbage format-commands (as I still do to get my $searchable
string), but then the RTF document doesn't display correctly in Word
unless I go in and edit the file by hand.

What am I missing?  I invite your suggestions and comments.  Am I
going about this entirely wrong?  Or is there some trick that I
haven't thought of that will elegantly do what I need?  I've looked at
the RTF parsing modules, but ended up rolling my own regex stuff when
I couldn't make heads or tails of how they should be used.  I
purchased Sean Burke's RTF Pocket Guide, and it is very helpful with
regard to the specification and how to write good RTF
programmatically.  But it basically says, "Parsing RTF files is beyond
the scope of this short book."  I really hope that some bright person
out there can show me my blind spot.

Thanks,

-Brian

_________________________
Brian H. Oak   CISSP CISA
Acorn Networks & Security
<http://acornnetsec.com/>


_______________________________________________
Perl-Win32-Users mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to