mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Import RDoc 2.2.1 r185
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19537 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
00b4a3f9c4
commit
858362e761
54 changed files with 2893 additions and 2268 deletions
165
lib/rdoc/parser/perl.rb
Normal file
165
lib/rdoc/parser/perl.rb
Normal file
|
@ -0,0 +1,165 @@
|
|||
require 'rdoc/parser'
|
||||
|
||||
##
|
||||
#
|
||||
# This is an attamept to write a basic parser for Perl's
|
||||
# POD (Plain old Documentation) format. Ruby code must
|
||||
# co-exist with Perl, and some tasks are easier in Perl
|
||||
# than Ruby because of existing libraries.
|
||||
#
|
||||
# One difficult is that Perl POD has no means of identifying
|
||||
# the classes (packages) and methods (subs) with which it
|
||||
# is associated, it is more like literate programming in so
|
||||
# far as it just happens to be in the same place as the code,
|
||||
# but need not be.
|
||||
#
|
||||
# We would like to support all the markup the POD provides
|
||||
# so that it will convert happily to HTML. At the moment
|
||||
# I don't think I can do that: time constraints.
|
||||
#
|
||||
|
||||
class RDoc::Parser::PerlPOD < RDoc::Parser
|
||||
|
||||
parse_files_matching(/.p[lm]$/)
|
||||
|
||||
##
|
||||
# Prepare to parse a perl file
|
||||
|
||||
def initialize(top_level, file_name, content, options, stats)
|
||||
super
|
||||
|
||||
preprocess = RDoc::Markup::PreProcess.new @file_name, @options.rdoc_include
|
||||
|
||||
preprocess.handle @content do |directive, param|
|
||||
warn "Unrecognized directive '#{directive}' in #{@file_name}"
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Extract the Pod(-like) comments from the code.
|
||||
# At its most basic there will ne no need to distinguish
|
||||
# between the different types of header, etc.
|
||||
#
|
||||
# This uses a simple finite state machine, in a very
|
||||
# procedural pattern. I could "replace case with polymorphism"
|
||||
# but I think it would obscure the intent, scatter the
|
||||
# code all over tha place. This machine is necessary
|
||||
# because POD requires that directives be preceded by
|
||||
# blank lines, so reading line by line is necessary,
|
||||
# and preserving state about what is seen is necesary.
|
||||
|
||||
def scan
|
||||
|
||||
@top_level.comment ||= ""
|
||||
state=:code_blank
|
||||
line_number = 0
|
||||
line = nil
|
||||
|
||||
# This started out as a really long nested case statement,
|
||||
# which also led to repetitive code. I'd like to avoid that
|
||||
# so I'm using a "table" instead.
|
||||
|
||||
# Firstly we need some procs to do the transition and processing
|
||||
# work. Because these are procs they are closures, and they can
|
||||
# use variables in the local scope.
|
||||
#
|
||||
# First, the "nothing to see here" stuff.
|
||||
code_noop = lambda do
|
||||
if line =~ /^\s+$/
|
||||
state = :code_blank
|
||||
end
|
||||
end
|
||||
|
||||
pod_noop = lambda do
|
||||
if line =~ /^\s+$/
|
||||
state = :pod_blank
|
||||
end
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
|
||||
begin_noop = lambda do
|
||||
if line =~ /^\s+$/
|
||||
state = :begin_blank
|
||||
end
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
|
||||
# Now for the blocks that process code and comments...
|
||||
|
||||
transit_to_pod = lambda do
|
||||
case line
|
||||
when /^=(?:pod|head\d+)/
|
||||
state = :pod_no_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=over/
|
||||
state = :over_no_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=(?:begin|for)/
|
||||
state = :begin_no_blank
|
||||
end
|
||||
end
|
||||
|
||||
process_pod = lambda do
|
||||
case line
|
||||
when /^\s*$/
|
||||
state = :pod_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=cut/
|
||||
state = :code_no_blank
|
||||
when /^=end/
|
||||
$stderr.puts "'=end' unexpected at #{line_number} in #{@file_name}"
|
||||
else
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
process_begin = lambda do
|
||||
case line
|
||||
when /^\s*$/
|
||||
state = :begin_blank
|
||||
@top_level.comment += filter(line)
|
||||
when /^=end/
|
||||
state = :code_no_blank
|
||||
when /^=cut/
|
||||
$stderr.puts "'=cut' unexpected at #{line_number} in #{@file_name}"
|
||||
else
|
||||
@top_level.comment += filter(line)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
transitions = { :code_no_blank => code_noop,
|
||||
:code_blank => transit_to_pod,
|
||||
:pod_no_blank => pod_noop,
|
||||
:pod_blank => process_pod,
|
||||
:begin_no_blank => begin_noop,
|
||||
:begin_blank => process_begin}
|
||||
@content.each_line do |l|
|
||||
line = l
|
||||
line_number += 1
|
||||
transitions[state].call
|
||||
end # each line
|
||||
|
||||
@top_level
|
||||
end
|
||||
|
||||
# Filter the perl markup that does the same as the rdoc
|
||||
# filtering. Only basic for now. Will probably need a
|
||||
# proper parser to cope with C<<...>> etc
|
||||
def filter(comment)
|
||||
return '' if comment =~ /^=pod\s*$/
|
||||
comment.gsub!(/^=pod/, '==')
|
||||
comment.gsub!(/^=head(\d+)/) do
|
||||
"=" * $1.to_i
|
||||
end
|
||||
comment.gsub!(/=item/, '');
|
||||
comment.gsub!(/C<(.*?)>/, '<tt>\1</tt>');
|
||||
comment.gsub!(/I<(.*?)>/, '<i>\1</i>');
|
||||
comment.gsub!(/B<(.*?)>/, '<b>\1</b>');
|
||||
comment
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue