diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/lib/rdoc/tom_doc.rb |
Fresh start
Diffstat (limited to 'jni/ruby/lib/rdoc/tom_doc.rb')
-rw-r--r-- | jni/ruby/lib/rdoc/tom_doc.rb | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/jni/ruby/lib/rdoc/tom_doc.rb b/jni/ruby/lib/rdoc/tom_doc.rb new file mode 100644 index 0000000..2b62243 --- /dev/null +++ b/jni/ruby/lib/rdoc/tom_doc.rb @@ -0,0 +1,257 @@ +# :markup: tomdoc + +# A parser for TomDoc based on TomDoc 1.0.0-rc1 (02adef9b5a) +# +# The TomDoc specification can be found at: +# +# http://tomdoc.org +# +# The latest version of the TomDoc specification can be found at: +# +# https://github.com/mojombo/tomdoc/blob/master/tomdoc.md +# +# To choose TomDoc as your only default format see RDoc::Options@Saved+Options +# for instructions on setting up a <code>.rdoc_options</code> file to store +# your project default. +# +# There are a few differences between this parser and the specification. A +# best-effort was made to follow the specification as closely as possible but +# some choices to deviate were made. +# +# A future version of RDoc will warn when a MUST or MUST NOT is violated and +# may warn when a SHOULD or SHOULD NOT is violated. RDoc will always try +# to emit documentation even if given invalid TomDoc. +# +# Here are some implementation choices this parser currently makes: +# +# This parser allows rdoc-style inline markup but you should not depended on +# it. +# +# This parser allows a space between the comment and the method body. +# +# This parser does not require the default value to be described for an +# optional argument. +# +# This parser does not examine the order of sections. An Examples section may +# precede the Arguments section. +# +# This class is documented in TomDoc format. Since this is a subclass of the +# RDoc markup parser there isn't much to see here, unfortunately. + +class RDoc::TomDoc < RDoc::Markup::Parser + + # Internal: Token accessor + + attr_reader :tokens + + # Internal: Adds a post-processor which sets the RDoc section based on the + # comment's status. + # + # Returns nothing. + + def self.add_post_processor # :nodoc: + RDoc::Markup::PreProcess.post_process do |comment, code_object| + next unless code_object and + RDoc::Comment === comment and comment.format == 'tomdoc' + + comment.text.gsub!(/(\A\s*# )(Public|Internal|Deprecated):\s+/) do + section = code_object.add_section $2 + code_object.temporary_section = section + + $1 + end + end + end + + add_post_processor + + # Public: Parses TomDoc from text + # + # text - A String containing TomDoc-format text. + # + # Examples + # + # RDoc::TomDoc.parse <<-TOMDOC + # This method does some things + # + # Returns nothing. + # TOMDOC + # # => #<RDoc::Markup::Document:0xXXX @parts=[...], @file=nil> + # + # Returns an RDoc::Markup::Document representing the TomDoc format. + + def self.parse text + parser = new + + parser.tokenize text + doc = RDoc::Markup::Document.new + parser.parse doc + doc + end + + # Internal: Extracts the Signature section's method signature + # + # comment - An RDoc::Comment that will be parsed and have the signature + # extracted + # + # Returns a String containing the signature and nil if not + + def self.signature comment + return unless comment.tomdoc? + + document = comment.parse + + signature = nil + found_heading = false + found_signature = false + + document.parts.delete_if do |part| + next false if found_signature + + found_heading ||= + RDoc::Markup::Heading === part && part.text == 'Signature' + + next false unless found_heading + + next true if RDoc::Markup::BlankLine === part + + if RDoc::Markup::Verbatim === part then + signature = part + found_signature = true + end + end + + signature and signature.text + end + + # Public: Creates a new TomDoc parser. See also RDoc::Markup::parse + + def initialize + super + + @section = nil + @seen_returns = false + end + + # Internal: Builds a heading from the token stream + # + # level - The level of heading to create + # + # Returns an RDoc::Markup::Heading + + def build_heading level + heading = super + + @section = heading.text + + heading + end + + # Internal: Builds a verbatim from the token stream. A verbatim in the + # Examples section will be marked as in Ruby format. + # + # margin - The indentation from the margin for lines that belong to this + # verbatim section. + # + # Returns an RDoc::Markup::Verbatim + + def build_verbatim margin + verbatim = super + + verbatim.format = :ruby if @section == 'Examples' + + verbatim + end + + # Internal: Builds a paragraph from the token stream + # + # margin - Unused + # + # Returns an RDoc::Markup::Paragraph. + + def build_paragraph margin + p :paragraph_start => margin if @debug + + paragraph = RDoc::Markup::Paragraph.new + + until @tokens.empty? do + type, data, = get + + case type + when :TEXT then + @section = 'Returns' if data =~ /\AReturns/ + + paragraph << data + when :NEWLINE then + if :TEXT == peek_token[0] then + paragraph << ' ' + else + break + end + else + unget + break + end + end + + p :paragraph_end => margin if @debug + + paragraph + end + + ## + # Detects a section change to "Returns" and adds a heading + + def parse_text parent, indent # :nodoc: + paragraph = build_paragraph indent + + if false == @seen_returns and 'Returns' == @section then + @seen_returns = true + parent << RDoc::Markup::Heading.new(3, 'Returns') + parent << RDoc::Markup::BlankLine.new + end + + parent << paragraph + end + + # Internal: Turns text into an Array of tokens + # + # text - A String containing TomDoc-format text. + # + # Returns self. + + def tokenize text + text.sub!(/\A(Public|Internal|Deprecated):\s+/, '') + + setup_scanner text + + until @s.eos? do + pos = @s.pos + + # leading spaces will be reflected by the column of the next token + # the only thing we loose are trailing spaces at the end of the file + next if @s.scan(/ +/) + + @tokens << case + when @s.scan(/\r?\n/) then + token = [:NEWLINE, @s.matched, *token_pos(pos)] + @line_pos = char_pos @s.pos + @line += 1 + token + when @s.scan(/(Examples|Signature)$/) then + @tokens << [:HEADER, 3, *token_pos(pos)] + + [:TEXT, @s[1], *token_pos(pos)] + when @s.scan(/([:\w][\w\[\]]*)[ ]+- /) then + [:NOTE, @s[1], *token_pos(pos)] + else + @s.scan(/.*/) + [:TEXT, @s.matched.sub(/\r$/, ''), *token_pos(pos)] + end + end + + self + end + +end + |