History

Merge pull request #1439 from scherepn/gtk

Add GTK documentation

Simon Legner committed 5 years ago

Commit 6fd5b992 parents eb49b10 87b0f4b12 files · +386 −-1Browse files

Unified · Split

12 files
  1. assets/javascripts/news.json +4 −0
  2. assets/javascripts/templates/pages/about_tmpl.coffee +5 −0
  3. assets/stylesheets/application.css.scss +2 −1
  4. assets/stylesheets/pages/_gtk.scss +15 −0
  5. docs/scraper-reference.md +18 −0
  6. lib/docs/core/doc.rb +4 −0
  7. lib/docs/filters/gtk/clean_html.rb +69 −0
  8. lib/docs/filters/gtk/entries.rb +154 −0
  9. lib/docs/scrapers/gtk.rb +116 −0
  10. public/icons/docs/gtk/16.png +0 −0
  11. public/icons/docs/gtk/16@2x.png +0 −0
  12. public/icons/docs/gtk/SOURCE +1 −0
assets/javascripts/news.json+4−0
@@ -1,4 +1,8 @@
11 [
2+ [
3+ "2020-12-23",
4+ "New documentation: <a href=\"/gtk/\">GTK</a>"
5+ ],
26 [
37 "2020-12-07",
48 "New documentations: <a href=\"/flask/\">Flask</a>, <a href=\"/groovy/\">Groovy</a>, <a href=\"/jinja/\">Jinja</a>, <a href=\"/werkzeug/\">Werkzeug</a>"
assets/javascripts/templates/pages/about_tmpl.coffee+5−0
@@ -356,6 +356,11 @@ credits = [ · 355 unmodified lines
356356 'GruntJS Team',
357357 'MIT',
358358 'https://github.com/gruntjs/grunt-docs/blob/master/package.json#L10'
359+ ], [
360+ 'GTK',
361+ 'The GNOME Project',
362+ 'LGPLv2.1+',
363+ 'https://gitlab.gnome.org/GNOME/gtk/-/blob/master/COPYING'
359364 ], [
360365 'Handlebars',
361366 '2011-2017 Yehuda Katz',
assets/stylesheets/application.css.scss+2−1
@@ -59,10 +59,11 @@ · 58 unmodified lines
5959 'pages/express',
6060 'pages/git',
6161 'pages/github',
62+ 'pages/gnuplot',
6263 'pages/go',
6364 'pages/graphite',
6465 'pages/groovy',
65− 'pages/gnuplot',
66+ 'pages/gtk',
6667 'pages/haproxy',
6768 'pages/haskell',
6869 'pages/jekyll',
assets/stylesheets/pages/_gtk.scss+15−0
@@ -0,0 +1,15 @@
1+._gtk {
2+ padding-left: 1rem;
3+
4+ h1, h2, h3 { margin-left: -1rem; }
5+ h2 { @extend %block-heading; }
6+ h3 { @extend %block-label, %label-blue; }
7+
8+ div.toc { margin-top: 1.5em; }
9+ .toc dl { margin-top: 0; margin-bottom: 0; }
10+
11+ .note { @extend %note, %note-green; }
12+ .warning { @extend %note, %note-orange; }
13+
14+ .gallery-float { float:left; }
15+}
docs/scraper-reference.md+18−0
@@ -190,6 +190,8 @@ More information about how filters work is available on the [Filter Reference](. · 189 unmodified lines
190190 In order to keep scrapers up-to-date the `get_latest_version(opts)` method should be overridden. If `self.release` is defined, this should return the latest version of the documentation. If `self.release` is not defined, it should return the Epoch time when the documentation was last modified. If the documentation will never change, simply return `1.0.0`. The result of this method is periodically reported in a "Documentation versions report" issue which helps maintainers keep track of outdated documentations.
191191
192192 To make life easier, there are a few utility methods that you can use in `get_latest_version`:
193+
194+### General HTTP methods
193195 * `fetch(url, opts)`
194196
195197 Makes a GET request to the url and returns the response body.
@@ -205,11 +207,15 @@ To make life easier, there are a few utility methods that you can use in `get_la · 9 unmodified lines
205207 Makes a GET request to the url and returns the JSON body converted to a dictionary.
206208
207209 Example: [lib/docs/scrapers/mdn/mdn.rb](../lib/docs/scrapers/mdn/mdn.rb)
210+
211+### Package repository methods
208212 * `get_npm_version(package, opts)`
209213
210214 Returns the latest version of the given npm package.
211215
212216 Example: [lib/docs/scrapers/bower.rb](../lib/docs/scrapers/bower.rb)
217+
218+### GitHub methods
213219 * `get_latest_github_release(owner, repo, opts)`
214220
215221 Returns the tag name of the latest GitHub release of the given repository. If the tag name is preceded by a "v", the "v" will be removed.
@@ -225,3 +231,15 @@ To make life easier, there are a few utility methods that you can use in `get_la · 9 unmodified lines
225231 Returns the contents of the requested file in the default branch of the given repository.
226232
227233 Example: [lib/docs/scrapers/minitest.rb](../lib/docs/scrapers/minitest.rb)
234+* `get_latest_github_commit_date(owner, repo, opts)`
235+
236+ Returns the date of the most recent commit in the default branch of the given repository.
237+
238+ Example: [lib/docs/scrapers/reactivex.rb](../lib/docs/scrapers/reactivex.rb)
239+
240+### GitLab methods
241+* `get_gitlab_tags(hostname, group, project, opts)`
242+
243+ Returns the list of tags on the given repository ([format](https://docs.gitlab.com/ee/api/tags.html)).
244+
245+ Example: [lib/docs/scrapers/gtk.rb](../lib/docs/scrapers/gtk.rb)
lib/docs/core/doc.rb+4−0
@@ -270,5 +270,9 @@ module Docs · 269 unmodified lines
270270 timestamp = commits[0]['commit']['author']['date']
271271 Date.iso8601(timestamp).to_time.to_i
272272 end
273+
274+ def get_gitlab_tags(hostname, group, project, opts)
275+ fetch_json("https://#{hostname}/api/v4/projects/#{group}%2F#{project}/repository/tags", opts)
276+ end
273277 end
274278 end
lib/docs/filters/gtk/clean_html.rb+69−0
@@ -0,0 +1,69 @@
1+module Docs
2+ class Gtk
3+ class CleanHtmlFilter < Filter
4+ def call
5+
6+ css('table#top', 'table > colgroup', 'h2.title', '.footer', 'hr', 'br').remove
7+
8+ if root_page?
9+ css('span > a').each do |node|
10+ node.parent.before(node).remove
11+ end
12+ end
13+
14+ if top_table = at_css('.refnamediv > table')
15+ top_table.css('td > p', 'td > img').each do |node|
16+ top_table.before(node)
17+ end
18+ top_table.remove
19+ end
20+
21+ css('table').each do |node|
22+ node.remove_attribute 'border'
23+ node.remove_attribute 'width'
24+ end
25+
26+ # Move anchors to general headings
27+ css('h2 > a[name]', 'h3 > a[name]').each do |node|
28+ node.parent['id'] = node['name']
29+ end
30+
31+ # Move anchors to function/struct/enum/etc.
32+ css('a[name] + h2', 'a[name] + h3').each do |node|
33+ node['id'] = node.previous_element['name']
34+ end
35+
36+ # Move anchors to struct and enum members
37+ css('td.struct_member_name', 'td.enum_member_name').each do |node|
38+ node['id'] = node.at_css('a[name]')['name']
39+ end
40+
41+ # Remove surrounding table from code blocks
42+ css('.listing_frame').each do |node|
43+ node.before(at_css('.listing_code')).remove
44+ end
45+
46+ css('.literallayout code').each do |node|
47+ node.name = 'pre'
48+ end
49+
50+ # Fix code highlighting
51+ css('pre').each do |node|
52+ # If a codeblock has URLs, don't touch it
53+ next if node.at_css('a[href]')
54+
55+ node.content = node.content
56+
57+ # it's not perfect, but make a guess at language
58+ if node.content =~ /\<\?xml/
59+ node['data-language'] = 'xml'
60+ else
61+ node['data-language'] = 'c'
62+ end
63+ end
64+
65+ doc
66+ end
67+ end
68+ end
69+end
lib/docs/filters/gtk/entries.rb+154−0
@@ -0,0 +1,154 @@
1+module Docs
2+ class Gtk
3+ class EntriesFilter < Docs::EntriesFilter
4+ # The GTK documentation paths are "flat" and while the contents of each
5+ # page provides a way to determine the direct parent relationship, we
6+ # really need a full hierarchy of pages *a priori* to be able to fully
7+ # categorize all pages and entries. So we're going to recursivly generate
8+ # a full map of page -> parent relationships from the table of contents...
9+ PARENT_BY_PATH = {}
10+
11+ # And then use it to generate the list of 'breadcrumb' paths for each page
12+ # ex: ['gtkwidgets', 'fancywidgets', 'gtkexamplewidget']
13+ attr_accessor :breadcrumbs
14+
15+ # Map of paths to Page Names/Titles
16+ NAME_BY_PATH = {}
17+
18+ # GTK+ 3 and GTK 4
19+ REPLACE_NAMES = {
20+ 'I. GTK+ Overview' => '1. Overview',
21+ 'II. GTK+ Widgets and Objects' => '2. Widgets and Objects',
22+ 'III. GTK+ Core Reference' => '3. Core Reference',
23+ 'IV. Theming in GTK+' => '4. Theming',
24+ 'VI. GTK+ Tools' => '6. Tools',
25+ 'VII. GTK+ Platform Support' => '7. Platform Support',
26+
27+ 'I. Introduction' => '1. Introduction',
28+ 'II. GTK Concepts' => '2. Concepts',
29+ 'III. GTK Widgets and Objects' => '3. Widgets and Objects',
30+ 'IV. GTK Core Reference' => '4. Core Reference',
31+ 'V. Theming in GTK' => '5. Theming',
32+ 'VII. GTK Tools' => '7. Tools',
33+ 'VIII. GTK Platform Support' => '8. Platform Support'
34+ }
35+
36+ def call
37+ if root_page?
38+ # Generate NAME_BY_PATH Hash
39+ css('dl.toc a').each do |node|
40+ name = node.content
41+ path = node['href'].split('/').last.remove('.html')
42+ NAME_BY_PATH[path] = REPLACE_NAMES[name] || name
43+ end
44+ # Generate PARENT_BY_PATH Hash
45+ process_toc(at_css('dl.toc'), nil)
46+ end
47+ super
48+ end
49+
50+ # Recursive depth-first search
51+ # Treat solo 'dt' nodes as leaf nodes and
52+ # sibling 'dt + dd' nodes as nodes with children
53+ def process_toc(toc_dl_node, parent_path)
54+ toc_dl_node.css('> dt').each do |node|
55+ node_path = node.at_css('a')['href'].split('/').last.remove('.html')
56+ PARENT_BY_PATH[node_path] = parent_path
57+
58+ if node.next_element && node.next_element.name == 'dd'
59+ children = node.next_element.children.first
60+ process_toc(children, node_path)
61+ end
62+ end
63+ end
64+
65+ def breadcrumbs
66+ @breadcrumbs ||= get_breadcrumbs
67+ end
68+
69+ def get_breadcrumbs
70+ return [] if root_page?
71+
72+ breadcrumbs = []
73+ path = slug.downcase
74+ while path
75+ breadcrumbs.prepend path
76+ path = PARENT_BY_PATH[path]
77+ end
78+
79+ breadcrumbs
80+ end
81+
82+ def get_name
83+ NAME_BY_PATH[self.breadcrumbs.last]
84+ end
85+
86+ def get_type
87+ NAME_BY_PATH[self.breadcrumbs.first]
88+ end
89+
90+ def additional_entries
91+ entries = []
92+ type = case self.breadcrumbs.first
93+ when 'gtkobjects'
94+ "Widgets / #{NAME_BY_PATH[self.breadcrumbs[1]]}"
95+ when 'gtkbase'
96+ "Base / #{self.name}"
97+ when'theming'
98+ "Theming / #{self.name}"
99+ end
100+
101+ if funcs = at_css('h2:contains("Functions")')
102+ funcs.next_element.css('td.function_name > a').each do |node|
103+ name = "#{node.content}()"
104+ id = node['href']
105+ entries << [name, id, type]
106+ end
107+ end
108+
109+ css('td.property_name > a').each do |node|
110+ name = "#{node.content} (#{self.name} property)"
111+ id = node['href']
112+ entries << [name, id, type]
113+ end
114+
115+ css('td.signal_name > a').each do |node|
116+ name = "#{node.content} (#{self.name} signal)"
117+ id = node['href']
118+ entries << [name, id, type]
119+ end
120+
121+ css('td.enum_member_name').each do |node|
122+ name = node.content
123+ id = node.at_css('a')['name']
124+ entries << [name, id, type]
125+ end
126+
127+ if values_node = at_css('h2:contains("Types and Values") + .informaltable')
128+ values_node.css('tr').each do |node|
129+ data_type = node.css('td').first.content
130+ name = node.at_css('td.function_name').content
131+ if data_type == ' '
132+ name = "#{name} (type)"
133+ elsif data_type == 'enum' || data_type == 'struct'
134+ name = "#{name} (#{data_type})"
135+ end
136+ id = node.at_css('td.function_name a')['href']
137+ entries << [name, id, type]
138+ end
139+ end
140+
141+ if slug == 'gtk-running'
142+ css('h3 > a[name]').each do |node|
143+ name = node.parent.content
144+ id = node['name']
145+ entries << [name, id, 'Platform / Environment Variables']
146+ end
147+ end
148+
149+ entries
150+ end
151+
152+ end
153+ end
154+end
lib/docs/scrapers/gtk.rb+116−0
@@ -0,0 +1,116 @@
1+module Docs
2+ class Gtk < UrlScraper
3+ self.name = 'GTK'
4+ self.slug = 'gtk'
5+ self.type = 'gtk'
6+ self.root_path = 'index.html'
7+ self.links = {
8+ home: 'https://www.gtk.org/',
9+ code: 'https://gitlab.gnome.org/GNOME/gtk/'
10+ }
11+
12+ html_filters.push 'gtk/entries', 'gtk/clean_html', 'title'
13+
14+ options[:container] = '.content'
15+
16+ # These are all "index"-ish pages with no valuable content
17+ GTK3_SKIP = %w(
18+ gtk.html
19+ gtk-resources.html gtk-question-index.html
20+ gtkobjects.html
21+ Application.html Builder.html WindowWidgets.html LayoutContainers.html
22+ DisplayWidgets.html ButtonWidgets.html NumericEntry.html
23+ TextWidgetObjects.html TreeWidgetObjects.html MenusAndCombos.html
24+ SelectorWidgets.html Ornaments.html ScrollingWidgets.html Printing.html
25+ ShortcutsOverview.html MiscObjects.html AbstractObjects.html
26+ PlugSocket.html RecentDocuments.html ApplicationChoosing.html
27+ Gestures.html DeprecatedObjects.html
28+ gtkbase.html
29+ theming.html
30+ migrating.html
31+ ch26s02.html ch28s02.html
32+ pt06.html
33+ platform-support.html
34+ glossary.html
35+ annotation-glossary.html
36+ )
37+
38+ GTK3_SKIP_PATTERNS = [
39+ /migrating/, /checklist/, /ch30/, /ch32/, /api-index-/
40+ ]
41+
42+ # These are all "index"-ish pages with no valuable content
43+ GTK4_SKIP = %w(
44+ gtk.html
45+ gtk-resources.html gtk-question-index.html ch02s02.html
46+ concepts.html
47+ gtkobjects.html
48+ Lists.html Trees.html Application.html Builder.html WindowWidgets.html
49+ LayoutContainers.html LayoutManagers.html DisplayWidgets.html
50+ MediaSupport.html ButtonWidgets.html NumericEntry.html
51+ MenusAndCombos.html SelectorWidgets.html DrawingWidgets.html
52+ Ornaments.html ScrollingWidgets.html Printing.html
53+ ShortcutsOverview.html MiscObjects.html AbstractObjects.html
54+ RecentDocuments.html ApplicationChoosing.html Gestures.html ch36.html
55+ ch37.html
56+ gtkbase.html
57+ theming.html
58+ migrating.html
59+ ch41s02.html ch41s03.html
60+ pt07.html
61+ platform-support.html
62+ api-index-full.html
63+ annotation-glossary.html
64+ )
65+
66+ GTK4_SKIP_PATTERNS = [
67+ /migrating/, /ch03/, /ch09/, /ch10/
68+ ]
69+
70+ options[:attribution] = <<-HTML
71+ &copy; 2005&ndash;2020 The GNOME Project<br>
72+ Licensed under the GNU Lesser General Public License version 2.1 or later.
73+ HTML
74+
75+ version '4.0' do
76+ self.release = '4.0.0'
77+ self.base_url = "https://developer.gnome.org/gtk4/#{self.version}/"
78+
79+ options[:root_title] = 'GTK 4 Reference Manual'
80+ options[:skip] = GTK4_SKIP
81+ options[:skip_patterns] = GTK4_SKIP_PATTERNS
82+ end
83+
84+ version '3.24' do
85+ self.release = '3.24.24'
86+ self.base_url = "https://developer.gnome.org/gtk3/#{self.version}/"
87+
88+ options[:root_title] = 'GTK+ 3 Reference Manual'
89+ options[:skip] = GTK3_SKIP
90+ options[:skip_patterns] = GTK3_SKIP_PATTERNS
91+ end
92+
93+ version '3.22' do
94+ self.release = '3.22.3'
95+ self.base_url = "https://developer.gnome.org/gtk3/#{self.version}/"
96+
97+ options[:root_title] = 'GTK+ 3 Reference Manual'
98+ options[:skip] = GTK3_SKIP
99+ options[:skip_patterns] = GTK3_SKIP_PATTERNS
100+ end
101+
102+ version '3.20' do
103+ self.release = '3.20.4'
104+ self.base_url = "https://developer.gnome.org/gtk3/#{self.version}/"
105+
106+ options[:root_title] = 'GTK+ 3 Reference Manual'
107+ options[:skip] = GTK3_SKIP
108+ options[:skip_patterns] = GTK3_SKIP_PATTERNS
109+ end
110+
111+ def get_latest_version(opts)
112+ tags = get_gitlab_tags('gitlab.gnome.org', 'GNOME', 'gtk', opts)
113+ tags[0]['name']
114+ end
115+ end
116+end
public/icons/docs/gtk/16.png+0−0

Binary file not shown.

public/icons/docs/gtk/16@2x.png+0−0

Binary file not shown.

public/icons/docs/gtk/SOURCE+1−0
@@ -0,0 +1 @@
1+https://www.gtk.org/assets/img/logo-gtk-sm.png