Class: RDoc::Markup::PreProcess
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | lib/rdoc/markup/pre_process.rb |
Overview
Handle common directives that can occur in a block of text:
\:include: filename
Directives can be escaped by preceding them with a backslash.
::RDoc::RDoc plugin authors can register additional directives to be handled by
using .register.
Any directive that is not built-in to ::RDoc::RDoc (including those registered via
plugins) will be stored in the metadata hash on the ::RDoc::CodeObject the comment
is attached to. See RDoc::Markup@Directives for the list of built-in
directives.
Class Method Summary
-
.new(input_file_name, include_path) ⇒ PreProcess
constructor
Creates a new pre-processor for
input_file_namethat will look for included files ininclude_path -
.post_process(&block)
Adds a post-process handler for directives.
-
.post_processors
Registered post-processors.
-
.register(directive, &block)
Registers
directiveas one handled by::RDoc::RDoc. -
.registered
Registered directives.
-
.reset
Clears all registered directives and post-processors.
Instance Attribute Summary
-
#options
rw
An
::RDoc::Optionsinstance that will be filled in with overrides from directives.
Instance Method Summary
-
#find_include_file(name)
Look for the given file in the directory containing the current file, and then in each of the directories specified in the RDOC_INCLUDE path.
-
#handle(text, code_object = nil, &block)
Look for directives in the given
text. -
#handle_directive(prefix, directive, param, code_object = nil, encoding = nil)
Performs the actions described by
directiveand its parameterparam. -
#include_file(name, indent, encoding)
Handles the :include: _filename_ directive.
-
#parse_comment(text, line_no, type)
Parse comment and return [normalized_comment_text, directives_hash].
-
#run_post_processes(comment, code_object)
Perform post preocesses to a code object.
-
#run_pre_processes(comment_text, code_object, start_line_no, type)
Apply directives to a code object.
Constructor Details
.new(input_file_name, include_path) ⇒ PreProcess
Creates a new pre-processor for input_file_name that will look for
included files in include_path
# File 'lib/rdoc/markup/pre_process.rb', line 80
def initialize(input_file_name, include_path) @input_file_name = input_file_name @include_path = include_path @options = nil end
Class Method Details
.post_process(&block)
Adds a post-process handler for directives. The handler will be called
with the result ::RDoc::Comment (or text String) and the code object for the
comment (if any).
# File 'lib/rdoc/markup/pre_process.rb', line 32
def self.post_process(&block) @post_processors << block end
.post_processors
Registered post-processors
# File 'lib/rdoc/markup/pre_process.rb', line 39
def self.post_processors @post_processors end
.register(directive, &block)
Registers directive as one handled by ::RDoc::RDoc. If a block is given the
directive will be replaced by the result of the block, otherwise the
directive will be removed from the processed text.
The block will be called with the directive name and the directive parameter:
RDoc::Markup::PreProcess.register 'my-directive' do |directive, param|
# replace text, etc.
end
# File 'lib/rdoc/markup/pre_process.rb', line 55
def self.register(directive, &block) @registered[directive] = block end
.registered
Registered directives
# File 'lib/rdoc/markup/pre_process.rb', line 62
def self.registered @registered end
.reset
Clears all registered directives and post-processors
# File 'lib/rdoc/markup/pre_process.rb', line 69
def self.reset @post_processors = [] @registered = {} end
Instance Attribute Details
#options (rw)
An ::RDoc::Options instance that will be filled in with overrides from
directives
# File 'lib/rdoc/markup/pre_process.rb', line 25
attr_accessor :
Instance Method Details
#find_include_file(name)
Look for the given file in the directory containing the current file, and then in each of the directories specified in the RDOC_INCLUDE path
# File 'lib/rdoc/markup/pre_process.rb', line 309
def find_include_file(name) to_search = [File.dirname(@input_file_name)].concat @include_path to_search.each do |dir| full_name = File.join(dir, name) stat = File.stat(full_name) rescue next return full_name if stat.readable? end nil end
#handle(text, code_object = nil, &block)
Look for directives in the given text.
::RDoc::Options that we don't handle are yielded. If the block returns false the
directive is restored to the text. If the block returns nil or no block
was given the directive is handled according to the registered directives.
If a String was returned the directive is replaced with the string.
If no matching directive was registered the directive is restored to the text.
If code_object is given and the directive is unknown then the
directive's parameter is set as metadata on the code_object. See
CodeObject#metadata for details.
# File 'lib/rdoc/markup/pre_process.rb', line 101
def handle(text, code_object = nil, &block) if Comment === text comment = text text = text.text end # regexp helper (square brackets for optional) # $1 $2 $3 $4 $5 # [prefix][\]:directive:[spaces][param]newline text = text.gsub(/^([ \t]*(?:#|\/?\*)?[ \t]*)(\\?):([\w-]+):([ \t]*)(.+)?(\r?\n|$)/) do # skip something like ':toto::' next $& if $4.empty? and $5 and $5[0, 1] == ':' # skip if escaped next "#$1:#$3:#$4#$5\n" unless $2.empty? # This is not in handle_directive because I didn't want to pass another # argument into it if comment and $3 == 'markup' next "#{$1.strip}\n" unless $5 comment.format = $5.downcase next "#{$1.strip}\n" end handle_directive $1, $3, $5, code_object, text.encoding, &block end if comment comment.text = text else comment = text end run_post_processes(comment, code_object) text end
#handle_directive(prefix, directive, param, code_object = nil, encoding = nil)
Performs the actions described by directive and its parameter param.
code_object is used for directives that operate on a class or module.
prefix is used to ensure the replacement for handled directives is
correct. encoding is used for the include directive.
For a list of directives in ::RDoc::RDoc see ::RDoc::Markup.
# File 'lib/rdoc/markup/pre_process.rb', line 179
def handle_directive(prefix, directive, param, code_object = nil, encoding = nil) blankline = "#{prefix.strip}\n" directive = directive.downcase case directive when 'arg', 'args' return "#{prefix}:#{directive}: #{param}\n" unless code_object && code_object.kind_of?(AnyMethod) code_object.params = param blankline when 'category' if Context === code_object section = code_object.add_section param code_object.temporary_section = section elsif AnyMethod === code_object code_object.section_title = param end blankline # ignore category if we're not on an RDoc::Context when 'doc' return blankline unless code_object code_object.document_self = true code_object.force_documentation = true blankline when 'enddoc' return blankline unless code_object code_object.done_documenting = true blankline when 'include' filename = param.split(' ', 2).first include_file filename, prefix, encoding when 'nodoc' return blankline unless code_object code_object.document_self = nil # notify nodoc code_object.document_children = param !~ /all/i blankline when 'notnew', 'not_new', 'not-new' return blankline unless AnyMethod === code_object code_object.dont_rename_initialize = true blankline when 'startdoc' return blankline unless code_object code_object.start_doc code_object.force_documentation = true blankline when 'stopdoc' return blankline unless code_object code_object.stop_doc blankline when 'yield', 'yields' return blankline unless code_object # remove parameter &block code_object.params = code_object.params.sub(/,?\s*&\w+/, '') if code_object.params code_object.block_params = param || '' blankline else result = yield directive, param if block_given? case result when nil code_object.[directive] = param if code_object if Markup::PreProcess.registered.include? directive handler = Markup::PreProcess.registered[directive] result = handler.call directive, param if handler else result = "#{prefix}:#{directive}: #{param}\n" end when false result = "#{prefix}:#{directive}: #{param}\n" end result end end
#include_file(name, indent, encoding)
Handles the :include: _filename_ directive.
If the first line of the included file starts with '#', and contains an encoding information in the form 'coding:' or 'coding=', it is removed.
If all lines in the included file start with a '#', this leading '#' is removed before inclusion. The included content is indented like the :include: directive.
# File 'lib/rdoc/markup/pre_process.rb', line 283
def include_file(name, indent, encoding) full_name = find_include_file name unless full_name warn "Couldn't find file to include '#{name}' from #{@input_file_name}" return '' end content = Encoding.read_file full_name, encoding, true content = Encoding.remove_magic_comment content # strip magic comment content = content.sub(/\A# .*coding[=:].*$/, '').lstrip # strip leading '#'s, but only if all lines start with them if content =~ /^[^#]/ content.gsub(/^/, indent) else content.gsub(/^#?/, indent) end end
#parse_comment(text, line_no, type)
Parse comment and return [normalized_comment_text, directives_hash]
# File 'lib/rdoc/markup/pre_process.rb', line 162
def parse_comment(text, line_no, type) Comment.parse(text, @input_file_name, line_no, type) do |filename, prefix_indent| include_file(filename, prefix_indent, text.encoding) end end
#run_post_processes(comment, code_object)
Perform post preocesses to a code object
# File 'lib/rdoc/markup/pre_process.rb', line 154
def run_post_processes(comment, code_object) self.class.post_processors.each do |handler| handler.call comment, code_object end end
#run_pre_processes(comment_text, code_object, start_line_no, type)
Apply directives to a code object
# File 'lib/rdoc/markup/pre_process.rb', line 140
def run_pre_processes(comment_text, code_object, start_line_no, type) comment_text, directives = parse_comment(comment_text, start_line_no, type) directives.each do |directive, (param, line_no)| handle_directive('', directive, param, code_object) end if code_object.is_a?(AnyMethod) && (call_seq, = directives['call-seq']) && call_seq code_object.call_seq = call_seq.lines.map(&:chomp).reject(&:empty?).join("\n") end format, = directives['markup'] [comment_text, format] end