⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blackbox.pm

📁 source of perl for linux application,
💻 PM
📖 第 1 页 / 共 5 页
字号:
        $para->[0] = 'Para';        $para_type = '?Plain';      } elsif($para_type eq 'Data') {        $para->[0] = 'Data';        $para_type = '?Data';      } elsif( $para_type =~ s/^=//s        and defined( $para_type = $self->{'accept_directives'}{$para_type} )      ) {        DEBUG > 1 and print " Pondering known directive ${$para}[0] as $para_type\n";      } else {        # An unknown directive!        DEBUG > 1 and printf "Unhandled directive %s (Handled: %s)\n",         $para->[0], join(' ', sort keys %{$self->{'accept_directives'}} )        ;        $self->whine(          $para->[1]{'start_line'},          "Unknown directive: $para->[0]"        );        # And maybe treat it as text instead of just letting it go?        next;      }      if($para_type =~ s/^\?//s) {        if(! @$curr_open) {  # usual case          DEBUG and print "Treating $para_type paragraph as such because stack is empty.\n";        } else {          my @fors = grep $_->[0] eq '=for', @$curr_open;          DEBUG > 1 and print "Containing fors: ",            join(',', map $_->[1]{'target'}, @fors), "\n";                    if(! @fors) {            DEBUG and print "Treating $para_type paragraph as such because stack has no =for's\n";                      #} elsif(grep $_->[1]{'~resolve'}, @fors) {          #} elsif(not grep !$_->[1]{'~resolve'}, @fors) {          } elsif( $fors[-1][1]{'~resolve'} ) {            # Look to the immediately containing for                      if($para_type eq 'Data') {              DEBUG and print "Treating Data paragraph as Plain/Verbatim because the containing =for ($fors[-1][1]{'target'}) is a resolver\n";              $para->[0] = 'Para';              $para_type = 'Plain';            } else {              DEBUG and print "Treating $para_type paragraph as such because the containing =for ($fors[-1][1]{'target'}) is a resolver\n";            }          } else {            DEBUG and print "Treating $para_type paragraph as Data because the containing =for ($fors[-1][1]{'target'}) is a non-resolver\n";            $para->[0] = $para_type = 'Data';          }        }      }      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~      if($para_type eq 'Plain') {        $self->_ponder_Plain($para);      } elsif($para_type eq 'Verbatim') {        $self->_ponder_Verbatim($para);              } elsif($para_type eq 'Data') {        $self->_ponder_Data($para);      } else {        die "\$para type is $para_type -- how did that happen?";        # Shouldn't happen.      }      #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~      $para->[0] =~ s/^[~=]//s;      DEBUG and print "\n", pretty($para), "\n";      # traverse the treelet (which might well be just one string scalar)      $self->{'content_seen'} ||= 1;      $self->_traverse_treelet_bit(@$para);    }  }    return;}############################################################################ The sub-ponderers...sub _ponder_for {  my ($self,$para,$curr_open,$paras) = @_;  # Fake it out as a begin/end  my $target;  if(grep $_->[1]{'~ignore'}, @$curr_open) {    DEBUG > 1 and print "Ignoring ignorable =for\n";    return 1;  }  for(my $i = 2; $i < @$para; ++$i) {    if($para->[$i] =~ s/^\s*(\S+)\s*//s) {      $target = $1;      last;    }  }  unless(defined $target) {    $self->whine(      $para->[1]{'start_line'},      "=for without a target?"    );    return 1;  }  DEBUG > 1 and   print "Faking out a =for $target as a =begin $target / =end $target\n";    $para->[0] = 'Data';    unshift @$paras,    ['=begin',      {'start_line' => $para->[1]{'start_line'}, '~really' => '=for'},      $target,    ],    $para,    ['=end',      {'start_line' => $para->[1]{'start_line'}, '~really' => '=for'},      $target,    ],  ;    return 1;}sub _ponder_begin {  my ($self,$para,$curr_open,$paras) = @_;  my $content = join ' ', splice @$para, 2;  $content =~ s/^\s+//s;  $content =~ s/\s+$//s;  unless(length($content)) {    $self->whine(      $para->[1]{'start_line'},      "=begin without a target?"    );    DEBUG and print "Ignoring targetless =begin\n";    return 1;  }    unless($content =~ m/^\S+$/s) {  # i.e., unless it's one word    $self->whine(      $para->[1]{'start_line'},      "'=begin' only takes one parameter, not several as in '=begin $content'"    );    DEBUG and print "Ignoring unintelligible =begin $content\n";    return 1;  }  $para->[1]{'target'} = $content;  # without any ':'  $content =~ s/^:!/!:/s;  my $neg;  # whether this is a negation-match  $neg = 1        if $content =~ s/^!//s;  my $to_resolve;  # whether to process formatting codes  $to_resolve = 1 if $content =~ s/^://s;    my $dont_ignore; # whether this target matches us    foreach my $target_name (    split(',', $content, -1),    $neg ? () : '*'  ) {    DEBUG > 2 and     print " Considering whether =begin $content matches $target_name\n";    next unless $self->{'accept_targets'}{$target_name};        DEBUG > 2 and     print "  It DOES match the acceptable target $target_name!\n";    $to_resolve = 1      if $self->{'accept_targets'}{$target_name} eq 'force_resolve';    $dont_ignore = 1;    $para->[1]{'target_matching'} = $target_name;    last; # stop looking at other target names  }  if($neg) {    if( $dont_ignore ) {      $dont_ignore = '';      delete $para->[1]{'target_matching'};      DEBUG > 2 and print " But the leading ! means that this is a NON-match!\n";    } else {      $dont_ignore = 1;      $para->[1]{'target_matching'} = '!';      DEBUG > 2 and print " But the leading ! means that this IS a match!\n";    }  }  $para->[0] = '=for';  # Just what we happen to call these, internally  $para->[1]{'~really'} ||= '=begin';  $para->[1]{'~ignore'}   = (! $dont_ignore) || 0;  $para->[1]{'~resolve'}  = $to_resolve || 0;  DEBUG > 1 and print " Making note to ", $dont_ignore ? 'not ' : '',    "ignore contents of this region\n";  DEBUG > 1 and $dont_ignore and print " Making note to treat contents as ",    ($to_resolve ? 'verbatim/plain' : 'data'), " paragraphs\n";  DEBUG > 1 and print " (Stack now: ", $self->_dump_curr_open(), ")\n";  push @$curr_open, $para;  if(!$dont_ignore or scalar grep $_->[1]{'~ignore'}, @$curr_open) {    DEBUG > 1 and print "Ignoring ignorable =begin\n";  } else {    $self->{'content_seen'} ||= 1;    $self->_handle_element_start((my $scratch='for'), $para->[1]);  }  return 1;}sub _ponder_end {  my ($self,$para,$curr_open,$paras) = @_;  my $content = join ' ', splice @$para, 2;  $content =~ s/^\s+//s;  $content =~ s/\s+$//s;  DEBUG and print "Ogling '=end $content' directive\n";    unless(length($content)) {    $self->whine(      $para->[1]{'start_line'},      "'=end' without a target?" . (        ( @$curr_open and $curr_open->[-1][0] eq '=for' )        ? ( " (Should be \"=end " . $curr_open->[-1][1]{'target'} . '")' )        : ''      )    );    DEBUG and print "Ignoring targetless =end\n";    return 1;  }    unless($content =~ m/^\S+$/) {  # i.e., unless it's one word    $self->whine(      $para->[1]{'start_line'},      "'=end $content' is invalid.  (Stack: "      . $self->_dump_curr_open() . ')'    );    DEBUG and print "Ignoring mistargetted =end $content\n";    return 1;  }    unless(@$curr_open and $curr_open->[-1][0] eq '=for') {    $self->whine(      $para->[1]{'start_line'},      "=end $content without matching =begin.  (Stack: "      . $self->_dump_curr_open() . ')'    );    DEBUG and print "Ignoring mistargetted =end $content\n";    return 1;  }    unless($content eq $curr_open->[-1][1]{'target'}) {    $self->whine(      $para->[1]{'start_line'},      "=end $content doesn't match =begin "       . $curr_open->[-1][1]{'target'}      . ".  (Stack: "      . $self->_dump_curr_open() . ')'    );    DEBUG and print "Ignoring mistargetted =end $content at line $para->[1]{'start_line'}\n";    return 1;  }  # Else it's okay to close...  if(grep $_->[1]{'~ignore'}, @$curr_open) {    DEBUG > 1 and print "Not firing any event for this =end $content because in an ignored region\n";    # And that may be because of this to-be-closed =for region, or some    #  other one, but it doesn't matter.  } else {    $curr_open->[-1][1]{'start_line'} = $para->[1]{'start_line'};      # what's that for?        $self->{'content_seen'} ||= 1;    $self->_handle_element_end( my $scratch = 'for' );  }  DEBUG > 1 and print "Popping $curr_open->[-1][0] $curr_open->[-1][1]{'target'} because of =end $content\n";  pop @$curr_open;  return 1;} sub _ponder_doc_end {  my ($self,$para,$curr_open,$paras) = @_;  if(@$curr_open) { # Deal with things left open    DEBUG and print "Stack is nonempty at end-document: (",      $self->_dump_curr_open(), ")\n";          DEBUG > 9 and print "Stack: ", pretty($curr_open), "\n";    unshift @$paras, $self->_closers_for_all_curr_open;    # Make sure there is exactly one ~end in the parastack, at the end:    @$paras = grep $_->[0] ne '~end', @$paras;    push @$paras, $para, $para;     # We need two -- once for the next cycle where we     #  generate errata, and then another to be at the end     #  when that loop back around to process the errata.    return 1;      } else {    DEBUG and print "Okay, stack is empty now.\n";  }    # Try generating errata section, if applicable  unless($self->{'~tried_gen_errata'}) {    $self->{'~tried_gen_errata'} = 1;    my @extras = $self->_gen_errata();    if(@extras) {      unshift @$paras, @extras;      DEBUG and print "Generated errata... relooping...\n";      return 1;  # I.e., loop around again to process these fake-o paragraphs    }  }    splice @$paras; # Well, that's that for this paragraph buffer.  DEBUG and print "Throwing end-document event.\n";  $self->_handle_element_end( my $scratch = 'Document' );  return 1; # Hasta la byebye}sub _ponder_pod {  my ($self,$para,$curr_open,$paras) = @_;  $self->whine(    $para->[1]{'start_line'},    "=pod directives shouldn't be over one line long!  Ignoring all "     . (@$para - 2) . " lines of content"  ) if @$para > 3;  # Content is always ignored.  return;}sub _ponder_over {  my ($self,$para,$curr_open,$paras) = @_;  return 1 unless @$paras;  my $list_type;  if($paras->[0][0] eq '=item') { # most common case    $list_type = $self->_get_initial_item_type($paras->[0]);  } elsif($paras->[0][0] eq '=back') {    # Ignore empty lists.  TODO: make this an option?    shift @$paras;    return 1;      } elsif($paras->[0][0] eq '~end') {    $self->whine(      $para->[1]{'start_line'},      "=over is the last thing in the document?!"    );    return 1; # But feh, ignore it.  } else {    $list_type = 'block';  }  $para->[1]{'~type'} = $list_type;  push @$curr_open, $para;   # yes, we reuse the paragraph as a stack item    my $content = join ' ', splice @$para, 2;  my $overness;  if($content =~ m/^\s*$/s) {    $para->[1]{'indent'} = 4;  } elsif($content =~ m/^\s*((?:\d*\.)?\d+)\s*$/s) {    no integer;    $para->[1]{'indent'} = $1;    if($1 == 0) {      $self->whine(        $para->[1]{'start_line'},        "Can't have a 0 in =over $content"      );      $para->[1]{'indent'} = 4;    }  } else {    $self->whine(      $para->[1]{'start_line'},      "=over should be: '=over' or '=over positive_number'"    );    $para->[1]{'indent'} = 4;  }  DEBUG > 1 and print "=over found of type $list_type\n";    $self->{'content_seen'} ||= 1;  $self->_handle_element_start((my $scratch = 'over-' . $list_type), $para->[1]);  return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -