This short snippet will number headings of a file formatted with standard Emacs Outline Mode (yes, I know there is allout.el).
#!/usr/bin/perl -w -p s/^(\*+)/ $n = length($1), $n < $o ? @l[$n+1..$#l] = (0)x($#l-$n) : 0, $l[$n]++, $o = $n, join(".",@l[1..$n]) /e;

Replies are listed 'Best First'.
Re: Emacs Outline Mode Header Numbering
by merlyn (Sage) on May 31, 2001 at 20:11 UTC
    !/usr/bin/perl -w -p s/^(\*+)/ $n = length($1), $n < $o ? @l[$n+1..$#l] = (0)x($#l-$n) : 0, $l[$n]++, $o = $n, join(".",@l[1..$n]) /e;
    The item on the right of an s///e is a full block, so you don't need to haggle it all into a single expression. Thus, using a more natural coding style, this would be:
    !/usr/bin/perl -w -p s { ^(\*+) # look for stars at the beginning of line }{ my $n = length($1); # get number of stars @l[$n+1..$#l] = (0)x($#l-$n) if $n < $o; # @l is global $l[$n]++; $o = $n; # $o is global join(".",@l[1..$n]); # returning this }ex;
    I see a possibility (I think) of having only one global rather than two, but I'm not quite ready to rewrite that yet... just wanted to show the isomorphic equivalent of your code in a cleaner syntax.

    -- Randal L. Schwartz, Perl hacker

      Sure, you can get by with one global by using the empty first place in the global @l.

      #!/usr/bin/perl -w -p s/^(\*+)/ # use only one global by using empty first place in @l my $n = length($1); $n < $l[0] ? @l[$n+1..$#l] = (0)x($#l-$n) : 0; $l[$n]++; $l[0] = $n; join(".",@l[1..$n]); /e;

      Christian Lemburg
      Brainbench MVP for Perl
      http://www.brainbench.com

Re: Emacs Outline Mode Header Numbering
by clemburg (Curate) on Jun 19, 2001 at 13:54 UTC

    And this snippet reverses the actions of the snippet above, converting numbered headlines to outline mode header level indicators.

    #!/usr/bin/perl -p if (/^((\d+\.)*\d+)/) { my $h = $1; my $l = ($h =~ tr/././) + 1; s/^((\d+\.)*\d+)/'*' x $l/e; }

    Christian Lemburg
    Brainbench MVP for Perl
    http://www.brainbench.com