Reputation:
In my program, I store the level of indentation seen in @indentation_stack
For example:
$line =~ /^(\s*)(if|elif|else|while)/
push(@indentation_stack, $1);
I then compare the level of indentation I see in a subsequent line to the level of indentation in the last element of the @indentation_stack
.
if ($line =~ /^(\s*)[^\s+]/) {
while (@indentation_stack && $1 le $indentation_stack[-1]){
print $indentation_stack[-1],"}\n";
pop @indentation_stack;
}
}
The idea is, if the indentation on a subsequent line is equivalent to the last element of the @indentation_stack
, I print a }
and a newline.
This works fine as long as indentations consist of spaces
. However, if I create the same level of indentation using \t
, my code does not work as intended.
EDIT:
If all spacing is consistent, either all \t
or all spaces
are used, then there is no problem. So I guess what I'm trying to work out is, how can I simply compare space. That is a \t
may be equivalent to a number of spaces
.
Would anyone know why this is happening?
Thank you for your help.
Upvotes: 2
Views: 105
Reputation: 414
The problem with tabs versus spaces is an old one with no answer, pick one and be consistent as mixing the two is bad. Different editors may display tabs as differing numbers of spaces and even dynamically within a single file relative to their context.
Thus a lot of editors, emacs is the one I know about, offer ways to automatically convert tabs to spaces for you and only insert spaces when you hit tab.
In addition your program could take tabs to be a certain number of spaces though this will probably need a conversion of tabs to spaces throughout all lines not just those you're generating. Unless you want to do a kind of mixed representation or convert to the closest tab spacing - this is a lot of complexity for little reason though.
Upvotes: 3
Reputation: 386396
Are you asking how to calculate the visible length of tabs? Tabs move the cursor to the next tab stop.
use constant TAB_STOP => 4;
sub indent_size {
my ($s) = @_;
my $i = 0;
while ($s =~ /\G([ \t])/g) {
$i += $1 eq "\t" ? ( TAB_STOP - ($i % TAB_STOP) ) : 1;
}
return $i;
}
if (my ($indent) = $line =~ /^([ \t]+)[^ \t\n]/) {
my $indent_size = indent_size($indent);
while (@indent_stack && $indent_size <= indent_size($indent_stack[-1])) {
print pop(@indent_stack), "}\n";
}
}
It would be more efficient to store the indent and its length in the stack.
Upvotes: 1