Skip to content

Commit b9fd5fa

Browse files
committed
Merge branch 'romeovs-master'
* romeovs-master: make flex work with webkit fix correct index fix tables to work everywhere, add comments clean up complexity notation and deprecated, better caption handling add haskell logos get the thing working for haskell start adding haskell scraper
2 parents dbf4217 + 923fc90 commit b9fd5fa

File tree

6 files changed

+360
-0
lines changed

6 files changed

+360
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
._icon-haskell:before {
2+
background-image: image-url('/icons/docs/haskell/16.png');
3+
background-size: cover;
4+
background-repeat: no-repeat;
5+
}
6+
7+
.empty-table .empty {
8+
display: none;
9+
}
10+
11+
.arguments td.src {
12+
background: #faf9e2;
13+
width: 30%;
14+
}
15+
16+
th.src,
17+
td.src {
18+
font-family: $monoFont;
19+
font-weight: normal;
20+
font-style: normal;
21+
background: #f8f8f8;
22+
}
23+
24+
caption {
25+
font-weight: bold;
26+
text-align: left;
27+
font-style: italic;
28+
font-size: 1.1em;
29+
}
30+
31+
// remove margin in descript listing
32+
dd > pre {
33+
@extend %pre;
34+
margin: 0;
35+
background: #faf9e2;
36+
border-color: #dddaaa #dddaaa #d7d7a9;
37+
}
38+
39+
// warnings are red
40+
.warning {
41+
@extend %note;
42+
@extend %note-red;
43+
}
44+
45+
46+
// complexity classes are blue boxes
47+
.with-complexity {
48+
display: flex;
49+
display: -webkit-flex;
50+
51+
justify-content: space-between;
52+
-webkit-justify-content: space-between;
53+
54+
align-items: flex-start;
55+
-webkit-align-items: flex-start;
56+
57+
align-content: stretch;
58+
-webkit-align-content: stretch;
59+
}
60+
61+
.complexity {
62+
@extend %note;
63+
@extend %note-blue;
64+
margin: 0;
65+
margin-left: 1em;
66+
margin-bottom: 0.75em;
67+
font-style: italic;
68+
white-space: nowrap;
69+
70+
flex-shrink: 0;
71+
-webkit-flex-shrink: 0;
72+
73+
order: 2;
74+
-webkit-order: 2;
75+
}
76+
77+
.complexity + span {
78+
order: 1;
79+
-webkit-order: 1;
80+
}
81+
82+
// add box type to "since: ..."
83+
.added {
84+
@extend %note;
85+
@extend %note-gold;
86+
}
87+
88+
.added-cell {
89+
@extend %note-gold;
90+
}
91+
92+
.fields h3 {
93+
display: none;
94+
}
95+
96+
// separate types more
97+
.src {
98+
margin-top: 2.5em;
99+
}
100+
101+
h1 + .top .src,
102+
h2 + .top .src,
103+
h3 + .top .src,
104+
.caption + .top .src {
105+
margin-top: 0;
106+
}
107+
108+
// but not for first type
109+
h1 + .top,
110+
h2 + .top,
111+
h3 + .top,
112+
h4 + .top {
113+
margin-top: 0;
114+
}
115+
116+
// change color of example code
117+
.example {
118+
border: 1px solid;
119+
background: #faf9e2;
120+
border-color: #dddaaa #dddaaa #d7d7a9;
121+
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
module Docs
2+
class Haskell
3+
class CleanHtmlFilter < Filter
4+
def call
5+
6+
# remove unwanted elements
7+
css('#footer', '#package-header', '#module-header', '#synopsis', '.link', '#table-of-contents', '.package').remove
8+
9+
# cpations in tables are h3
10+
css('table .caption').each do |node|
11+
node.name = 'h3'
12+
end
13+
14+
# turn captions into real headers
15+
css('.caption').each do |node|
16+
node.name = 'h1'
17+
end
18+
19+
# section
20+
css('.top > .caption').each do |node|
21+
node.name = 'h2'
22+
end
23+
24+
# subsections
25+
css('.top > .subs > .caption', '.fields > .caption').each do |node|
26+
node.name = 'h3'
27+
end
28+
29+
# subsubsections
30+
css('.top > .subs > .subs > .caption').each do |node|
31+
node.name = 'h4'
32+
end
33+
34+
# ...
35+
css('.top > .subs > .subs > .subs > .caption').each do |node|
36+
node.name = 'h5'
37+
end
38+
39+
# ......
40+
css('.top > .subs > .subs > .subs > .subs > .caption').each do |node|
41+
node.name = 'h6'
42+
end
43+
44+
# all pre's are examples
45+
css('pre').each do |node|
46+
node.add_css_class('example')
47+
end
48+
49+
# turn source listing in to pre
50+
css('.src').each do |node|
51+
if node.name != "td"
52+
node.name = 'pre'
53+
end
54+
end
55+
56+
# check if second column of table is totally empty.
57+
# and remove it if it is
58+
css('table').each do |table|
59+
empty = true
60+
table.css('td + td').each do |snd|
61+
empty = empty && snd['class'] =~ /empty/
62+
end
63+
if empty
64+
# remove empty column
65+
table.css('td + td').remove
66+
end
67+
end
68+
69+
# move table captions into the tables
70+
css(".caption + table").each do |table|
71+
caption = table.previous
72+
caption.name = "caption"
73+
caption.parent = table
74+
end
75+
76+
css(".caption + .show table").each do |table|
77+
caption = table.parent.parent.css('.caption')[0]
78+
caption.name = 'caption'
79+
caption.parent = table
80+
end
81+
82+
# better arguments display:
83+
css('.src + .arguments table').each do |table|
84+
src = table.parent.previous # the function name
85+
row = doc.document.create_element('tr')
86+
table.css('tr')[0].before(row)
87+
src.parent = row
88+
src.name = "th"
89+
src['colspan'] = 2
90+
end
91+
92+
# remove root page title
93+
if root_page?
94+
at_css('h1').remove
95+
end
96+
97+
# add id to links (based on name)
98+
css('a').each do |node|
99+
if node['name']
100+
node['id'] = node['name']
101+
end
102+
end
103+
104+
# make code in description into proper pre
105+
css('dd > code').each do |node|
106+
node.name = 'pre'
107+
end
108+
109+
# add some informational boxes
110+
css('em').each do |node|
111+
if node.content == 'Deprecated.'
112+
# Make deprecated messages red.
113+
node.parent.add_css_class('warning')
114+
elsif node.content =~ /O\(.*\)/
115+
# this is big_O notation, but only apply the class if this is not
116+
# inside running text (it must be at the start of a paragraph)
117+
# from:
118+
# <p><em>O(n)</em>. Koel ok</p>
119+
# to:
120+
# <p class="with-complexity">
121+
# <span class="complexity">O(n)</span>
122+
# <span>Koel ok</span>
123+
# </p>
124+
if node.previous == nil
125+
node.add_css_class('complexity') # add css class
126+
node.name="span" # just make it div
127+
node.next.content = node.next.content.gsub(/^. /, "") # remove . if directly after em
128+
node.content = node.content.gsub(/\.$/, "") # remove trailing . if it's inside em
129+
130+
# reparent the nodes
131+
cont = doc.document.create_element "p", :class => "with-complexity"
132+
node.parent.previous = cont
133+
par = node.parent
134+
node.parent = cont
135+
par.parent = cont
136+
par.name = "span"
137+
end
138+
elsif node.content =~ /Since: .*/
139+
# add box to 'Since:' annotations
140+
if node.parent.parent.name == "td"
141+
node.parent.parent.add_css_class('added-cell')
142+
else
143+
node.add_css_class('added')
144+
end
145+
end
146+
end
147+
148+
doc
149+
end
150+
end
151+
end
152+
end
153+
154+
class Nokogiri::XML::Node
155+
def add_css_class( *classes )
156+
existing = (self['class'] || "").split(/\s+/)
157+
self['class'] = existing.concat(classes).uniq.join(" ")
158+
end
159+
end

lib/docs/filters/haskell/entries.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module Docs
2+
class Haskell
3+
class EntriesFilter < Docs::EntriesFilter
4+
5+
# gets name and type in one fell swoop
6+
#
7+
# eg.
8+
# Control.Monad > [Monad, Control]
9+
# Control.Concurrent.Mvar > [Concurrent.MVar, Control]
10+
# Array > [Array, nil]
11+
def get_name_and_type
12+
if at_css('h1') && at_css('h1').content == 'Haskell Hierarchical Libraries'
13+
puts 'ok'
14+
name = 'Haskell'
15+
type = nil
16+
else
17+
# find full module identifier
18+
caption = at_css('#module-header .caption')
19+
20+
if caption
21+
# split the module path
22+
parts = caption.content.split('.')
23+
24+
if parts.length > 1
25+
# if more than one part then the
26+
# first is the type and the rest is the name
27+
type = parts[0]
28+
name = parts.drop(1).join('.')
29+
else
30+
# if only one part, this is the name
31+
name = parts[0]
32+
type = nil
33+
end
34+
else
35+
# no caption found -> no type / no name
36+
name = 'no-name'
37+
type = 'no-type'
38+
end
39+
end
40+
[name, type]
41+
end
42+
43+
# get the name
44+
def get_name
45+
n, t = get_name_and_type()
46+
n
47+
end
48+
49+
# get the type
50+
def get_type
51+
n, t = get_name_and_type()
52+
t
53+
end
54+
end
55+
end
56+
end

lib/docs/scrapers/haskell.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Docs
2+
class Haskell < UrlScraper
3+
self.name = 'Haskell'
4+
self.slug = 'haskell'
5+
self.type = 'haskell'
6+
self.version = '7.8.2'
7+
self.base_url = 'http://www.haskell.org/ghc/docs/7.8.2/html/libraries/'
8+
self.initial_paths = ['/index.html']
9+
10+
html_filters.push 'haskell/entries'
11+
html_filters.push 'haskell/clean_html'
12+
html_filters.push 'title'
13+
14+
15+
options[:container] = '#content'
16+
options[:skip_patterns] = [/src/, /index/, /haskell2010/, /ghc-/, /Cabal-/] # skip source listings and index files
17+
18+
options[:attribution] = <<-HTML
19+
&copy; The University Court of the University of Glasgow.<br>
20+
All rights reserved. <a href="http://www.haskell.org/ghc/license">See here for more info</a>
21+
HTML
22+
23+
end
24+
end

public/icons/docs/haskell/16.png

994 Bytes
Loading

public/icons/docs/haskell/16@2x.png

1.26 KB
Loading

0 commit comments

Comments
 (0)