makepp

 view release on metacpan or  search on metacpan

makeppgraph  view on Meta::CPAN

}
sub SELF() { '' }		# Impossible node name used for own attributes.

my $home = absolute_filename dereference file_info $ENV{HOME};
$datadir = absolute_filename dereference file_info $datadir;


package Mpp::Rewrite;

# Reduce any file (except dirs) to the containing directory.
sub dir() { defined and $_ ne '' and -d || s!/[^/]+$!! || s!^(\|\w+\|).*!$1! }

# Replace your home directory with '~'
sub home() { defined and s/^$home/~/ }

# Replace makepp dir with abbreviation |m|.
sub makepp() { defined and s!^$Mpp::datadir(?:/|$|(?=:))!|m|! }

# Replace basename including dir or optionally only part of dir with '*'
sub suf(;$) {
  no warnings 'uninitialized';
  if( !defined $_[0] ) {
    s!.+ (\.[^/.]+) $!*$1!x;
  } elsif( !$_[0] ) {
    s!^ ([/~|]?) .+ (\.[^/.]+) $!$1*$2!x;
  } elsif( $_[0] > 0 ) {
    my $n_1 = $_[0] - 1;
    s!^ (\|\w+\| | [/~]?[^/]*/ )? ((?:[^/]+/){0,$n_1}) .+ (\.[^/.]+) $!$1$2*$3!x;
  } else {
    my $n_1 = -1 - $_[0];
    s! (?: ^\|\w+\| | ^/(?:[^/]+/)? | ^~[^/]*/ | [^|/]+/ )? (?:[^/]+/){0,$n_1} [^/]+ (\.[^/.]+) $!*$1!x;
  }
}

# Replace common system dirs with abbreviation.
sub usr() {
  no warnings 'uninitialized';
  s!^/(?:(?=(.))(?:opt|usr)/(?:(?=(.))(?:local|X11R?[67]?)/)?)?(?=(.))(?:bin|etc|include|lib|share)(?:/|$)!|$1$2$3|!;
}



sub merge($$$$) {
  return if !/([^\/]+)$_[2]$/;
  my $basename = $1;
  for( keys %{$_[0]} ) {
    if( /(?:.*\/)?\Q$basename\E$_[3]$/ ) {
      delete $_[0]{$_};
      return ["$_$_[1]", $_];
    }
  }
}

# .o in any dir depending on a C or C++ source
sub c2o($) { merge $_[0], '>o', qr/\.o(?:bj)?/, qr/\.(?:c(|[xp+])\1|cc|CC?)/ }

# basename or .exe in any dir depending on same .o file
sub exe($) { merge $_[0], '*', qr/(?:\.exe)?/, qr/\.o/ }

# Same name in different directories, like headers published to a central include dir.
sub x2($) { merge $_[0], '*2', '', '' }



package Mpp;



# Styles which can be overridden.
our %head = ( dot => <<EOSdot, html => <<EOShtml, txt => '', udg => "[\n" );
// Generated by makeppgraph
digraph a {
rankdir=LR
outputorder=edgesfirst
node [shape=box style=filled fillcolor="#ffffffe0"]
edge [dir=back]
EOSdot
<html>
<meta name='generator' content='makeppgraph' />
<style>
a { border: 1px dotted #bbb; padding-left: 1ex; padding-right: 1ex; }
b { font-weight: normal; border: 1px solid; padding-left: 1ex; padding-right: 1ex; }
ul ul { border-left: 1px dotted #bbb; }
ul { margin: 0; padding-left: 1em; }
li { list-style: square; padding: 0; padding-top: 3px; }
li.fold { list-style: disc; }
li.fold > b { cursor: n-resize; }
li.unfold { list-style: circle; }
li.unfold > b { cursor: s-resize; }
.flash { background-color: yellow; }
/* Actually show and hide sublists */
li.fold ul { display: block; }
li.unfold ul { display: none; }
</style>
<script>
// Inspired by Stuart Langridge, www.kryogenix.org/code/browser/aqlists/
function foldify( ul ) {
  if( !ul.childNodes || ul.childNodes.length == 0 ) return;
  // Iterate LIs
  for( var itemi = 0; itemi < ul.childNodes.length; itemi++ ) {
    var item = ul.childNodes[itemi];
    if( item.nodeName == "LI" ) {
      // Iterate things in this LI
      var b;
      for( var sitemi = 0; sitemi < item.childNodes.length; sitemi++ ) {
        var sitem = item.childNodes[sitemi];
        switch( sitem.nodeName ) {
          case "B": b = sitem; break;
          case "UL": foldify(sitem);
            item.className = 'fold';
            b.title = 'click to (un)fold, double click to unfold all';
            b.onclick = function() {
              this.parentNode.className = (this.parentNode.className=='fold') ? 'unfold' : 'fold';
              return false;
            };
            b.ondblclick = function() {
              foldify( this.parentNode.parentNode.getElementsByTagName( "ul" )[0] );
              return false;
            };
        }
      }



( run in 1.190 second using v1.01-cache-2.11-cpan-13bb782fe5a )