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

I wrote a script for a website I am making that allows writers of the website to post articles without having to actually open of the files of the web site. I made a web page that has a text area where they can submit there work. Then at the Web site when you click on a link to the article it will use a script to open to textfile and show it on the page 45 lines at a time with a link ot the next 45 lines(so it can fit in the page). But recently I realized a problem, if you copy and paste alot of text into the textarea it messes the program up since the program splits the lines up by seperating \n charcters. Any ideas?

Jemts

"If you're traveling in a time machine, and you're eating corn on the cob, I don't think it's going to affect things one way or the other. But here's the point I'm trying to make: Corn on the cob is good, isn't it."

Replies are listed 'Best First'.
Re: Posting Program
by vladb (Vicar) on May 25, 2002 at 16:52 UTC
    You may also consider splitting your text into separate sentences rather than lines. I believe this should make even more sense if you display an article across multiple pages. This way, you won't end up splitting a sentence in the middle etc.

    The module that would let you do this is Lingua::EN::Sentence. I have already used the module in a few applications of my own to great success. For example, to spilt a piece of text in chunks of 45 sentences each, you could do the following:
    use strict; # DO THIS! (by the way, you missed that one..) use warnings; # haha and that too.. use Lingua::EN::Sentence; my $page_sentence_count = 45; # 45 sentences per page! my $sentences=get_sentences($text); ## Get the sentences. for (my $scount = 0; $scount < scalar @$sentences; $scount++) { unless ($scount % $page_sentence_count) { print "Next page!\n"; # do whatever you want here (say, open next file etc) } print $sentences->[$scount] . "\n"; }
    Disclaimer: code not tested (couldn't test it well on this box)

    UPDATE: In reply to Re:Re:Posting Program
    Ahh, for that, just use the set_EOS() method of the module to specify a new 'end-of-sentence' string.

    _____________________
    $"=q;grep;;$,=q"grep";for(`find . -name ".saves*~"`){s;$/;;;/(.*-(\d+) +-.*)$/; $_=["ps -e -o pid | "," $2 | "," -v "," "];`@$_`?{print"+ $1"}:{print" +- $1"}&&`rm $1`; print$\;}
      The page I am printing to has a width limit of 100 characters, at font size 2. So there could be more than one sentence per line.

      Jemts

      "If you're traveling in a time machine, and you're eating corn on the cob, I don't think it's going to affect things one way or the other. But here's the point I'm trying to make: Corn on the cob is good, isn't it."
Re: Posting Program
by DigitalKitty (Parson) on May 25, 2002 at 16:03 UTC
    Hi.

    Could you post your code? This sounds like a good idea.

    Thanks,
    -DK
      here is the code for the program that reads the textareea and prints it into a file:
      #!/usr/local/bin/perl ############################## #Post article of information # # by Matthew Manela # ############################## require 'subparseform.lib'; # sub parsing $basedir = "/data1/blah.net/blah/"; $baseurl = "http://blah.blah.net"; &Parse_Form; print "Content-type: text/html\n\n"; $tpass=$formdata{password}; $article=$formdata{text}; $destination=$formdata{destination}; #the source of the file to write to @info=split(/\n/,$article); # set $file to location of txt file $file="$basedir$destination\.txt"; # make sure destination is within parameters if($destination=~/^([a-zA-Z])+$/){ &main; }else{ &filename; } sub main{ if(-e $file){ open(WRITE, ">$file")|| &filename; foreach $line (@info){ print WRITE "$line\n"; } close(WRITE); }else{ &filename; } sub filename{ print"You can't write to that file!\n"; exit; }
        Ouch. There are many things here you need to look at, but to get you going:
        • it's &nbsp; with a semi-colon
        • your ssi check only removes includes - what about the other ssi calls? use generic instead
        • use CGI and strict
        • know when to use an array and when to use a scalar
        • sub &main is not needed

        Here is a quick rewrite (untested) of the above code. Please ask if there's anything you don't understand.

        #!/usr/local/bin/perl -w use strict; use CGI; my $basedir = "/data1/blah.net/blah/"; my $baseurl = "http://blah.blah.net"; my $q=CGI::new(); my $tpass = $q->param('password'); my $article = $q->param('text'); my $destination = $q->param('destination'); # set $file to location of txt file my $file="$basedir$destination\.txt"; # strip out all possible SSI calls here, not below (ie, remove all com +ments) $article =~ s/<!--.*?-->//gis; # make sure destination is within parameters (allow underscores as wel +l if ($destination !~ /^\w+$/){ &filename; } # ?? only overwrite existing file? If so use -T instead # if(-e $file) if(-T $file) { open(WRITE, ">$file") || &filename; print WRITE "$line\n"; close(WRITE); } else { &filename; } sub filename{ print $q->header, $q->start_html, $q->h4("Error: You can't write to that file!"), $q->end_html; exit(0); } ###################################################################### +# #!/usr/local/bin/perl-w use strict; use CGI; my $q = CGI::new(); my $basedir = "/data1/blah.net/blahs/"; my $baseurl = "http://blah.blah.net"; my $article = $q->param('article'); my $page = $q->param('page'); my $maxlength = 43; my $next = $page+1; my $previous = $page-1; my $start = ($page-1)*$maxlength; my $finish = $page*$maxlength; my $file="$basedir$article\.txt"; open(TOP, "$basedir/top\.htm")|| &filename; my $top= join '',(<TOP>); close(TOP); open(BOTTOM, "$basedir/bottom\.htm")|| &filename; my $bottom = join '', (<BOTTOM>); close(BOTTOM); open(READ, "$file")|| &filename; my @info = (<READ>); close(READ); $length=@info; $top =~ s|</head>|<base href="http://blah.blah.net"></head>|is; print $q->header, $top; print $q->header, $q->start_html, $info[$start..$finish]; # note, this -> $info[$start..$finish]; may not work - it's late and s +eemed like a good idea :) if ( ($length>$finish) && ($page>1) ) { print $q->p("&nbsp;&nbsp;", $q->font({-color=>'yellow'}, '<--&nbsp;' ), $q->a({-href => "http://blah.blah.net/cgi-bin/article. +cgi?article=$article&page=$previous"}, 'Go to the previous page' ), $q->a({-href => "http://blah.blah.net/cgi-bin/article. +cgi?article=$article&page=$next"}, 'Continue to the next page' ), $q->font({-color=>'yellow'}, '&nbsp;-->' ) ); } elsif ( ($length>$finish) && ($page==1) ) { print $q->p({-align => 'right'}, $q->a({-href => "http://blah.blah.net/cgi-bin/article. +cgi?article=$article&page=$next"}, 'Continue to the next page' ), $q->font({-color=>'yellow'}, '&nbsp-->' ) ); } print $bottom, $q->end_html; exit(0); sub filename{ print $q->header, $q->start_html( -title => 'Article does not exist'), $q->p('Sorry, That article does not exist), $q->end_html; exit(0); }

        This is by no means how I would write this, but I hope you will take the time to look up the CGI docs and use it in future. It's a lot better than trusting your own sub!

        This should keep you going for now...

        As to your characters per line issue, you don't state whether paragraph breaks are needed. Here's a hint anyway for the first script:

        $article =~ s/\s+/ /gs; $article =~ s|([^\n]\b{0,100})|$1<br/>|gs;

        hth

        cLive ;-)

        --
        seek(JOB,$$LA,0);