http://www.perlmonks.org?node_id=455756

eric256 has asked for the wisdom of the Perl Monks concerning the following question:

I've got a project that I'm not sure how to attack. The question isn't specificaly perl, but the implementation is going to be perl sooo... there you have it.

Short story is I have a file with X's in it where information should be inserted. I'm going to have to look at the location of the X's in relation to a printed form I have to determine what goes where. So I would like to find some method of either filling in the existing "template" I was given OR produce a template that looks like it but with named feilds to fill in. So far so good and nice and easy. My only problem then is that many many of the feilds are single character feilds. I would like whatever template engine I use, and consequently whatever template, to look as close to the original as possible in the spaceing area. So single character feilds need to either have single digit names, or something else. I'm asking hoping someone with more experience with this kind of templateing will have help for me! Below is a sample of the "template" I was given for what its worth. I'm considering now building a seperate file with width based definitions of each line, but that will be hard to visualy tie back to my source document. Hopefully I haven't lost everyone at this point. Any help at all, even telling me to shut up and build a line by line definition, would be greatly appreciated.

XXXXXXXXXXXXXXX +XXXXXXX X X X X X X X XXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXX X XX XX XX X X XXXXXXXXXXXXXXXX XXXX +XXXXX X XXXXXXXXXXXXXXXXXXXXXXXXX X X X X XXXXXXXXXXXXXXXXXXXXX +XXXX

P.S. yes I know it is a mess, but sometimes you just have to work with what you are given. ;)


___________
Eric Hodges

Replies are listed 'Best First'.
Re: Picking a Template Engine/Method
by holli (Abbot) on May 10, 2005 at 21:22 UTC
    ... that will be hard to visualy tie back to my source document.
    True. But you could write a tool that translates your description file into the X-format, and compare that output with your original.

    just 2 cents


    holli, /regexed monk/

      Thanks! I think that might be just the outside perspective I needed. I wanted to be able to test my output agianst there expected and that would work perfectly.


      ___________
      Eric Hodges
Re: Picking a Template Engine/Method
by eric256 (Parson) on May 10, 2005 at 22:51 UTC

    Thanks for the replies. hollie's reply sent me down what I hope will be the right path. I am defining the layout line by line in a perl data structure that is mostly human readable.

    1 => [ [50, 26, "Ins Company Name" , ""]], 2 => [ [50, 26, "Ins Street Address" , ""]], 3 => [ [50, 26, "Ins Street Address 2", ""]], 4 => [ [50, 12, "Ins City" ,""], [64, 2, "Ins State",""], [67, 5, "Ins Zip" ,""], ], 6 => [ [57, 22, "Unknown", ""]], 8 => [ [ 1, 1, "Medicare" ,"" , '1'], [ 8, 1, "Medicade" ,"" , '1'], [15, 1, "Champus" ,"" , '1'], [24, 1, "Champva" ,"" , '1'], [31, 1, "Group Health Plan" ,"" , '1'], [39, 1, "FECA BLK LUNG" ,"" , '1'], [45, 1, "Other" ,"" , '1'], [50, 17, "Insured's I.D. Number" ,"" , '1a'], ],

    I then wrote a fairly simple script that translates this into the X format for comparison/verification pourposes. Here is my quick little script which will be refined some more.

    my $hcfa = do "hcfa.lay"; my $layout = []; foreach my $line ( sort keys %$hcfa ) { foreach my $item ( @{$hcfa->{$line}} ) { insert_into_layout($layout, $line, $item->[0], "X" x $ +item->[1]); } } print layout_form($layout); sub insert_into_layout { my ($layout, $line, $row, $value) = @_; my @data = split //, $value; my $offset = 0; foreach ( @data ) { $layout->[$line][$row + $offset++] = $_; } } sub layout_form { my $layout = shift; my $output; foreach my $row (@$layout) { foreach my $val (@$row) { $output .= (defined $val ? $val : ' '); } $output .= "\n"; } return $output; }

    I plan on linking the 4th feild in that definition file to the database in some as yet undefined way. Maybe coderefs in some cases and plain scalars of the database feild in others. Either way I think this gets the best of both worlds. Thanks agian!


    ___________
    Eric Hodges
Re: Picking a Template Engine/Method
by DrWhy (Chaplain) on May 10, 2005 at 21:19 UTC
    Seems like you might be able to use a Perl format to attack this problem. It sounds like what you want in terms of the look of your template is very close to what the 'picture' lines in a template look like.

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

Re: Picking a Template Engine/Method
by dynamo (Chaplain) on May 10, 2005 at 21:24 UTC
    If it's really only <10 lines or so, as you post above, I suggest building another template, line-by-line, verbosely.

    As for a system to use, this is one of those times I think you might actually want to use perl's built-in format system, with the template lines etc..

    See perlman:perlform.

      Or look at the Perl6::Form module.
Re: Picking a Template Engine/Method
by holli (Abbot) on May 10, 2005 at 21:18 UTC
    Shut up and build a line by line definition.


    *g*, sorry. Too good to resist. ;-)


    holli, /regexed monk/
Re: Picking a Template Engine/Method
by Adrade (Pilgrim) on May 10, 2005 at 21:36 UTC
    Ya know... I think I misunderstood the question... I'm leaving my orig response tho

    A response to the correct question I've included as a reply to this msg :-)
      -Adam
      Since I misinterpreted the question, I thought I'd offer another reply... $form would hold the data loaded in from file. An array called @data would hold the stuff you want to load into the Xs. The following hacky way of doing a format is suggested by perlform.
      $form = <<"EOF"; XXXXX XXXXX XXXX XX XX XXXXX X XXXX XXXX XXX EOF @data = qw/one two three four five six seven eight nine ten/; $form =~ s/\bX/\@/sg; $form =~ s/X/</sg; my $totalcount = 0; my $format = "format STDOUT = \n"; foreach (split(/\n/,$form)) { $format .= $_."\n"; (@c) = (m/([@<]+)/g); $format .= '$data['.$totalcount++.'],' for 0..$#c; $format =~ s/,$//s; $format .= "\n"; } $format .= "."; eval $format; write;

      This would produce this output:
      one       two   thre
        fo fi     six
      s    eigh    nine   ten
      


      Hopefully having repented for my error, I hope that helps!

        -Adam