History

Add PostgreSQL documentation

Thibaut committed 12 years ago

Commit bec23e61 parent dd2229e14 files · +298 −-3Browse files

Unified · Split

14 files
  1. assets/images/icons.png +0 −0
  2. assets/images/icons@2x.png +0 −0
  3. assets/javascripts/templates/pages/about_tmpl.coffee +5 −0
  4. assets/javascripts/templates/pages/news_tmpl.coffee +4 −1
  5. assets/stylesheets/application.css.scss +1 −0
  6. assets/stylesheets/global/_icons.scss +1 −0
  7. assets/stylesheets/pages/_postgres.scss +13 −0
  8. lib/docs/filters/postgresql/clean_html.rb +44 −0
  9. lib/docs/filters/postgresql/clean_nav.rb +25 −0
  10. lib/docs/filters/postgresql/entries.rb +153 −0
  11. lib/docs/scrapers/postgresql.rb +55 −0
  12. public/icons/docs/postgresql/16.png +0 −0
  13. public/icons/docs/postgresql/16@2x.png +0 −0
  14. public/icons/docs/postgresql/SOURCE +1 −0
assets/images/icons.png+0−0

Binary file not shown.

assets/images/icons@2x.png+0−0

Binary file not shown.

assets/javascripts/templates/pages/about_tmpl.coffee+5−0
@@ -143,6 +143,11 @@ credits = [ · 142 unmodified lines
143143 '1997-2013 The PHP Documentation Group',
144144 'CC BY',
145145 'http://creativecommons.org/licenses/by/3.0/'
146+ ], [
147+ 'PostgreSQL',
148+ '1996-2013 The PostgreSQL Global Development Group<br>&copy; 1994 The Regents of the University of California',
149+ 'PostgreSQL',
150+ 'http://www.postgresql.org/about/licence/'
146151 ], [
147152 'Python',
148153 '1990-2013 Python Software Foundation<br>Python is a trademark of the Python Software Foundation.',
assets/javascripts/templates/pages/news_tmpl.coffee+4−1
@@ -24,7 +24,10 @@ newsItem = (date, news) -> · 23 unmodified lines
2424 result
2525
2626 app.news = [
27− [ 1386892800000, # December 13, 2013
27+ [ 1386979200000, # December 14, 2013
28+ """ New <a href="/postgresql/">PostgreSQL</a> documentation """
29+ ], [
30+ 1386892800000, # December 13, 2013
2831 """ New <a href="/git/">Git</a> and <a href="/redis/">Redis</a> documentations """
2932 ], [
3033 1385424000000, # November 26, 2013
assets/stylesheets/application.css.scss+1−0
@@ -37,6 +37,7 @@ · 36 unmodified lines
3737 'pages/mdn',
3838 'pages/node',
3939 'pages/php',
40+ 'pages/postgres',
4041 'pages/rdoc',
4142 'pages/redis',
4243 'pages/rfc',
assets/stylesheets/global/_icons.scss+1−0
@@ -44,3 +44,4 @@ · 43 unmodified lines
4444 ._icon-python:before { background-position: 0 -6rem; }
4545 ._icon-git:before { background-position: -1rem -6rem; }
4646 ._icon-redis:before { background-position: -2rem -6rem; }
47+._icon-postgresql:before { background-position: -3rem -6rem; }
assets/stylesheets/pages/_postgres.scss+13−0
@@ -0,0 +1,13 @@
1+._postgres {
2+ padding-left: 1rem;
3+
4+ h1, h1 ~ p, h2 { margin-left: -1rem; }
5+ h2 { @extend %block-heading; }
6+
7+ .VARIABLELIST dt { @extend %block-label, %label-blue; }
8+
9+ blockquote.NOTE, blockquote.IMPORTANT { @extend %note; }
10+ blockquote.TIP { @extend %note, %note-green; }
11+
12+ p > code { @extend %label; }
13+}
lib/docs/filters/postgresql/clean_html.rb+44−0
@@ -0,0 +1,44 @@
1+module Docs
2+ class Postgresql
3+ class CleanHtmlFilter < Filter
4+ def call
5+ root_page? ? root : other
6+ doc
7+ end
8+
9+ def root
10+ doc.inner_html = ' '
11+ end
12+
13+ def other
14+ css('a[name]').each do |node|
15+ node.parent['id'] = node['name']
16+ node.before(node.children).remove
17+ end
18+
19+ css('div.SECT1', 'pre > kbd', 'tt > code', 'h1 > tt').each do |node|
20+ node.before(node.children).remove
21+ end
22+
23+ css('table').each do |node|
24+ node.remove_attribute 'border'
25+ node.remove_attribute 'width'
26+ end
27+
28+ css('td').each do |node|
29+ node.remove_attribute 'align'
30+ node.remove_attribute 'valign'
31+ end
32+
33+ css('tt').each do |node|
34+ node.name = 'code'
35+ end
36+
37+ css('.REFSYNOPSISDIV > p').each do |node|
38+ node.name = 'pre'
39+ node.content = node.content
40+ end
41+ end
42+ end
43+ end
44+end
lib/docs/filters/postgresql/clean_nav.rb+25−0
@@ -0,0 +1,25 @@
1+module Docs
2+ class Postgresql
3+ class CleanNavFilter < Filter
4+ def call
5+ extract_up_path
6+ extract_chapter
7+ css('.NAVHEADER', '.NAVFOOTER').remove
8+ doc
9+ end
10+
11+ def extract_up_path
12+ if node = at_css('.NAVHEADER a[accesskey="U"]')
13+ result[:pg_up_path] = node['href']
14+ end
15+ end
16+
17+ def extract_chapter
18+ return unless text = at_css('.NAVHEADER td[align="center"]').content
19+ return unless match = text.match(/\AChapter (\d+)\. (.+)\z/)
20+ result[:pg_chapter] = match[1].to_i
21+ result[:pg_chapter_name] = match[2]
22+ end
23+ end
24+ end
25+end
lib/docs/filters/postgresql/entries.rb+153−0
@@ -0,0 +1,153 @@
1+module Docs
2+ class Postgresql
3+ class EntriesFilter < Docs::EntriesFilter
4+ REPLACE_NAMES = {
5+ 'Sorting Rows' => 'ORDER BY',
6+ 'Select Lists' => 'SELECT Lists',
7+ 'Data Type Formatting Functions' => 'Formatting Functions',
8+ 'Enum Support Functions' => 'Enum Functions',
9+ 'Row and Array Comparisons' => 'Array Comparisons',
10+ 'Sequence Manipulation Functions' => 'Sequence Functions',
11+ 'System Administration Functions' => 'Administration Functions',
12+ 'System Information Functions' => 'Information Functions' }
13+
14+ def get_name
15+ name = at_css('h1').content
16+ clean_heading_name(name)
17+
18+ if %w(Overview Introduction).include?(name)
19+ result[:pg_chapter_name]
20+ else
21+ name.sub! ' (Common Table Expressions)', ''
22+ REPLACE_NAMES[name] || name
23+ end
24+ end
25+
26+ def clean_heading_name(name)
27+ name.sub! %r{\A[\d\.\s]+}, ''
28+ name.sub! 'Using ', ''
29+ name.sub! %r{\AThe }, ''
30+ name
31+ end
32+
33+ def get_type
34+ return if initial_page?
35+
36+ if result[:pg_up_path] == 'sql-commands.html'
37+ 'Commands'
38+ elsif result[:pg_up_path].start_with? 'reference-'
39+ 'Applications'
40+ elsif type = result[:pg_chapter_name]
41+ if type.start_with?('Func') && (match = name.match(/\A(?!Form|Seq|Set|Enum)(.+) Func/))
42+ "Functions: #{match[1]}"
43+ else
44+ type.sub 'SQL ', ''
45+ end
46+ end
47+ end
48+
49+ def additional_entries
50+ return [] if skip_additional_entries?
51+ return get_config_entries if config_page?
52+ return get_heading_entries('h3[id]') if slug == 'functions-xml'
53+
54+ if type == 'Data Types'
55+ return get_custom_entries case slug
56+ when 'rangetypes' then 'li > p > .TYPE:first-child'
57+ when 'datatype-textsearch' then '.SECT2 > .TYPE'
58+ else '.CALSTABLE td:first-child > .TYPE' end
59+ end
60+
61+ entries = get_heading_entries('h2[id]')
62+
63+ if slug == 'queries-union'
64+ entries.concat get_custom_entries('p > .LITERAL:first-child')
65+ elsif slug == 'queries-table-expressions'
66+ entries.concat get_heading_entries('h3[id]')
67+ entries.concat get_custom_entries('dt > .LITERAL:first-child')
68+ elsif slug == 'functions-logical'
69+ entries.concat get_custom_entries('> table td:first-child > code')
70+ elsif slug == 'functions-formatting'
71+ entries.concat get_custom_entries('#FUNCTIONS-FORMATTING-TABLE td:first-child > code')
72+ elsif slug == 'functions-admin'
73+ entries.concat get_custom_entries('.TABLE td:first-child > code')
74+ elsif slug == 'functions-string'
75+ entries.concat get_custom_entries('> div[id^="FUNC"] td:first-child > code')
76+ elsif type && type.start_with?('Functions')
77+ entries.concat get_custom_entries('> .TABLE td:first-child > code:first-child')
78+ entries.concat get_comparison_entries if slug == 'functions-comparison'
79+ end
80+
81+ entries
82+ end
83+
84+ def get_config_entries
85+ css('.VARIABLELIST dt[id]').map do |node|
86+ name = node.at_css('.VARNAME').content
87+ ["Config: #{name}", node['id']]
88+ end
89+ end
90+
91+ def get_heading_entries(selector)
92+ css(selector).inject [] do |entries, node|
93+ name = node.content
94+ clean_heading_name(name)
95+
96+ unless skip_heading?(name)
97+ entries << ["#{additional_entry_prefix}: #{name}", node['id']]
98+ end
99+
100+ entries
101+ end
102+ end
103+
104+ def get_custom_entries(selector)
105+ css(selector).inject [] do |entries, node|
106+ name = node.content
107+ name.gsub! %r{\(.*?\)}m, ''
108+ name.gsub! %r{\[.*?\]}m, ''
109+ name.squeeze! ' '
110+ name.sub! %r{\([^\)]*\z}, '' # bug fix: json_populate_record
111+ name = '||' if name.include? ' || '
112+ id = name.gsub(/[^a-z0-9\-_]/) { |char| char.ord }
113+ id = id.parameterize
114+ name.prepend "#{additional_entry_prefix}: "
115+
116+ unless entries.any? { |entry| entry[0] == name }
117+ node['id'] = id
118+ entries << [name, id]
119+ end
120+
121+ entries
122+ end
123+ end
124+
125+ def get_comparison_entries
126+ %w(IS NULL BETWEEN DISTINCT\ FROM).map do |name|
127+ ["#{self.name}: #{name}"]
128+ end
129+ end
130+
131+ def additional_entry_prefix
132+ type.dup.sub!('Functions: ', '') || self.name
133+ end
134+
135+ def skip_additional_entries?
136+ slug == 'config-setting' || %w(Concurrency\ Control Localization).include?(type)
137+ end
138+
139+ def skip_heading?(name)
140+ %w(Usage\ Patterns Portability Caveats Overview).include?(name) ||
141+ (type.start_with?('Functions') && slug != 'functions-xml' && name.split.first.upcase!)
142+ end
143+
144+ def include_default_entry?
145+ !(initial_page? || at_css('.TOC') || config_page?)
146+ end
147+
148+ def config_page?
149+ slug.start_with? 'runtime-config'
150+ end
151+ end
152+ end
153+end
lib/docs/scrapers/postgresql.rb+55−0
@@ -0,0 +1,55 @@
1+module Docs
2+ class Postgresql < FileScraper
3+ self.name = 'PostgreSQL'
4+ self.type = 'postgres'
5+ self.version = 'up to 9.3.2'
6+ self.dir = '/Users/Thibaut/DevDocs/Docs/PostgreSQL'
7+ self.base_url = 'http://www.postgresql.org/docs/9.3/static/'
8+ self.root_path = 'reference.html'
9+ self.initial_paths = %w(sql.html runtime-config.html charset.html)
10+
11+ html_filters.insert_before 'normalize_urls', 'postgresql/clean_nav'
12+ html_filters.push 'postgresql/clean_html', 'postgresql/entries', 'title'
13+
14+ options[:title] = false
15+ options[:root_title] = 'PostgreSQL'
16+ options[:follow_links] = ->(filter) { filter.initial_page? }
17+
18+ options[:only] = %w(
19+ arrays.html
20+ rowtypes.html
21+ rangetypes.html
22+ mvcc-intro.html
23+ transaction-iso.html
24+ explicit-locking.html
25+ applevel-consistency.html
26+ locking-indexes.html
27+ config-setting.html
28+ locale.html
29+ collation.html
30+ multibyte.html)
31+
32+ options[:only_patterns] = [
33+ /\Asql\-/,
34+ /\Aapp\-/,
35+ /\Addl\-/,
36+ /\Adml\-/,
37+ /\Aqueries\-/,
38+ /\Adatatype\-/,
39+ /\Afunctions\-/,
40+ /\Aindexes\-/,
41+ /\Aruntime\-config\-/]
42+
43+ options[:skip] = %w(
44+ ddl-others.html
45+ runtime-config-custom.html
46+ runtime-config-short.html
47+ functions-event-triggers.html
48+ functions-trigger.html)
49+
50+ options[:attribution] = <<-HTML
51+ &copy; 1996&ndash;2013 The PostgreSQL Global Development Group<br>
52+ Licensed under the PostgreSQL License.
53+ HTML
54+ end
55+end
public/icons/docs/postgresql/16.png+0−0

Binary file not shown.

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

Binary file not shown.

public/icons/docs/postgresql/SOURCE+1−0
@@ -0,0 +1 @@
1+http://www.postgresql.org/about/press/presskit93/#logos