Commit 7c7a874c authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Move source related classes to source/ subdir.

parent 7793b1ab
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
require 'rubygems'
require 'jsduck/aggregator'
require 'jsduck/source_file'
require 'jsduck/source/file'
require 'jsduck/source/writer'
require 'jsduck/doc_formatter'
require 'jsduck/class_formatter'
require 'jsduck/class'
@@ -16,7 +17,6 @@ require 'jsduck/return_values'
require 'jsduck/lint'
require 'jsduck/template_dir'
require 'jsduck/class_writer'
require 'jsduck/source_writer'
require 'jsduck/app_data'
require 'jsduck/index_html'
require 'jsduck/exporter/api'
@@ -85,7 +85,7 @@ module JsDuck
        # between source files and classes. Therefore it MUST to be done
        # after writing sources which needs the links to work.
        if @opts.source
          source_writer = SourceWriter.new(parsed_files)
          source_writer = Source::Writer.new(parsed_files)
          source_writer.write(@opts.output_dir + "/source")
        end
        format_classes
@@ -109,7 +109,7 @@ module JsDuck
      ParallelWrap.map(filenames) do |fname|
        Logger.instance.log("Parsing", fname)
        begin
          SourceFile.new(JsDuck::IO.read(fname), fname, @opts)
          Source::File.new(JsDuck::IO.read(fname), fname, @opts)
        rescue
          Logger.instance.fatal_backtrace("Error while parsing #{fname}", $!)
          exit(1)
+98 −0
Original line number Diff line number Diff line
require 'jsduck/source/file_parser'
require 'jsduck/html'

module JsDuck
  module Source

    # Represents one JavaScript or CSS source file.
    #
    # The filename parameter determines whether it's parsed as
    # JavaScript (the default) or CSS.
    class File
      attr_reader :filename
      attr_reader :contents
      attr_reader :docs
      attr_reader :html_filename

      def initialize(contents, filename="", options={})
        @contents = contents
        @filename = filename
        @html_filename = ""
        @links = {}

        @docs = Source::FileParser.new.parse(@contents, @filename, options)

        @docs.map do |docset|
          link(docset[:linenr], docset)
        end
      end

      # loops through each doc-object in file
      def each(&block)
        @docs.each(&block)
      end

      # Sets the html filename of this file,
      # updating also all doc-objects linking this file
      def html_filename=(html_filename)
        @html_filename = html_filename
        @links.each_value do |line|
          line.each do |link|
            link[:file][:html_filename] = @html_filename
            link[:file][:href] = @html_filename + "#" + id(link[:doc])
          end
        end
      end

      # Returns source code as HTML with lines starting doc-comments specially marked.
      def to_html
        linenr = 0
        lines = []
        # Use #each_line instead of #lines to support Ruby 1.6
        @contents.each_line do |line|
          linenr += 1;
          line = HTML.escape(line)
          # wrap the line in as many spans as there are links to this line number.
          if @links[linenr]
            @links[linenr].each do |link|
              line = "<span id='#{id(link[:doc])}'>#{line}</span>"
            end
          end
          lines << line
        end
        lines.join()
      end

      def id(doc)
        if doc[:tagname] == :class
          doc[:name].gsub(/\./, '-')
        else
          # when creation of global class is skipped,
          # this owner property can be nil.
          (doc[:owner] || "global").gsub(/\./, '-') + "-" + doc[:id]
        end
      end

      private

      # Creates two-way link between sourcefile and doc-object.
      # If doc-object is class, links also the contained cfgs and constructor.
      # Returns the modified doc-object after done.
      def link(linenr, doc)
        @links[linenr] = [] unless @links[linenr]
        file = {
          :filename => @filename,
          :linenr => linenr,
        }
        @links[linenr] << {:doc => doc, :file => file}
        doc[:files] = [file]
        if doc[:tagname] == :class
          doc[:members].each {|m| link(linenr, m) }
        end
        doc
      end

    end

  end
end
+72 −0
Original line number Diff line number Diff line
require 'jsduck/js_parser'
require 'jsduck/css_parser'
require 'jsduck/doc_parser'
require 'jsduck/merger'
require 'jsduck/ast'
require 'jsduck/doc_type'
require 'jsduck/doc_ast'
require 'jsduck/class_doc_expander'

