Unified · Split
Binary file not shown.
Binary file not shown.
| @@ -143,6 +143,11 @@ credits = [ · 142 unmodified lines | |||
| 143 | '1997-2013 The PHP Documentation Group', | 143 | '1997-2013 The PHP Documentation Group', |
| 144 | 'CC BY', | 144 | 'CC BY', |
| 145 | 'http://creativecommons.org/licenses/by/3.0/' | 145 | 'http://creativecommons.org/licenses/by/3.0/' |
| 146 | ], [ | ||
| 147 | 'PostgreSQL', | ||
| 148 | '1996-2013 The PostgreSQL Global Development Group<br>© 1994 The Regents of the University of California', | ||
| 149 | 'PostgreSQL', | ||
| 150 | 'http://www.postgresql.org/about/licence/' | ||
| 146 | ], [ | 151 | ], [ |
| 147 | 'Python', | 152 | 'Python', |
| 148 | '1990-2013 Python Software Foundation<br>Python is a trademark of the Python Software Foundation.', | 153 | '1990-2013 Python Software Foundation<br>Python is a trademark of the Python Software Foundation.', |
| @@ -24,7 +24,10 @@ newsItem = (date, news) -> · 23 unmodified lines | |||
| 24 | result | 24 | result |
| 25 | 25 | ||
| 26 | app.news = [ | 26 | 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 | ||
| 28 | """ New <a href="/git/">Git</a> and <a href="/redis/">Redis</a> documentations """ | 31 | """ New <a href="/git/">Git</a> and <a href="/redis/">Redis</a> documentations """ |
| 29 | ], [ | 32 | ], [ |
| 30 | 1385424000000, # November 26, 2013 | 33 | 1385424000000, # November 26, 2013 |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | 'pages/mdn', | 37 | 'pages/mdn', |
| 38 | 'pages/node', | 38 | 'pages/node', |
| 39 | 'pages/php', | 39 | 'pages/php', |
| 40 | 'pages/postgres', | ||
| 40 | 'pages/rdoc', | 41 | 'pages/rdoc', |
| 41 | 'pages/redis', | 42 | 'pages/redis', |
| 42 | 'pages/rfc', | 43 | 'pages/rfc', |
| @@ -44,3 +44,4 @@ · 43 unmodified lines | |||
| 44 | ._icon-python:before { background-position: 0 -6rem; } | 44 | ._icon-python:before { background-position: 0 -6rem; } |
| 45 | ._icon-git:before { background-position: -1rem -6rem; } | 45 | ._icon-git:before { background-position: -1rem -6rem; } |
| 46 | ._icon-redis:before { background-position: -2rem -6rem; } | 46 | ._icon-redis:before { background-position: -2rem -6rem; } |
| 47 | ._icon-postgresql:before { background-position: -3rem -6rem; } | ||
| @@ -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 | } | ||
| @@ -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 | ||
| @@ -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 | ||
| @@ -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 | ||
| @@ -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 | © 1996–2013 The PostgreSQL Global Development Group<br> | ||
| 52 | Licensed under the PostgreSQL License. | ||
| 53 | HTML | ||
| 54 | end | ||
| 55 | end | ||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1 @@ | |||
| 1 | http://www.postgresql.org/about/press/presskit93/#logos | ||