浏览代码

Merge pull request #705 from jamiely/add-scala-docs

Adds Scala documentation
Jasper van Merle 6 年之前
父节点
当前提交
728c16c398

+ 1 - 0
assets/stylesheets/application.css.scss

@@ -93,6 +93,7 @@
         'pages/rfc',
         'pages/rubydoc',
         'pages/rust',
+        'pages/scala',
         'pages/sinon',
         'pages/socketio',
         'pages/sphinx',

+ 4 - 0
assets/stylesheets/pages/_scala.scss

@@ -0,0 +1,4 @@
+._scala {
+  @extend %simple;
+  .deprecated { @extend %label-red; }
+}

+ 109 - 0
lib/docs/filters/scala/clean_html.rb

@@ -0,0 +1,109 @@
+module Docs
+  class Scala
+    class CleanHtmlFilter < Filter
+      def call
+        @doc = at_css('#content')
+
+        always
+        add_title
+
+        doc
+      end
+
+      def always
+        # Remove deprecated sections
+        css('.members').each do |members|
+          header = members.at_css('h3')
+          members.remove if header.text.downcase.include? 'deprecate'
+        end
+
+        css('#mbrsel, #footer').remove
+
+        css('.diagram-container').remove
+        css('.toggleContainer > .toggle').each do |node|
+          title = node.at_css('span')
+          next if title.nil?
+
+          content = node.at_css('.hiddenContent')
+          next if content.nil?
+
+          title.name = 'dt'
+
+          content.remove_attribute('class')
+          content.remove_attribute('style')
+          content.name = 'dd'
+
+          attributes = at_css('.attributes')
+          unless attributes.nil?
+            title.parent = attributes
+            content.parent = attributes
+          end
+        end
+
+        signature = at_css('#signature')
+        signature.replace "<h2 id=\"signature\">#{signature.inner_html}</h2>"
+
+        css('div.members > h3').each do |node|
+          node.name = 'h2'
+        end
+
+        css('div.members > ol').each do |list|
+          list.css('li').each do |li|
+            h3 = doc.document.create_element 'h3'
+            h3['id'] = li['name'].rpartition('#').last unless li['name'].nil?
+
+            li.prepend_child h3
+            li.css('.shortcomment').remove
+
+            modifier = li.at_css('.modifier_kind')
+            modifier.parent = h3 unless modifier.nil?
+
+            kind = li.at_css('.modifier_kind .kind')
+            kind.content = kind.content + ' ' unless kind.nil?
+
+            symbol = li.at_css('.symbol')
+            symbol.parent = h3 unless symbol.nil?
+
+            li.swap li.children
+          end
+
+          list.swap list.children
+        end
+
+        css('.fullcomment pre, .fullcommenttop pre').each do |pre|
+          pre['data-language'] = 'scala'
+          pre.content = pre.content
+        end
+
+        # Sections of the documentation which do not seem useful
+        %w(#inheritedMembers #groupedMembers .permalink .hiddenContent .material-icons).each do |selector|
+          css(selector).remove
+        end
+
+        # Things that are not shown on the site, like deprecated members
+        css('li[visbl=prt]').remove
+      end
+
+      def add_title
+        css('.permalink').remove
+
+        definition = at_css('#definition')
+        return if definition.nil?
+
+        type_full_name = {a: 'Annotation', c: 'Class', t: 'Trait', o: 'Object', p: 'Package'}
+        type = type_full_name[definition.at_css('.big-circle').text.to_sym]
+        name = CGI.escapeHTML definition.at_css('h1').text
+
+        package = definition.at_css('#owner').text rescue ''
+        package = package + '.' unless name.empty? || package.empty?
+
+        other = definition.at_css('.morelinks').dup
+        other_content = other ? "<h3>#{other.to_html}</h3>" : ''
+
+        title_content = root_page? ? 'Package root' : "#{type} #{package}#{name}".strip
+        title = "<h1>#{title_content}</h1>"
+        definition.replace title + other_content
+      end
+    end
+  end
+end

+ 105 - 0
lib/docs/filters/scala/entries.rb

@@ -0,0 +1,105 @@
+module Docs
+  class Scala
+    class EntriesFilter < Docs::EntriesFilter
+      REPLACEMENTS = {
+        '$eq' => '=',
+        '$colon' => ':',
+        '$less' => '<',
+      }
+
+      def get_name
+        if is_package?
+          symbol = at_css('#definition h1')
+          symbol ? symbol.text.gsub(/\W+/, '') : "package"
+        else
+          name = slug.split('/').last
+
+          # Some objects have inner objects, show ParentObject$.ChildObject$ instead of ParentObject$$ChildObject$
+          name = name.gsub('$$', '$.')
+
+          # If a dollar sign is used as separator between two characters, replace it with a dot
+          name = name.gsub(/([^$.])\$([^$.])/, '\1.\2')
+
+          REPLACEMENTS.each do |key, value|
+            name = name.gsub(key, value)
+          end
+
+          name
+        end
+      end
+
+      def get_type
+        # if this entry is for a package, we group the package under the parent package
+        if is_package?
+          parent_package
+        # otherwise, group it under the regular package name
+        else
+          package_name
+        end
+      end
+
+      def include_default_entry?
+        true
+      end
+
+      def additional_entries
+        entries = []
+
+        full_name = "#{type}.#{name}".remove('$')
+        css(".members li[name^=\"#{full_name}\"]").each do |node|
+          # Ignore packages
+          kind = node.at_css('.modifier_kind > .kind')
+          next if !kind.nil? && kind.content == 'package'
+
+          # Ignore deprecated members
+          next unless node.at_css('.symbol > .name.deprecated').nil?
+
+          id = node['name'].rpartition('#').last
+          member_name = node.at_css('.name')
+
+          # Ignore members only existing of hashtags, we can't link to that
+          next if member_name.nil? || member_name.content.strip.remove('#').blank?
+
+          member = "#{name}.#{member_name.content}()"
+          entries << [member, id]
+        end
+
+        entries
+      end
+
+      private
+
+      # For the package name, we use the slug rather than parsing the package
+      # name from the HTML because companion object classes may be broken out into
+      # their own entries (by the source documentation). When that happens,
+      # we want to group these classes (like `scala.reflect.api.Annotations.Annotation`)
+      # under the package name, and not the fully-qualfied name which would
+      # include the companion object.
+      def package_name
+        name = package_drop_last(slug_parts)
+        name.empty? ? '_root_' : name
+      end
+
+      def parent_package
+        parent = package_drop_last(package_name.split('.'))
+        parent.empty? ? '_root_' : parent
+      end
+
+      def package_drop_last(parts)
+        parts[0...-1].join('.')
+      end
+
+      def slug_parts
+        slug.split('/')
+      end
+
+      def owner
+        at_css('#owner')
+      end
+
+      def is_package?
+        slug.ends_with?('index') || slug.ends_with?('package')
+      end
+    end
+  end
+end

+ 60 - 0
lib/docs/scrapers/scala.rb

@@ -0,0 +1,60 @@
+module Docs
+  class Scala < FileScraper
+    self.name = 'Scala'
+    self.type = 'scala'
+    self.links = {
+      home: 'http://www.scala-lang.org/',
+      code: 'https://github.com/scala/scala'
+    }
+
+    options[:container] = '#content-container'
+    options[:attribution] = <<-HTML
+        &copy; 2002-2019 EPFL, with contributions from Lightbend.
+    HTML
+
+    # https://downloads.lightbend.com/scala/2.13.0/scala-docs-2.13.0.zip
+    # Extract api/scala-library into docs/scala~2.13_library
+    version '2.13 Library' do
+      self.release = '2.13.0'
+      self.base_url = 'https://www.scala-lang.org/api/2.13.0/'
+      self.root_path = 'index.html'
+
+      html_filters.push 'scala/entries', 'scala/clean_html'
+    end
+
+    # https://downloads.lightbend.com/scala/2.13.0/scala-docs-2.13.0.zip
+    # Extract api/scala-reflect into docs/scala~2.13_reflection
+    version '2.13 Reflection' do
+      self.release = '2.13.0'
+      self.base_url = 'https://www.scala-lang.org/api/2.13.0/scala-reflect/'
+      self.root_path = 'index.html'
+
+      html_filters.push 'scala/entries', 'scala/clean_html'
+    end
+
+    # https://downloads.lightbend.com/scala/2.12.6/scala-docs-2.12.6.zip
+    # Extract api/scala-library into docs/scala~2.12_library
+    version '2.12 Library' do
+      self.release = '2.12.6'
+      self.base_url = 'https://www.scala-lang.org/api/2.12.6/'
+      self.root_path = 'index.html'
+
+      html_filters.push 'scala/entries', 'scala/clean_html'
+    end
+
+    # https://downloads.lightbend.com/scala/2.12.6/scala-docs-2.12.6.zip
+    # Extract api/scala-reflect into docs/scala~2.12_reflection
+    version '2.12 Reflection' do
+      self.release = '2.12.6'
+      self.base_url = 'https://www.scala-lang.org/api/2.12.6/scala-reflect/'
+      self.root_path = 'index.html'
+
+      html_filters.push 'scala/entries', 'scala/clean_html'
+    end
+
+    def get_latest_version(opts)
+      doc = fetch_doc('https://www.scala-lang.org/api/current/', opts)
+      doc.at_css('#doc-version').content
+    end
+  end
+end

二进制
public/icons/docs/scala/16.png


二进制
public/icons/docs/scala/16@2x.png