1 #############################################################################
2 # Pod/Checker.pm -- check pod documents for syntax errors
4 # Based on Tom Christiansen's Pod::Text::pod2text() function
5 # (with modifications).
7 # Copyright (C) 1994-1999 Tom Christiansen. All rights reserved.
8 # This file is part of "PodParser". PodParser is free software;
9 # you can redistribute it and/or modify it under the same terms
11 #############################################################################
15 use vars qw($VERSION);
16 $VERSION = 1.081; ## Current version of this package
17 require 5.004; ## requires this Perl version or later
21 Pod::Checker, podchecker() - check pod documents for syntax errors
27 $syntax_okay = podchecker($filepath, $outputpath);
29 =head1 OPTIONS/ARGUMENTS
31 C<$filepath> is the input POD to read and C<$outputpath> is
32 where to write POD syntax error messages. Either argument may be a scalar
33 indcating a file-path, or else a reference to an open filehandle.
34 If unspecified, the input-file it defaults to C<\*STDIN>, and
35 the output-file defaults to C<\*STDERR>.
40 B<podchecker> will perform syntax checking of Perl5 POD format documentation.
42 I<NOTE THAT THIS MODULE IS CURRENTLY IN THE INITIAL DEVELOPMENT STAGE!>
43 As of this writing, all it does is check for unknown '=xxxx' commands,
44 unknown 'X<...>' interior-sequences, and unterminated interior sequences.
46 It is hoped that curious/ambitious user will help flesh out and add the
47 additional features they wish to see in B<Pod::Checker> and B<podchecker>.
55 Brad Appleton E<lt>bradapp@enteract.comE<gt> (initial version)
57 Based on code for B<Pod::Text::pod2text()> written by
58 Tom Christiansen E<lt>tchrist@mox.perl.comE<gt>
62 #############################################################################
70 use vars qw(@ISA @EXPORT);
71 @ISA = qw(Pod::Parser);
72 @EXPORT = qw(&podchecker);
74 use vars qw(%VALID_COMMANDS %VALID_SEQUENCES);
76 my %VALID_COMMANDS = (
89 my %VALID_SEQUENCES = (
101 ##---------------------------------------------------------------------------
103 ##---------------------------------
104 ## Function definitions begin here
105 ##---------------------------------
107 sub podchecker( $ ; $ ) {
108 my ($infile, $outfile) = @_;
113 $outfile ||= \*STDERR;
115 ## Now create a pod checker
116 my $checker = new Pod::Checker();
118 ## Now check the pod document for errors
119 $checker->parse_from_file($infile, $outfile);
121 ## Return the number of errors found
122 return $checker->num_errors();
125 ##---------------------------------------------------------------------------
127 ##-------------------------------
128 ## Method definitions begin here
129 ##-------------------------------
133 my $class = ref($this) || $this;
135 my $self = {%params};
143 $self->num_errors(0);
147 return (@_ > 1) ? ($_[0]->{_NUM_ERRORS} = $_[1]) : $_[0]->{_NUM_ERRORS};
151 ## Print the number of errors found
153 my $infile = $self->input_file();
154 my $out_fh = $self->output_handle();
156 my $num_errors = $self->num_errors();
157 if ($num_errors > 0) {
158 printf $out_fh ("$infile has $num_errors pod syntax %s.\n",
159 ($num_errors == 1) ? "error" : "errors");
162 print $out_fh "$infile pod syntax OK.\n";
167 my ($self, $command, $paragraph, $line_num, $pod_para) = @_;
168 my ($file, $line) = $pod_para->file_line;
169 my $out_fh = $self->output_handle();
170 ## Check the command syntax
171 if (! $VALID_COMMANDS{$command}) {
172 ++($self->{_NUM_ERRORS});
173 _invalid_cmd($out_fh, $command, $paragraph, $file, $line);
176 ## check syntax of particular command
178 ## Check the interior sequences in the command-text
179 my $expansion = $self->interpolate($paragraph, $line_num);
184 ## my ($self, $paragraph, $line_num, $pod_para) = @_;
188 my ($self, $paragraph, $line_num, $pod_para) = @_;
189 my $out_fh = $self->output_handle();
190 ## Check the interior sequences in the text (set $SIG{__WARN__} to
191 ## send parse_text warnings about untermnated sequences to $out_fh)
192 local $SIG{__WARN__} = sub {
193 ++($self->{_NUM_ERRORS});
196 my $expansion = $self->interpolate($paragraph, $line_num);
199 sub interior_sequence {
200 my ($self, $seq_cmd, $seq_arg, $pod_seq) = @_;
201 my ($file, $line) = $pod_seq->file_line;
202 my $out_fh = $self->output_handle();
203 ## Check the sequence syntax
204 if (! $VALID_SEQUENCES{$seq_cmd}) {
205 ++($self->{_NUM_ERRORS});
206 _invalid_seq($out_fh, $seq_cmd, $seq_arg, $file, $line);
209 ## check syntax of the particular sequence
214 my ($fh, $cmd, $text, $file, $line) = @_;
215 print $fh "*** ERROR: Unknown command \"$cmd\""
216 . " at line $line of file $file\n";
220 my ($fh, $cmd, $text, $file, $line) = @_;
221 print $fh "*** ERROR: Unknown interior-sequence \"$cmd\""
222 . " at line $line of file $file\n";