(Replaced by #4265.)
[p5sagit/p5-mst-13.2.git] / lib / Pod / Checker.pm
CommitLineData
360aca43 1#############################################################################
2# Pod/Checker.pm -- check pod documents for syntax errors
3#
4# Based on Tom Christiansen's Pod::Text::pod2text() function
5# (with modifications).
6#
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
10# as Perl itself.
11#############################################################################
12
13package Pod::Checker;
14
15use vars qw($VERSION);
e9fdc7d2 16$VERSION = 1.081; ## Current version of this package
360aca43 17require 5.004; ## requires this Perl version or later
18
19=head1 NAME
20
21Pod::Checker, podchecker() - check pod documents for syntax errors
22
23=head1 SYNOPSIS
24
25 use Pod::Checker;
26
27 $syntax_okay = podchecker($filepath, $outputpath);
28
29=head1 OPTIONS/ARGUMENTS
30
31C<$filepath> is the input POD to read and C<$outputpath> is
32where to write POD syntax error messages. Either argument may be a scalar
33indcating a file-path, or else a reference to an open filehandle.
34If unspecified, the input-file it defaults to C<\*STDIN>, and
35the output-file defaults to C<\*STDERR>.
36
37
38=head1 DESCRIPTION
39
40B<podchecker> will perform syntax checking of Perl5 POD format documentation.
41
42I<NOTE THAT THIS MODULE IS CURRENTLY IN THE INITIAL DEVELOPMENT STAGE!>
43As of this writing, all it does is check for unknown '=xxxx' commands,
44unknown 'X<...>' interior-sequences, and unterminated interior sequences.
45
46It is hoped that curious/ambitious user will help flesh out and add the
47additional features they wish to see in B<Pod::Checker> and B<podchecker>.
48
49=head1 EXAMPLES
50
51I<[T.B.D.]>
52
53=head1 AUTHOR
54
55Brad Appleton E<lt>bradapp@enteract.comE<gt> (initial version)
56
57Based on code for B<Pod::Text::pod2text()> written by
58Tom Christiansen E<lt>tchrist@mox.perl.comE<gt>
59
60=cut
61
62#############################################################################
63
64use strict;
65#use diagnostics;
66use Carp;
67use Exporter;
68use Pod::Parser;
69
70use vars qw(@ISA @EXPORT);
71@ISA = qw(Pod::Parser);
72@EXPORT = qw(&podchecker);
73
74use vars qw(%VALID_COMMANDS %VALID_SEQUENCES);
75
76my %VALID_COMMANDS = (
77 'pod' => 1,
78 'cut' => 1,
79 'head1' => 1,
80 'head2' => 1,
81 'over' => 1,
82 'back' => 1,
83 'item' => 1,
84 'for' => 1,
85 'begin' => 1,
86 'end' => 1,
87);
88
89my %VALID_SEQUENCES = (
90 'I' => 1,
91 'B' => 1,
92 'S' => 1,
93 'C' => 1,
94 'L' => 1,
95 'F' => 1,
96 'X' => 1,
97 'Z' => 1,
98 'E' => 1,
99);
100
101##---------------------------------------------------------------------------
102
103##---------------------------------
104## Function definitions begin here
105##---------------------------------
106
107sub podchecker( $ ; $ ) {
108 my ($infile, $outfile) = @_;
109 local $_;
110
111 ## Set defaults
112 $infile ||= \*STDIN;
113 $outfile ||= \*STDERR;
114
115 ## Now create a pod checker
116 my $checker = new Pod::Checker();
117
118 ## Now check the pod document for errors
119 $checker->parse_from_file($infile, $outfile);
120
121 ## Return the number of errors found
122 return $checker->num_errors();
123}
124
125##---------------------------------------------------------------------------
126
127##-------------------------------
128## Method definitions begin here
129##-------------------------------
130
131sub new {
132 my $this = shift;
133 my $class = ref($this) || $this;
134 my %params = @_;
135 my $self = {%params};
136 bless $self, $class;
137 $self->initialize();
138 return $self;
139}
140
141sub initialize {
142 my $self = shift;
143 $self->num_errors(0);
144}
145
146sub num_errors {
147 return (@_ > 1) ? ($_[0]->{_NUM_ERRORS} = $_[1]) : $_[0]->{_NUM_ERRORS};
148}
149
150sub end_pod {
151 ## Print the number of errors found
152 my $self = shift;
153 my $infile = $self->input_file();
154 my $out_fh = $self->output_handle();
155
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");
160 }
161 else {
162 print $out_fh "$infile pod syntax OK.\n";
163 }
164}
165
166sub command {
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);
174 }
175 else {
176 ## check syntax of particular command
177 }
178 ## Check the interior sequences in the command-text
179 my $expansion = $self->interpolate($paragraph, $line_num);
180}
181
182sub verbatim {
183 ## Nothing to check
184 ## my ($self, $paragraph, $line_num, $pod_para) = @_;
185}
186
187sub textblock {
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});
194 print $out_fh @_
195 };
196 my $expansion = $self->interpolate($paragraph, $line_num);
197}
198
199sub 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);
207 }
208 else {
209 ## check syntax of the particular sequence
210 }
211}
212
213sub _invalid_cmd {
214 my ($fh, $cmd, $text, $file, $line) = @_;
215 print $fh "*** ERROR: Unknown command \"$cmd\""
216 . " at line $line of file $file\n";
217}
218
219sub _invalid_seq {
220 my ($fh, $cmd, $text, $file, $line) = @_;
221 print $fh "*** ERROR: Unknown interior-sequence \"$cmd\""
222 . " at line $line of file $file\n";
223}
224