Explorar el Código

Add PostgreSQL documentation

Thibaut hace 12 años
padre
commit
bec23e6b70

BIN
assets/images/icons.png


BIN
assets/images/icons@2x.png


+ 5 - 0
assets/javascripts/templates/pages/about_tmpl.coffee

@@ -143,6 +143,11 @@ credits = [
     '1997-2013 The PHP Documentation Group',
     'CC BY',
     'http://creativecommons.org/licenses/by/3.0/'
+  ], [
+    'PostgreSQL',
+    '1996-2013 The PostgreSQL Global Development Group<br>&copy; 1994 The Regents of the University of California',
+    'PostgreSQL',
+    'http://www.postgresql.org/about/licence/'
   ], [
     'Python',
     '1990-2013 Python Software Foundation<br>Python is a trademark of the Python Software Foundation.',

+ 4 - 1
assets/javascripts/templates/pages/news_tmpl.coffee

@@ -24,7 +24,10 @@ newsItem = (date, news) ->
   result
 
 app.news = [
-  [ 1386892800000, # December 13, 2013
+  [ 1386979200000, # December 14, 2013
+    """ New <a href="/postgresql/">PostgreSQL</a> documentation """
+  ], [
+    1386892800000, # December 13, 2013
     """ New <a href="/git/">Git</a> and <a href="/redis/">Redis</a> documentations """
   ], [
     1385424000000, # November 26, 2013

+ 1 - 0
assets/stylesheets/application.css.scss

@@ -37,6 +37,7 @@
         'pages/mdn',
         'pages/node',
         'pages/php',
+        'pages/postgres',
         'pages/rdoc',
         'pages/redis',
         'pages/rfc',

+ 1 - 0
assets/stylesheets/global/_icons.scss

@@ -44,3 +44,4 @@
 ._icon-python:before        { background-position: 0 -6rem; }
 ._icon-git:before           { background-position: -1rem -6rem; }
 ._icon-redis:before         { background-position: -2rem -6rem; }
+._icon-postgresql:before    { background-position: -3rem -6rem; }

+ 13 - 0
assets/stylesheets/pages/_postgres.scss

@@ -0,0 +1,13 @@
+._postgres {
+  padding-left: 1rem;
+
+  h1, h1 ~ p, h2 { margin-left: -1rem; }
+  h2 { @extend %block-heading; }
+
+  .VARIABLELIST dt { @extend %block-label, %label-blue; }
+
+  blockquote.NOTE, blockquote.IMPORTANT { @extend %note; }
+  blockquote.TIP { @extend %note, %note-green; }
+
+  p > code { @extend %label; }
+}

+ 44 - 0
lib/docs/filters/postgresql/clean_html.rb

@@ -0,0 +1,44 @@
+module Docs
+  class Postgresql
+    class CleanHtmlFilter < Filter
+      def call
+        root_page? ? root : other
+        doc
+      end
+
+      def root
+        doc.inner_html = ' '
+      end
+
+      def other
+        css('a[name]').each do |node|
+          node.parent['id'] = node['name']
+          node.before(node.children).remove
+        end
+
+        css('div.SECT1', 'pre > kbd', 'tt > code', 'h1 > tt').each do |node|
+          node.before(node.children).remove
+        end
+
+        css('table').each do |node|
+          node.remove_attribute 'border'
+          node.remove_attribute 'width'
+        end
+
+        css('td').each do |node|
+          node.remove_attribute 'align'
+          node.remove_attribute 'valign'
+        end
+
+        css('tt').each do |node|
+          node.name = 'code'
+        end
+
+        css('.REFSYNOPSISDIV > p').each do |node|
+          node.name = 'pre'
+          node.content = node.content
+        end
+      end
+    end
+  end
+end

+ 25 - 0
lib/docs/filters/postgresql/clean_nav.rb

@@ -0,0 +1,25 @@
+module Docs
+  class Postgresql
+    class CleanNavFilter < Filter
+      def call
+        extract_up_path
+        extract_chapter
+        css('.NAVHEADER', '.NAVFOOTER').remove
+        doc
+      end
+
+      def extract_up_path
+        if node = at_css('.NAVHEADER a[accesskey="U"]')
+          result[:pg_up_path] = node['href']
+        end
+      end
+
+      def extract_chapter
+        return unless text = at_css('.NAVHEADER td[align="center"]').content
+        return unless match = text.match(/\AChapter (\d+)\. (.+)\z/)
+        result[:pg_chapter] = match[1].to_i
+        result[:pg_chapter_name] = match[2]
+      end
+    end
+  end
+end

+ 153 - 0
lib/docs/filters/postgresql/entries.rb

@@ -0,0 +1,153 @@
+module Docs
+  class Postgresql
+    class EntriesFilter < Docs::EntriesFilter
+      REPLACE_NAMES = {
+        'Sorting Rows'                    => 'ORDER BY',
+        'Select Lists'                    => 'SELECT Lists',
+        'Data Type Formatting Functions'  => 'Formatting Functions',
+        'Enum Support Functions'          => 'Enum Functions',
+        'Row and Array Comparisons'       => 'Array Comparisons',
+        'Sequence Manipulation Functions' => 'Sequence Functions',
+        'System Administration Functions' => 'Administration Functions',
+        'System Information Functions'    => 'Information Functions' }
+
+      def get_name
+        name = at_css('h1').content
+        clean_heading_name(name)
+
+        if %w(Overview Introduction).include?(name)
+          result[:pg_chapter_name]
+        else
+          name.sub! ' (Common Table Expressions)', ''
+          REPLACE_NAMES[name] || name
+        end
+      end
+
+      def clean_heading_name(name)
+        name.sub! %r{\A[\d\.\s]+}, ''
+        name.sub! 'Using ', ''
+        name.sub! %r{\AThe }, ''
+        name
+      end
+
+      def get_type
+        return if initial_page?
+
+        if result[:pg_up_path] == 'sql-commands.html'
+          'Commands'
+        elsif result[:pg_up_path].start_with? 'reference-'
+          'Applications'
+        elsif type = result[:pg_chapter_name]
+          if type.start_with?('Func') && (match = name.match(/\A(?!Form|Seq|Set|Enum)(.+) Func/))
+            "Functions: #{match[1]}"
+          else
+            type.sub 'SQL ', ''
+          end
+        end
+      end
+
+      def additional_entries
+        return [] if skip_additional_entries?
+        return get_config_entries if config_page?
+        return get_heading_entries('h3[id]') if slug == 'functions-xml'
+
+        if type == 'Data Types'
+          return get_custom_entries case slug
+            when 'rangetypes'          then 'li > p > .TYPE:first-child'
+            when 'datatype-textsearch' then '.SECT2 > .TYPE'
+            else '.CALSTABLE td:first-child > .TYPE' end
+        end
+
+        entries = get_heading_entries('h2[id]')
+
+        if slug == 'queries-union'
+          entries.concat get_custom_entries('p > .LITERAL:first-child')
+        elsif slug == 'queries-table-expressions'
+          entries.concat get_heading_entries('h3[id]')
+          entries.concat get_custom_entries('dt > .LITERAL:first-child')
+        elsif slug == 'functions-logical'
+          entries.concat get_custom_entries('> table td:first-child > code')
+        elsif slug == 'functions-formatting'
+          entries.concat get_custom_entries('#FUNCTIONS-FORMATTING-TABLE td:first-child > code')
+        elsif slug == 'functions-admin'
+          entries.concat get_custom_entries('.TABLE td:first-child > code')
+        elsif slug == 'functions-string'
+          entries.concat get_custom_entries('> div[id^="FUNC"] td:first-child > code')
+        elsif type && type.start_with?('Functions')
+          entries.concat get_custom_entries('> .TABLE td:first-child > code:first-child')
+          entries.concat get_comparison_entries if slug == 'functions-comparison'
+        end
+
+        entries
+      end
+
+      def get_config_entries
+        css('.VARIABLELIST dt[id]').map do |node|
+          name = node.at_css('.VARNAME').content
+          ["Config: #{name}", node['id']]
+        end
+      end
+
+      def get_heading_entries(selector)
+        css(selector).inject [] do |entries, node|
+          name = node.content
+          clean_heading_name(name)
+
+          unless skip_heading?(name)
+            entries << ["#{additional_entry_prefix}: #{name}", node['id']]
+          end
+
+          entries
+        end
+      end
+
+      def get_custom_entries(selector)
+        css(selector).inject [] do |entries, node|
+          name = node.content
+          name.gsub! %r{\(.*?\)}m, ''
+          name.gsub! %r{\[.*?\]}m, ''
+          name.squeeze! ' '
+          name.sub! %r{\([^\)]*\z}, '' # bug fix: json_populate_record
+          name = '||' if name.include? ' || '
+          id = name.gsub(/[^a-z0-9\-_]/) { |char| char.ord }
+          id = id.parameterize
+          name.prepend "#{additional_entry_prefix}: "
+
+          unless entries.any? { |entry| entry[0] == name }
+            node['id'] = id
+            entries << [name, id]
+          end
+
+          entries
+        end
+      end
+
+      def get_comparison_entries
+        %w(IS NULL BETWEEN DISTINCT\ FROM).map do |name|
+          ["#{self.name}: #{name}"]
+        end
+      end
+
+      def additional_entry_prefix
+        type.dup.sub!('Functions: ', '') || self.name
+      end
+
+      def skip_additional_entries?
+        slug == 'config-setting' || %w(Concurrency\ Control Localization).include?(type)
+      end
+
+      def skip_heading?(name)
+        %w(Usage\ Patterns Portability Caveats Overview).include?(name) ||
+        (type.start_with?('Functions') && slug != 'functions-xml' && name.split.first.upcase!)
+      end
+
+      def include_default_entry?
+        !(initial_page? || at_css('.TOC') || config_page?)
+      end
+
+      def config_page?
+        slug.start_with? 'runtime-config'
+      end
+    end
+  end
+end

+ 55 - 0
lib/docs/scrapers/postgresql.rb

@@ -0,0 +1,55 @@
+module Docs
+  class Postgresql < FileScraper
+    self.name = 'PostgreSQL'
+    self.type = 'postgres'
+    self.version = 'up to 9.3.2'
+    self.dir = '/Users/Thibaut/DevDocs/Docs/PostgreSQL'
+    self.base_url = 'http://www.postgresql.org/docs/9.3/static/'
+    self.root_path = 'reference.html'
+    self.initial_paths = %w(sql.html runtime-config.html charset.html)
+
+    html_filters.insert_before 'normalize_urls', 'postgresql/clean_nav'
+    html_filters.push 'postgresql/clean_html', 'postgresql/entries', 'title'
+
+    options[:title] = false
+    options[:root_title] = 'PostgreSQL'
+    options[:follow_links] = ->(filter) { filter.initial_page? }
+
+    options[:only] = %w(
+      arrays.html
+      rowtypes.html
+      rangetypes.html
+      mvcc-intro.html
+      transaction-iso.html
+      explicit-locking.html
+      applevel-consistency.html
+      locking-indexes.html
+      config-setting.html
+      locale.html
+      collation.html
+      multibyte.html)
+
+    options[:only_patterns] = [
+      /\Asql\-/,
+      /\Aapp\-/,
+      /\Addl\-/,
+      /\Adml\-/,
+      /\Aqueries\-/,
+      /\Adatatype\-/,
+      /\Afunctions\-/,
+      /\Aindexes\-/,
+      /\Aruntime\-config\-/]
+
+    options[:skip] = %w(
+      ddl-others.html
+      runtime-config-custom.html
+      runtime-config-short.html
+      functions-event-triggers.html
+      functions-trigger.html)
+
+    options[:attribution] = <<-HTML
+      &copy; 1996&ndash;2013 The PostgreSQL Global Development Group<br>
+      Licensed under the PostgreSQL License.
+    HTML
+  end
+end

BIN
public/icons/docs/postgresql/16.png


BIN
public/icons/docs/postgresql/16@2x.png


+ 1 - 0
public/icons/docs/postgresql/SOURCE

@@ -0,0 +1 @@
+http://www.postgresql.org/about/press/presskit93/#logos