sub load_toc_before {
  my $fh = shift;
  my $toc = shift;
  while (<$fh>) {
    chomp;
    my ($depth, $secno, $title) = split /\s+/, $_, 3;
    my @nos = split /\./, $secno;
    my $cur = \$toc;
    while (@nos) {
      my $no = shift @nos;
      unless (ref $$cur) {
        $$cur = [$$cur];
      }
      if (@nos > 0) {
        $cur = \$$$cur[$no];
      } else {
        ($$cur)->[$no] = "$secno $title";
      }
    }
  }
  return $toc;
}

sub load_toc_after {
  my $fh = shift;
  my $toc = shift;
  while (<$fh>) {
    chomp;
    my ($depth, $secno, $title) = split /\s+/, $_, 3;
    my @nos = split /\./, $secno;
    my $ref = \$toc;
    while (@nos) {
      my $cur = $$ref;
      my $no = shift @nos;
      unless (ref $cur) {
        $cur = $$ref = [$cur];
      }
      if (@nos > 0) {
        $ref = \$cur->[$no];
      } else {
        $cur->[$no] = "$secno $title";
      }
    }
  }
  return $toc;
}

my $toc = load_toc(\*DATA, "Perl Advanced Techniques Handbook");

1;
1;
1;

__DATA__
0 1 Recursion
1 1.1 Decimal to Binary Conversion
1 1.2 Factorial
2 1.2.1 Why Private Variables are Important
1 1.3 Towers of Hanoi
1 1.4 Hierarchical Data
1 1.5 Applications and Variations of Directory Walking
1 1.6 Functional vs. Object-Oriented Programming
1 1.7 HTML
1 1.8 When Recursion Blows Up
2 1.8.1 Fibonacci Numbers
2 1.8.2 Partitioning
1 1.9 Elimination of Recursion
0 2 Dispatch Tables
1 2.1 Configuration File Handling
2 2.1.1 Tabular Configurator Configuration
2 2.1.2 Advantages of Dispatch Tables
2 2.1.3 Dispatch Table Strategies
2 2.1.4 Default Actions
1 2.2 Calculator
2 2.2.1 HTML Processing Revisited
1 2.3 State Tables
0 3 Caching, Memoization, and Lazy Computation
1 3.1 Caching Fixes Recursion
1 3.2 Inline Caching
2 3.2.1 Basic Caching Techniques
1 3.3 Good Ideas
1 3.4 Memoization
1 3.5 The Memoize Module
2 3.5.1 Scope and Duration
3 3.5.1.1 Scope
3 3.5.1.2 Duration
2 3.5.2 Lexical Closure
2 3.5.3 Memoization Again
1 3.6 Caveats
2 3.6.1 Functions Whose Return Values do not Depend on their Arguments
2 3.6.2 Functions With Side Effects
2 3.6.3 Functions that Return References 
2 3.6.4 Very Fast Functions
1 3.7 Key Generation
2 3.7.1 More Applications of User-Supplied Key Generators
2 3.7.2 Inlined Cache Manager with Argument Normalizer
2 3.7.3 Functions with Reference Arguments
2 3.7.4 Partitioning
2 3.7.5 Custom Key Generation for Impure Functions
1 3.8 Caching in Object Methods
2 3.8.1 Memoization of Object Methods
1 3.9 Persistent Caches
1 3.10 Alternatives to Memoization
1 3.11 Evangelism
1 3.12 The Benefits of Speed
2 3.12.1 Profiling and Performance Analysis
2 3.12.2 Automatic Profiling
2 3.12.3 Hooks
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
2 4.5.1 append
0 1 Recursion
1 1.1 Decimal to Binary Conversion
1 1.2 Factorial
2 1.2.1 Why Private Variables are Important
1 1.3 Towers of Hanoi
1 1.4 Hierarchical Data
1 1.5 Applications and Variations of Directory Walking
1 1.6 Functional vs. Object-Oriented Programming
1 1.7 HTML
1 1.8 When Recursion Blows Up
2 1.8.1 Fibonacci Numbers
2 1.8.2 Partitioning
1 1.9 Elimination of Recursion
0 3 Caching, Memoization, and Lazy Computation
1 3.1 Caching Fixes Recursion
1 3.2 Inline Caching
2 3.2.1 Basic Caching Techniques
1 3.3 Good Ideas
1 3.4 Memoization
1 3.5 The Memoize Module
2 3.5.1 Scope and Duration
3 3.5.1.1 Scope
3 3.5.1.2 Duration
2 3.5.2 Lexical Closure
2 3.5.3 Memoization Again
1 3.6 Caveats
2 3.6.1 Functions Whose Return Values do not Depend on their Arguments
2 3.6.2 Functions With Side Effects
2 3.6.3 Functions that Return References 
2 3.6.4 Very Fast Functions
1 3.7 Key Generation
2 3.7.1 More Applications of User-Supplied Key Generators
2 3.7.2 Inlined Cache Manager with Argument Normalizer
2 3.7.3 Functions with Reference Arguments
2 3.7.4 Partitioning
2 3.7.5 Custom Key Generation for Impure Functions
1 3.8 Caching in Object Methods
2 3.8.1 Memoization of Object Methods
1 3.9 Persistent Caches
1 3.10 Alternatives to Memoization
1 3.11 Evangelism
1 3.12 The Benefits of Speed
2 3.12.1 Profiling and Performance Analysis
2 3.12.2 Automatic Profiling
2 3.12.3 Hooks
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
2 4.5.1 append
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
2 4.5.1 append
0 4 Iterators
1 4.1 Introduction
2 4.1.1 
2 4.1.2 Other Common Examples of Iterators
1 4.2 C<walk_tree>
2 4.2.1 
1 4.3 Examples
2 4.3.1 Permutations
2 4.3.2 Genome Sequence Generator
2 4.3.3 Filehandle Iterators
2 4.3.4 A Flat-File Database
3 4.3.4.1 Improved Database
2 4.3.5 Random Number Generation
1 4.4 Alternatives to Iterators
1 4.5 Filters and Transforms
2 4.5.1 append
