class RDoc::Markup::PreProcess
处理文本块中可能出现的常见指令
:include: filename
可以通过在指令前加上反斜杠来转义指令。
RDoc
插件作者可以使用 RDoc::Markup::PreProcess::register
注册要处理的其他指令。
任何不是 RDoc
内置的指令(包括通过插件注册的指令)都将存储在附加注释的 CodeObject 的元数据哈希中。 有关内置指令列表,请参阅RDoc::Markup
中的指令。
属性
一个 RDoc::Options
实例,将用指令中的覆盖信息填充
公共类方法
为 input_file_name
创建一个新的预处理器,该预处理器将在 include_path
中查找包含的文件
# File rdoc/markup/pre_process.rb, line 78 def initialize(input_file_name, include_path) @input_file_name = input_file_name @include_path = include_path @options = nil end
为指令添加一个后处理处理程序。 该处理程序将使用结果 RDoc::Comment
(或文本字符串) 和注释的代码对象(如果有)调用。
# File rdoc/markup/pre_process.rb, line 30 def self.post_process &block @post_processors << block end
注册的后处理程序
# File rdoc/markup/pre_process.rb, line 37 def self.post_processors @post_processors end
将 directive
注册为 RDoc
处理的指令。 如果给出了一个代码块,则该指令将被该代码块的结果替换,否则该指令将从处理的文本中删除。
将使用指令名称和指令参数调用该代码块
RDoc::Markup::PreProcess.register 'my-directive' do |directive, param| # replace text, etc. end
# File rdoc/markup/pre_process.rb, line 53 def self.register directive, &block @registered[directive] = block end
注册的指令
# File rdoc/markup/pre_process.rb, line 60 def self.registered @registered end
清除所有已注册的指令和后处理程序
# File rdoc/markup/pre_process.rb, line 67 def self.reset @post_processors = [] @registered = {} end
公共实例方法
在包含当前文件的目录中查找给定文件,然后在 RDOC_INCLUDE 路径中指定的每个目录中查找
# File rdoc/markup/pre_process.rb, line 308 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
在给定的 text
中查找指令。
我们不处理的选项将被产生。 如果代码块返回 false,则该指令将恢复到文本。 如果代码块返回 nil 或未给出代码块,则根据注册的指令处理该指令。 如果返回 String,则该指令将替换为该字符串。
如果没有注册匹配的指令,则该指令将恢复到文本。
如果给出了 code_object
并且该指令未知,则该指令的参数将设置为 code_object
上的元数据。 有关详细信息,请参阅RDoc::CodeObject#metadata
。
# File rdoc/markup/pre_process.rb, line 99 def handle text, code_object = nil, &block first_line = 1 if RDoc::Comment === text then comment = text text = text.text first_line = comment.line || 1 end # regexp helper (square brackets for optional) # $1 $2 $3 $4 $5 # [prefix][\]:directive:[spaces][param]newline text = text.lines.map.with_index(first_line) do |line, num| next line unless line =~ /\A([ \t]*(?:#|\/?\*)?[ \t]*)(\\?):([\w-]+):([ \t]*)(.+)?(\r?\n|$)/ # 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' then next "#{$1.strip}\n" unless $5 comment.format = $5.downcase next "#{$1.strip}\n" end handle_directive $1, $3, $5, code_object, text.encoding, num, &block end.join if comment then comment.text = text else comment = text end self.class.post_processors.each do |handler| handler.call comment, code_object end text end
执行 directive
及其参数 param
描述的操作。
code_object
用于对类或模块进行操作的指令。 prefix
用于确保处理的指令的替换是正确的。 encoding
用于 include
指令。
有关 RDoc
中的指令列表,请参阅 RDoc::Markup
。
# File rdoc/markup/pre_process.rb, line 153 def handle_directive prefix, directive, param, code_object = nil, encoding = nil, line = nil blankline = "#{prefix.strip}\n" directive = directive.downcase case directive when 'arg', 'args' then return "#{prefix}:#{directive}: #{param}\n" unless code_object && code_object.kind_of?(RDoc::AnyMethod) code_object.params = param blankline when 'category' then if RDoc::Context === code_object then section = code_object.add_section param code_object.temporary_section = section elsif RDoc::AnyMethod === code_object then code_object.section_title = param end blankline # ignore category if we're not on an RDoc::Context when 'doc' then return blankline unless code_object code_object.document_self = true code_object.force_documentation = true blankline when 'enddoc' then return blankline unless code_object code_object.done_documenting = true blankline when 'include' then filename = param.split(' ', 2).first include_file filename, prefix, encoding when 'main' then @options.main_page = param if @options.respond_to? :main_page warn <<~MSG The :main: directive is deprecated and will be removed in RDoc 7. You can use these options to specify the initial page displayed instead: - `--main=#{param}` via the command line - `rdoc.main = "#{param}"` if you use `RDoc::Task` - `main_page: #{param}` in your `.rdoc_options` file MSG blankline when 'nodoc' then 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' then return blankline unless RDoc::AnyMethod === code_object code_object.dont_rename_initialize = true blankline when 'startdoc' then return blankline unless code_object code_object.start_doc code_object.force_documentation = true blankline when 'stopdoc' then return blankline unless code_object code_object.stop_doc blankline when 'title' then @options.default_title = param if @options.respond_to? :default_title= warn <<~MSG The :title: directive is deprecated and will be removed in RDoc 7. You can use these options to specify the title displayed instead: - `--title=#{param}` via the command line - `rdoc.title = "#{param}"` if you use `RDoc::Task` - `title: #{param}` in your `.rdoc_options` file MSG blankline when 'yield', 'yields' then 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, line if block_given? case result when nil then code_object.metadata[directive] = param if code_object if RDoc::Markup::PreProcess.registered.include? directive then handler = RDoc::Markup::PreProcess.registered[directive] result = handler.call directive, param if handler else result = "#{prefix}:#{directive}: #{param}\n" end when false then result = "#{prefix}:#{directive}: #{param}\n" end result end end
处理 :include: filename
指令。
如果包含文件的第一行以“#”开头,并且包含 “coding:” 或 “coding=” 形式的编码信息,则将其删除。
如果包含文件中的所有行都以“#”开头,则在包含之前删除该前导“#”。 包含的内容会像 :include:
指令一样缩进。
# File rdoc/markup/pre_process.rb, line 282 def include_file name, indent, encoding full_name = find_include_file name unless full_name then warn "Couldn't find file to include '#{name}' from #{@input_file_name}" return '' end content = RDoc::Encoding.read_file full_name, encoding, true content = RDoc::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 =~ /^[^#]/ then content.gsub(/^/, indent) else content.gsub(/^#?/, indent) end end