in reply to Re: Converting HTML tags to upper case
in thread Converting HTML tags to upper case

I have taken what cdarke has advised on board and tried to break it down into 6 small chunks:

# 1 - Prompt the user to enter the filename .

#2 - Verify the file extension to make sure it's htm or html.

#3 - Open the file and read each line of the file.

#4 - Change all tags to uppercase.

#5 - Tag attributes need to remain in lowercase.

#6 - Original file needs renaming with the .old extension and the processed file needs the original filename.

This is what I've got so far (not a great deal of progress).

#1

Print ("Please enter the name of your html file\n"); $file = (<STDIN>);

#2

(I have the following regular expression) ($file =~ s/html|htm$/i).

Would I be best putting this in an IF statement ?.

#3 & #4

open (IN, $file); open (OUT, >$file); while ($line = [IN]) { $line =~ s/[html]/[HTML]/;<code> # Would I have to do the above line for all possible tags or is there +an easier way ?. <code>(print OUT $line); }
Struggling on part #5 !.

#6

Got the feeling I'm going to need to use something like the following.

rename $file, "$file.old"; open (IN, "<$file.old"); Open (OUT, ">$file");

Replies are listed 'Best First'.
Re^3: Converting HTML tags to upper case
by wfsp (Abbot) on Dec 12, 2006 at 13:50 UTC
    Here's my stab at #4 and #5.

    It uses HTML::TokeParser::Simple as suggested by marto above. If there is HTML in the air I won't leave home without it. :-)

    #!/usr/bin/perl use strict; use warnings; use HTML::TokeParser::Simple; my $file = 'home.html'; my $p = HTML::TokeParser::Simple->new($file); my $html; while (my $t = $p->get_token){ if ($t->is_start_tag){ my $tag = '<'. uc $t->get_tag; my $attr = $t->get_attr; my $inline; for my $name (keys %{$attr}){ $inline++, next if $name eq '/'; my $name_value = sprintf " %s=\"%s\"", uc $name, lc $attr->{$nam +e}; $tag .= $name_value; } $tag .= ' /' if $inline; $tag .= '>'; $html .= $tag; } elsif ($t->is_end_tag){ my $tag = sprintf "</%s>", uc $t->get_tag; $html .= $tag; } else{ $html .= $t->as_is; } } print $html;
Re^3: Converting HTML tags to upper case
by talexb (Chancellor) on Dec 12, 2006 at 14:35 UTC

    Some quick comments ..

    • In the UNIX/Linux world that Perl mostly lives in, it is more likely that the file name you'll be working on will be passed in as an argument, rather than supplied interactively, in response to a prompt. This allows us to do clever things like find the files we want to work on (perhaps by using ls and xargs and then call your utility.
    • Figure out a plan for what your file names are going to be. Typically you would do something like this: original file is renamed by adding '.org' or '.orig' to it (for original), and a new file is created with the original file name. Alternatively, '.org' can be '.bak' (for backup).
    • You asked Would I have to do the above line for all possible tags or is there an easier way, and the answer is, yes, use one of the modules suggested to you already. Parsing HTML with a regular expression is a tempting challenge, but it's a fool's errand. That means don't try to do it unless you want a Greek chorus chanting "Don't do that!" when you come and ask for assistance.
    • There's no rename command in UNIX/Linux -- we use mv (move) instead, and if you're going to be copying, moving or renaming files, best use File::Copy instead, for the following reasons:
      • It's tried and true code.
      • It works on multiple platforms.
      • it will handle all of the weird cases that you never thought of but will wake you at 4am if your homebrew code gets installed on a Production machine and it breaks in the worst possible way.
      • You won't have a Greek chorus chanting "Use CPAN" all the time. Actually, File::Copy is a core module, so you don't even have to go to CPAN for it.

    There's a lot to learn, so search for articles here on Perlmonks and do lots of reading. 99% of the time, the thing you want to do has already been thought of and coded up. It's amusing to reinvent the wheel, but only do so if you have plenty of time to learn.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

Re^3: Converting HTML tags to upper case
by ww (Archbishop) on Dec 12, 2006 at 14:35 UTC
    Bern: In keeping with your description of your experience, here's a rather basic trick you may find useful

    Re #2 - One good way to spoeed your learning is to run such constructs through a "try-out." Here's a fairly simply way to do so (using one specific bit of your proposed code):

    my @files = ("foo.htm","two.htm","three.HTM","FOUR.HTML"); # etc etc for as many variants as you like foreach $file(@files) { if ($file =~ s/html|htm$/i) { print $file; } }

    (What's happening above is that we're stuffing a variety of possible names into an array, which makes for an easy, compact way to check them all.)

    and then tell perl to run a check ( -c ):

    >perl -c bern.pl
    Substitution replacement not terminated at bern.pl line 6. >

    Now, Perl has told you there's something wrong with that scheme (Hint: You've said you're checking to make sure the file has an .htm or .html extension. So why are you using substitution ( s/// )? Perhaps that's an "aha" moment. We don't want to substitute in the test (and yes, we do need that if in order to test without being sensitive to case).

    So what happens if we edit the script to test for a MATCH instead of attempting substitution?

    my @files = ("foo.htm","two.htm","three.HTM","FOUR.HTML"); # etc etc +for as many variants as you like foreach $file(@files) { if ($file =~ /html|htm$/i) { print $file; } }

    Now, it passes the check... and running the script does this:

    >perl bern.pl
    foo.htmtwo.htmthree.HTMFOUR.HTML >

    Well, ugly, but "yep" -- all four bits of test data matched either htm or html.

    So we're done, right? BRRRRRRRRAATTTTTT!
      NO!

    Let us suppose some evil user (and if you don't think "evil user" is redundant, beware!) tried to foist a file like "oneHTML.xyz" on you? Well, try it!

                (...short pause while you do so)

    OK, so now we know the test works in part, but not well enough to do what you want -- that is, not well enough to restrict the acceptable files to those with an extension of .htm, .html, .HTM or .HTML (though your trailing "i" does provide the case insensitivity you probably want in the uploaded filename.)

    That means it's time to read some more; say, for example, perldoc perlretut or one of the many nodes here on regular expressions. And then, just for the record, the advice you'll see frequently in what you read here, "Don't use regexen to parse html," refers to the NEXT step of your journey. Using a regex is just fine (at least IMO) to test a filename.