+ $cached{$path} = [ [ ], undef, undef ] if $use_cache;
+
+ my $linenr = 0;
+ my $source = '';
+
+ local *SOURCE;
+ open SOURCE, '<', $path or return $level
+ ? qq{\cQ; die qq[Can't open "\Q$path\E" (\Q$!\E)]; print q\cQ}
+ : qq{\n#line $linespec\ndie qq[Can't open "\Q$path\E" (\Q$!\E)];};
+
+ LINE:
+ while (defined (my $line = <SOURCE>)) {
+ $linenr++;
+ for (;;) {
+ $line =~ /
+ \G # Begin where left off
+ ( \z # End
+ | <:=? | :> # PLP tags <:= ... :> <: ... :>
+ | <\([^)]*\)> # Include tags <(...)>
+ | <[^:(][^<:]* # Normal text
+ | :[^>][^<:]* # Normal text
+ | [^<:]* # Normal text
+ )
+ /gxs;
+ next LINE unless length $1;
+ my $part = $1;
+ if ($part eq '<:=' and not $in_block) {
+ $in_block = 2;
+ $source .= "\cQ, (";
+ } elsif ($part eq '<:' and not $in_block) {
+ $in_block = 1;
+ $source .= "\cQ; ";
+ } elsif ($part eq ':>' and $in_block) {
+ $source .= (
+ $in_block == 2
+ ? "), q\cQ" # 2
+ : "; $PLP::print q\cQ" # 1
+ );
+ $in_block = 0;
+ } elsif ($part =~ /^<\((.*?)\)>\z/ and not $in_block) {
+ my $ipath = File::Spec->rel2abs(
+ $1, File::Basename::dirname($path)
+ );
+ $source .= source($1, $level + 1, undef, $ipath) .
+ qq/\cQ, \n#line $linenr "$file"\nq\cQ/;
+ push @{ $cached{$path}[0] }, $ipath;
+ } else {
+ $part =~ s/\\/\\\\/ unless $in_block;
+ $source .= $part;
+ }
+ }
+ }
+
+ if ($in_block) {
+ $source .= (
+ $in_block == 2
+ ? "), q\cQ" # 2
+ : "; $PLP::print q\cQ" # 1
+ );
+ }