Loading lib/jsduck/doc_parser.rb +65 −41 Original line number Diff line number Diff line Loading @@ -20,7 +20,8 @@ module JsDuck # Unrecognized @tags are left as is into documentation as if they # were normal text. # # @see and {@link} are parsed separately in JsDuck::DocFormatter. # @example, {@img}, {@link} and {@video} are parsed separately in # JsDuck::DocFormatter. # class DocParser def initialize Loading Loading @@ -75,17 +76,11 @@ module JsDuck @linenr = linenr @tags = [] @input = StringScanner.new(purify(input)) parse_loop # The parsing process can leave whitespace at the ends of # doc-strings, here we get rid of it. Additionally null all empty docs @tags.each do |tag| tag[:doc].strip! tag[:doc] = nil if tag[:doc] == "" end # Get rid of empty default tag if @tags.first && @tags.first[:tagname] == :default && !@tags.first[:doc] @tags.shift end clean_empty_docs clean_empty_default_tag @tags end Loading Loading @@ -117,17 +112,27 @@ module JsDuck return result.join("\n") end def add_tag(tag) @tags << @current_tag = {:tagname => tag, :doc => ""} # The parsing process can leave whitespace at the ends of # doc-strings, here we get rid of it. # Additionally null all empty docs. def clean_empty_docs @tags.each do |tag| tag[:doc].strip! tag[:doc] = nil if tag[:doc] == "" end end def remove_last_tag @tags.pop @current_tag = @tags.last # Gets rid of empty default tag def clean_empty_default_tag if @tags.first && @tags.first[:tagname] == :default && !@tags.first[:doc] @tags.shift end end # The main loop of the DocParser def parse_loop add_tag(:default) while !@input.eos? do if look(/@/) parse_at_tag Loading @@ -137,29 +142,6 @@ module JsDuck end end # Skips until the beginning of next @tag. # # There must be space before the next @tag - this ensures that we # don't detect tags inside "foo@example.com" or "{@link}". # # Also check that the @tag is not part of an indented code block - # in which case we also ignore the tag. def skip_to_next_at_tag @current_tag[:doc] += match(/[^@]+/) while look(/@/) && (!prev_char_is_whitespace? || indented_as_code?) @current_tag[:doc] += match(/@+[^@]+/) end end def prev_char_is_whitespace? @current_tag[:doc][-1,1] =~ /\s/ end def indented_as_code? @current_tag[:doc] =~ /^ {4,}[^\n]*\Z/ end # Processes anything beginning with @-sign. # # - When @ is not followed by any word chards, do nothing. Loading @@ -178,7 +160,7 @@ module JsDuck send(*tagdef) elsif tagdef = @meta_tags[name] match(/\w+/) meta_at_tag(tagdef) parse_meta_tag(tagdef) else Logger.warn(:tag, "Unsupported tag: @#{name}", @filename, @linenr) @current_tag[:doc] += "@" Loading @@ -186,7 +168,7 @@ module JsDuck end # Matches the given meta-tag def meta_at_tag(tag) def parse_meta_tag(tag) prev_tag = @current_tag add_tag(:meta) Loading @@ -210,6 +192,33 @@ module JsDuck end end # Skips until the beginning of next @tag. # # There must be space before the next @tag - this ensures that we # don't detect tags inside "foo@example.com" or "{@link}". # # Also check that the @tag is not part of an indented code block - # in which case we also ignore the tag. def skip_to_next_at_tag @current_tag[:doc] += match(/[^@]+/) while look(/@/) && (!prev_char_is_whitespace? || indented_as_code?) @current_tag[:doc] += match(/@+[^@]+/) end end def prev_char_is_whitespace? @current_tag[:doc][-1,1] =~ /\s/ end def indented_as_code? @current_tag[:doc] =~ /^ {4,}[^\n]*\Z/ end # # Routines for parsing of concrete tags... # # matches @<tagname> [ classname ] # Used for @class, @extends, @member def class_at_tag(tagname, property_name) Loading Loading @@ -395,6 +404,21 @@ module JsDuck skip_white end # # Parsing helpers ... # # Appends new @tag to parsed tags list def add_tag(tag) @tags << @current_tag = {:tagname => tag, :doc => ""} end # Forgets the previously parsed tag def remove_last_tag @tags.pop @current_tag = @tags.last end # matches {type} if possible and sets it on @current_tag # Also checks for {optionality=} in type definition. def maybe_type Loading Loading
lib/jsduck/doc_parser.rb +65 −41 Original line number Diff line number Diff line Loading @@ -20,7 +20,8 @@ module JsDuck # Unrecognized @tags are left as is into documentation as if they # were normal text. # # @see and {@link} are parsed separately in JsDuck::DocFormatter. # @example, {@img}, {@link} and {@video} are parsed separately in # JsDuck::DocFormatter. # class DocParser def initialize Loading Loading @@ -75,17 +76,11 @@ module JsDuck @linenr = linenr @tags = [] @input = StringScanner.new(purify(input)) parse_loop # The parsing process can leave whitespace at the ends of # doc-strings, here we get rid of it. Additionally null all empty docs @tags.each do |tag| tag[:doc].strip! tag[:doc] = nil if tag[:doc] == "" end # Get rid of empty default tag if @tags.first && @tags.first[:tagname] == :default && !@tags.first[:doc] @tags.shift end clean_empty_docs clean_empty_default_tag @tags end Loading Loading @@ -117,17 +112,27 @@ module JsDuck return result.join("\n") end def add_tag(tag) @tags << @current_tag = {:tagname => tag, :doc => ""} # The parsing process can leave whitespace at the ends of # doc-strings, here we get rid of it. # Additionally null all empty docs. def clean_empty_docs @tags.each do |tag| tag[:doc].strip! tag[:doc] = nil if tag[:doc] == "" end end def remove_last_tag @tags.pop @current_tag = @tags.last # Gets rid of empty default tag def clean_empty_default_tag if @tags.first && @tags.first[:tagname] == :default && !@tags.first[:doc] @tags.shift end end # The main loop of the DocParser def parse_loop add_tag(:default) while !@input.eos? do if look(/@/) parse_at_tag Loading @@ -137,29 +142,6 @@ module JsDuck end end # Skips until the beginning of next @tag. # # There must be space before the next @tag - this ensures that we # don't detect tags inside "foo@example.com" or "{@link}". # # Also check that the @tag is not part of an indented code block - # in which case we also ignore the tag. def skip_to_next_at_tag @current_tag[:doc] += match(/[^@]+/) while look(/@/) && (!prev_char_is_whitespace? || indented_as_code?) @current_tag[:doc] += match(/@+[^@]+/) end end def prev_char_is_whitespace? @current_tag[:doc][-1,1] =~ /\s/ end def indented_as_code? @current_tag[:doc] =~ /^ {4,}[^\n]*\Z/ end # Processes anything beginning with @-sign. # # - When @ is not followed by any word chards, do nothing. Loading @@ -178,7 +160,7 @@ module JsDuck send(*tagdef) elsif tagdef = @meta_tags[name] match(/\w+/) meta_at_tag(tagdef) parse_meta_tag(tagdef) else Logger.warn(:tag, "Unsupported tag: @#{name}", @filename, @linenr) @current_tag[:doc] += "@" Loading @@ -186,7 +168,7 @@ module JsDuck end # Matches the given meta-tag def meta_at_tag(tag) def parse_meta_tag(tag) prev_tag = @current_tag add_tag(:meta) Loading @@ -210,6 +192,33 @@ module JsDuck end end # Skips until the beginning of next @tag. # # There must be space before the next @tag - this ensures that we # don't detect tags inside "foo@example.com" or "{@link}". # # Also check that the @tag is not part of an indented code block - # in which case we also ignore the tag. def skip_to_next_at_tag @current_tag[:doc] += match(/[^@]+/) while look(/@/) && (!prev_char_is_whitespace? || indented_as_code?) @current_tag[:doc] += match(/@+[^@]+/) end end def prev_char_is_whitespace? @current_tag[:doc][-1,1] =~ /\s/ end def indented_as_code? @current_tag[:doc] =~ /^ {4,}[^\n]*\Z/ end # # Routines for parsing of concrete tags... # # matches @<tagname> [ classname ] # Used for @class, @extends, @member def class_at_tag(tagname, property_name) Loading Loading @@ -395,6 +404,21 @@ module JsDuck skip_white end # # Parsing helpers ... # # Appends new @tag to parsed tags list def add_tag(tag) @tags << @current_tag = {:tagname => tag, :doc => ""} end # Forgets the previously parsed tag def remove_last_tag @tags.pop @current_tag = @tags.last end # matches {type} if possible and sets it on @current_tag # Also checks for {optionality=} in type definition. def maybe_type Loading