Skip to content

Commit 728c16c

Browse files
authored
Merge pull request #705 from jamiely/add-scala-docs
Adds Scala documentation
2 parents 85d591e + 6614375 commit 728c16c

File tree

7 files changed

+279
-0
lines changed

7 files changed

+279
-0
lines changed

assets/stylesheets/application.css.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
'pages/rfc',
9494
'pages/rubydoc',
9595
'pages/rust',
96+
'pages/scala',
9697
'pages/sinon',
9798
'pages/socketio',
9899
'pages/sphinx',

assets/stylesheets/pages/_scala.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
._scala {
2+
@extend %simple;
3+
.deprecated { @extend %label-red; }
4+
}

lib/docs/filters/scala/clean_html.rb

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
module Docs
2+
class Scala
3+
class CleanHtmlFilter < Filter
4+
def call
5+
@doc = at_css('#content')
6+
7+
always
8+
add_title
9+
10+
doc
11+
end
12+
13+
def always
14+
# Remove deprecated sections
15+
css('.members').each do |members|
16+
header = members.at_css('h3')
17+
members.remove if header.text.downcase.include? 'deprecate'
18+
end
19+
20+
css('#mbrsel, #footer').remove
21+
22+
css('.diagram-container').remove
23+
css('.toggleContainer > .toggle').each do |node|
24+
title = node.at_css('span')
25+
next if title.nil?
26+
27+
content = node.at_css('.hiddenContent')
28+
next if content.nil?
29+
30+
title.name = 'dt'
31+
32+
content.remove_attribute('class')
33+
content.remove_attribute('style')
34+
content.name = 'dd'
35+
36+
attributes = at_css('.attributes')
37+
unless attributes.nil?
38+
title.parent = attributes
39+
content.parent = attributes
40+
end
41+
end
42+
43+
signature = at_css('#signature')
44+
signature.replace "<h2 id=\"signature\">#{signature.inner_html}</h2>"
45+
46+
css('div.members > h3').each do |node|
47+
node.name = 'h2'
48+
end
49+
50+
css('div.members > ol').each do |list|
51+
list.css('li').each do |li|
52+
h3 = doc.document.create_element 'h3'
53+
h3['id'] = li['name'].rpartition('#').last unless li['name'].nil?
54+
55+
li.prepend_child h3
56+
li.css('.shortcomment').remove
57+
58+
modifier = li.at_css('.modifier_kind')
59+
modifier.parent = h3 unless modifier.nil?
60+
61+
kind = li.at_css('.modifier_kind .kind')
62+
kind.content = kind.content + ' ' unless kind.nil?
63+
64+
symbol = li.at_css('.symbol')
65+
symbol.parent = h3 unless symbol.nil?
66+
67+
li.swap li.children
68+
end
69+
70+
list.swap list.children
71+
end
72+
73+
css('.fullcomment pre, .fullcommenttop pre').each do |pre|
74+
pre['data-language'] = 'scala'
75+
pre.content = pre.content
76+
end
77+
78+
# Sections of the documentation which do not seem useful
79+
%w(#inheritedMembers #groupedMembers .permalink .hiddenContent .material-icons).each do |selector|
80+
css(selector).remove
81+
end
82+
83+
# Things that are not shown on the site, like deprecated members
84+
css('li[visbl=prt]').remove
85+
end
86+
87+
def add_title
88+
css('.permalink').remove
89+
90+
definition = at_css('#definition')
91+
return if definition.nil?
92+
93+
type_full_name = {a: 'Annotation', c: 'Class', t: 'Trait', o: 'Object', p: 'Package'}
94+
type = type_full_name[definition.at_css('.big-circle').text.to_sym]
95+
name = CGI.escapeHTML definition.at_css('h1').text
96+
97+
package = definition.at_css('#owner').text rescue ''
98+
package = package + '.' unless name.empty? || package.empty?
99+
100+
other = definition.at_css('.morelinks').dup
101+
other_content = other ? "<h3>#{other.to_html}</h3>" : ''
102+
103+
title_content = root_page? ? 'Package root' : "#{type} #{package}#{name}".strip
104+
title = "<h1>#{title_content}</h1>"
105+
definition.replace title + other_content
106+
end
107+
end
108+
end
109+
end

lib/docs/filters/scala/entries.rb

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
module Docs
2+
class Scala
3+
class EntriesFilter < Docs::EntriesFilter
4+
REPLACEMENTS = {
5+
'$eq' => '=',
6+
'$colon' => ':',
7+
'$less' => '<',
8+
}
9+
10+
def get_name
11+
if is_package?
12+
symbol = at_css('#definition h1')
13+
symbol ? symbol.text.gsub(/\W+/, '') : "package"
14+
else
15+
name = slug.split('/').last
16+
17+
# Some objects have inner objects, show ParentObject$.ChildObject$ instead of ParentObject$$ChildObject$
18+
name = name.gsub('$$', '$.')
19+
20+
# If a dollar sign is used as separator between two characters, replace it with a dot
21+
name = name.gsub(/([^$.])\$([^$.])/, '\1.\2')
22+
23+
REPLACEMENTS.each do |key, value|
24+
name = name.gsub(key, value)
25+
end
26+
27+
name
28+
end
29+
end
30+
31+
def get_type
32+
# if this entry is for a package, we group the package under the parent package
33+
if is_package?
34+
parent_package
35+
# otherwise, group it under the regular package name
36+
else
37+
package_name
38+
end
39+
end
40+
41+
def include_default_entry?
42+
true
43+
end
44+
45+
def additional_entries
46+
entries = []
47+
48+
full_name = "#{type}.#{name}".remove('$')
49+
css(".members li[name^=\"#{full_name}\"]").each do |node|
50+
# Ignore packages
51+
kind = node.at_css('.modifier_kind > .kind')
52+
next if !kind.nil? && kind.content == 'package'
53+
54+
# Ignore deprecated members
55+
next unless node.at_css('.symbol > .name.deprecated').nil?
56+
57+
id = node['name'].rpartition('#').last
58+
member_name = node.at_css('.name')
59+
60+
# Ignore members only existing of hashtags, we can't link to that
61+
next if member_name.nil? || member_name.content.strip.remove('#').blank?
62+
63+
member = "#{name}.#{member_name.content}()"
64+
entries << [member, id]
65+
end
66+
67+
entries
68+
end
69+
70+
private
71+
72+
# For the package name, we use the slug rather than parsing the package
73+
# name from the HTML because companion object classes may be broken out into
74+
# their own entries (by the source documentation). When that happens,
75+
# we want to group these classes (like `scala.reflect.api.Annotations.Annotation`)
76+
# under the package name, and not the fully-qualfied name which would
77+
# include the companion object.
78+
def package_name
79+
name = package_drop_last(slug_parts)
80+
name.empty? ? '_root_' : name
81+
end
82+
83+
def parent_package
84+
parent = package_drop_last(package_name.split('.'))
85+
parent.empty? ? '_root_' : parent
86+
end
87+
88+
def package_drop_last(parts)
89+
parts[0...-1].join('.')
90+
end
91+
92+
def slug_parts
93+
slug.split('/')
94+
end
95+
96+
def owner
97+
at_css('#owner')
98+
end
99+
100+
def is_package?
101+
slug.ends_with?('index') || slug.ends_with?('package')
102+
end
103+
end
104+
end
105+
end

lib/docs/scrapers/scala.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
module Docs
2+
class Scala < FileScraper
3+
self.name = 'Scala'
4+
self.type = 'scala'
5+
self.links = {
6+
home: 'http://www.scala-lang.org/',
7+
code: 'https://github.com/scala/scala'
8+
}
9+
10+
options[:container] = '#content-container'
11+
options[:attribution] = <<-HTML
12+
&copy; 2002-2019 EPFL, with contributions from Lightbend.
13+
HTML
14+
15+
# https://downloads.lightbend.com/scala/2.13.0/scala-docs-2.13.0.zip
16+
# Extract api/scala-library into docs/scala~2.13_library
17+
version '2.13 Library' do
18+
self.release = '2.13.0'
19+
self.base_url = 'https://www.scala-lang.org/api/2.13.0/'
20+
self.root_path = 'index.html'
21+
22+
html_filters.push 'scala/entries', 'scala/clean_html'
23+
end
24+
25+
# https://downloads.lightbend.com/scala/2.13.0/scala-docs-2.13.0.zip
26+
# Extract api/scala-reflect into docs/scala~2.13_reflection
27+
version '2.13 Reflection' do
28+
self.release = '2.13.0'
29+
self.base_url = 'https://www.scala-lang.org/api/2.13.0/scala-reflect/'
30+
self.root_path = 'index.html'
31+
32+
html_filters.push 'scala/entries', 'scala/clean_html'
33+
end
34+
35+
# https://downloads.lightbend.com/scala/2.12.6/scala-docs-2.12.6.zip
36+
# Extract api/scala-library into docs/scala~2.12_library
37+
version '2.12 Library' do
38+
self.release = '2.12.6'
39+
self.base_url = 'https://www.scala-lang.org/api/2.12.6/'
40+
self.root_path = 'index.html'
41+
42+
html_filters.push 'scala/entries', 'scala/clean_html'
43+
end
44+
45+
# https://downloads.lightbend.com/scala/2.12.6/scala-docs-2.12.6.zip
46+
# Extract api/scala-reflect into docs/scala~2.12_reflection
47+
version '2.12 Reflection' do
48+
self.release = '2.12.6'
49+
self.base_url = 'https://www.scala-lang.org/api/2.12.6/scala-reflect/'
50+
self.root_path = 'index.html'
51+
52+
html_filters.push 'scala/entries', 'scala/clean_html'
53+
end
54+
55+
def get_latest_version(opts)
56+
doc = fetch_doc('https://www.scala-lang.org/api/current/', opts)
57+
doc.at_css('#doc-version').content
58+
end
59+
end
60+
end

public/icons/docs/scala/16.png

944 Bytes
Loading
1.8 KB
Loading

0 commit comments

Comments
 (0)