module JsDuck
  module Source

    # Performs the actual parsing of CSS or JS source.
    #
    # This is the class that brings together all the different steps of
    # parsing the source.
    class FileParser

      def initialize
        @doc_type = DocType.new
        @doc_parser = DocParser.new
        @class_doc_expander = ClassDocExpander.new
        @doc_ast = DocAst.new
        @merger = Merger.new
      end

      # Parses file into final docset that can be fed into Aggregator
      def parse(contents, filename="", options={})
        @doc_ast.filename = filename

        parse_js_or_css(contents, filename, options).map do |docset|
          expand(docset)
        end.flatten.map do |docset|
          merge(docset)
        end
      end

      private

      # Parses the file depending on filename as JS or CSS
      def parse_js_or_css(contents, filename, options)
        if filename =~ /\.s?css$/
          docs = CssParser.new(contents, options).parse
        else
          docs = JsParser.new(contents, options).parse
          docs = Ast.new(docs, options).detect_all!
        end
      end

      # Parses the docs, detects tagname and expands class docset
      def expand(docset)
        docset[:comment] = @doc_parser.parse(docset[:comment])
        docset[:tagname] = @doc_type.detect(docset[:comment], docset[:code])

        if docset[:tagname] == :class
          @class_doc_expander.expand(docset)
        else
          docset
        end
      end

      # Merges comment and code parts of docset
      def merge(docset)
        @doc_ast.linenr = docset[:linenr]
        docset[:comment] = @doc_ast.detect(docset[:tagname], docset[:comment])

        @merger.merge(docset)
      end
    end

  end
end
+89 −0
Original line number Diff line number Diff line
@@ -3,9 +3,10 @@ require 'jsduck/parallel_wrap'
require 'fileutils'

module JsDuck
  module Source

    # Writes HTML JavaScript/CSS source into HTML files.
  class SourceWriter
    class Writer
      def initialize(source_files)
        @source_files = source_files
      end
@@ -49,11 +50,11 @@ module JsDuck
      # html_filename("Foo.js", 2) => "Foo3.html"
      #
      def html_filename(filename, nr=0)
      File.basename(filename, ".js") + (nr > 0 ? (nr+1).to_s : "") + ".html"
        ::File.basename(filename, ".js") + (nr > 0 ? (nr+1).to_s : "") + ".html"
      end

      def write_single(filename, source)
      File.open(filename, 'w') {|f| f.write(wrap_page(source)) }
        ::File.open(filename, 'w') {|f| f.write(wrap_page(source)) }
      end

      # Returns source wrapped inside HTML page
@@ -85,3 +86,4 @@ module JsDuck
    end

  end
end

lib/jsduck/source_file.rb

deleted100644 → 0
+0 −96
Original line number Diff line number Diff line
require 'jsduck/source_file_parser'
require 'jsduck/html'

module JsDuck

  # Represents one JavaScript or CSS source file.
  #
  # The filename parameter determines whether it's parsed as
  # JavaScript (the default) or CSS.
  class SourceFile
    attr_reader :filename
    attr_reader :contents
    attr_reader :docs
    attr_reader :html_filename

    def initialize(contents, filename="", options={})
      @contents = contents
      @filename = filename
      @html_filename = ""
      @links = {}

      @docs = SourceFileParser.new.parse(@contents, @filename, options)

      @docs.map do |docset|
        link(docset[:linenr], docset)
      end
    end

    # loops through each doc-object in file
    def each(&block)
      @docs.each(&block)
    end

    # Sets the html filename of this file,
    # updating also all doc-objects linking this file
    def html_filename=(html_filename)
      @html_filename = html_filename
      @links.each_value do |line|
        line.each do |link|
          link[:file][:html_filename] = @html_filename
          link[:file][:href] = @html_filename + "#" + id(link[:doc])
        end
      end
    end

    # Returns source code as HTML with lines starting doc-comments specially marked.
    def to_html
      linenr = 0
      lines = []
      # Use #each_line instead of #lines to support Ruby 1.6
      @contents.each_line do |line|
        linenr += 1;
        line = HTML.escape(line)
        # wrap the line in as many spans as there are links to this line number.
        if @links[linenr]
          @links[linenr].each do |link|
            line = "<span id='#{id(link[:doc])}'>#{line}</span>"
          end
        end
        lines << line
      end
      lines.join()
    end

    def id(doc)
      if doc[:tagname] == :class
        doc[:name].gsub(/\./, '-')
      else
        # when creation of global class is skipped,
        # this owner property can be nil.
        (doc[:owner] || "global").gsub(/\./, '-') + "-" + doc[:id]
      end
    end

    private

    # Creates two-way link between sourcefile and doc-object.
    # If doc-object is class, links also the contained cfgs and constructor.
    # Returns the modified doc-object after done.
    def link(linenr, doc)
      @links[linenr] = [] unless @links[linenr]
      file = {
        :filename => @filename,
        :linenr => linenr,
      }
      @links[linenr] << {:doc => doc, :file => file}
      doc[:files] = [file]
      if doc[:tagname] == :class
        doc[:members].each {|m| link(linenr, m) }
      end
      doc
    end

  end

end
Loading