Use a tool designed for the job. It looks like you may be generating XML, perhaps by parsing some lightly marked up, sorta HTML, source. So lets go with that for a moment and see what can be done:
use strict;
use warnings;
use XML::Twig;
my $twig = new XML::Twig (pretty_print => 'record');
my $root = new XML::Twig::Elt ('root');
$twig->set_root ($root);
my @pendingSections;
while (<DATA>) {
chomp;
if (/<h(\d+)>(.*)/i) {
# deal with a header line
# First pop any pending sections that need to be closed
pop @pendingSections while @pendingSections > $1;
while (@pendingSections < $1) {
# Add section elements out to current header level
my $level = @pendingSections + 1;
my $elt = new XML::Twig::Elt ("section$level");
if ($level == 1) {
$elt->paste (last_child => $root);
} else {
$elt->paste (last_child => $pendingSections[-1]);
}
push @pendingSections, $elt;
}
my $headElt = new XML::Twig::Elt ("head", $2);
$headElt->paste (last_child => $pendingSections[-1]);
} else {
# It's a paragraph
if (@pendingSections) {
$pendingSections[-1]->suffix ("$_\n");
} else {
$root->suffix ("$_\n");
}
}
}
$twig->print ();
__DATA__
<h1>Heading level 1
<h2>Heading level 2
<h3>Heading level 3
<h2>Heading level 2
<h1>Heading level 1
paragraph here
paragraph here
Prints:
<root>
<section1>
<head>Heading level 1</head>
<section2>
<head>Heading level 2</head>
<section3>
<head>Heading level 3</head>
</section3>
<head>Heading level 2</head>
</section2>
<head>Heading level 1</head>paragraph here
paragraph here
</section1>
</root>
which isn't quite what you showed (especially the root element), but does do the parsing/rendering magic it seems you may be after.
DWIM is Perl's answer to Gödel
|