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

I have an app where I am searching a Tk::TextUndo widget for string literals (" and ') and formatting the text if found. The problem is I have accounted for the escape character (\) and everything works fine unless there is escaped quoted text using either single or double quotes on the same line as quoted text of another quote character (if " was used in escape then ' is the problem and vise versa).

Here is the code snippet:

my @quotes = qw(" '); foreach my $word (@quotes) { my ($line, @found, $char, $beg, $last, $escape); my $word_len = length $word; my $next = $start; while (my $from = $t->search(-regexp, "$word", $next, $end)) { $next = "$from + $word_len chars"; my ($good, $trash) = split(/\./, $from); my $comment = $t->search( -regexp => $Comment, "$from linestart" => "$from lineend"); my $comment2 = $t->search(-regexp => $Comment2, "$from linestart" => "$from lineend"); @found = split(//, $data[$good - 1]); $char = 0; $escape = 0; foreach my $chars (@found) { $escape = 1 if ($chars eq "\\"); $last = $good.".".($char + 1) if (($chars =~ /$word/) && ($be +g) && ($escape != 1)); $beg = $good.".".$char if (($chars =~ /$word/) && (!$beg) && + ($escape != 1)); $escape = 0 if (($escape == 1) && ($chars =~ /$word/) || ($ch +ars =~ /\w+/)); if (($beg) && ($last)) { unless($comment and $t->compare($comment, '<', $beg)) { unless($comment2 and $t->compare($comment2, '<', $beg)) + { unhighlight_range($t, $beg, $last); mark_word($t, $beg, $last, 'String'); } } undef $beg; undef $last; } $char++; } undef $beg; undef $last; } }
Using the above code the following examples can be seen.

Ex:

"some text" not quoted 'this is'

the above example works fine but the following has issues.

Ex:

"some \"text\"" 'this is suppose to be'

Now that example does not quote the single quoted text but the following does.

Ex:

"some \"text\"" This makes it ok 'this is suppose to be'

Any ideas from looking at the code? I know it has to do with the value of $escape and whether or not $last and $beg have a value and when they get undefined but I am having trouble pinpointing it.

Oh and yes I know I need to take into account the other quoting methods such as qw() and such but I need this worked out first.


www.perlskripts.com

Replies are listed 'Best First'.
Re: Tk $widget->search() issues?
by eserte (Deacon) on Aug 11, 2004 at 10:41 UTC
    I don't know whether the search() method uses the Perl regexp engine or a Tcl regexp engine, and/or if there are any Tcl-ish quoting conventions left-over. My advice: try to match with a normal perl regexp on $text->get("1.0","end"). If it works there, then it's a problem with the regexp engine in search().
Re: Tk $widget->search() issues?
by zentara (Cardinal) on Aug 11, 2004 at 13:22 UTC
    I'm having a hard time getting a "grasp" on your problem, I'm in "fuzzy" mode this morning. But this is what pops into my head, and maybe it will help you.

    The search method allows for a "kind" of search, either 'exact' or 'regexp', and maybe you can use that to your advantage. Have you looked at the widget demo, for " A search tool built with a text widget" ? It has a great sub:

    sub search_text { # The utility procedure below searches for all instances of a give +n # string in a text widget and applies a given tag to each instance + found. # Arguments: # # w - The window in which to search. Must be a text widget. # string - Reference to the string to search for. The search i +s done # using exact matching only; no special characters. # tag - Tag to apply to each instance of a matching string. # kind rexexp or exact my($w, $string, $tag, $kind) = @_; return unless ref($string) && length($$string); $w->tagRemove($tag, qw/0.0 end/); my($current, $length) = ('1.0', 0); while (1) { $current = $w->search(-count => \$length, "-$kind", $$string, $cur +rent, 'end'); last if not $current; warn "Posn=$current count=$length\n", $w->tagAdd($tag, $current, "$current + $length char"); $current = $w->index("$current + $length char"); } } # end search_text

    Maybe you could compare the search results between exact and regexp, and filter according to your needs?


    I'm not really a human, but I play one on earth. flash japh