From b4b26ae9362087481faf7f784d9d2f33f68eda70 Mon Sep 17 00:00:00 2001 From: Hugo Sarti Date: Mon, 4 May 2015 20:28:41 -0300 Subject: [PATCH] Add docs for Drupal --- assets/stylesheets/application.css.scss | 1 + assets/stylesheets/pages/_drupal.scss | 10 +++++ lib/docs/filters/drupal/clean_html.rb | 24 +++++++++++ lib/docs/filters/drupal/entries.rb | 25 +++++++++++ lib/docs/filters/drupal/internal_urls.rb | 12 ++++++ lib/docs/filters/drupal/normalize_paths.rb | 11 +++++ lib/docs/scrapers/drupal.rb | 47 +++++++++++++++++++++ public/docs/docs.json | 2 +- public/icons/docs/drupal/16.png | Bin 0 -> 704 bytes public/icons/docs/drupal/16@2x.png | Bin 0 -> 1776 bytes public/icons/docs/drupal/SOURCE | 1 + 11 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 assets/stylesheets/pages/_drupal.scss create mode 100644 lib/docs/filters/drupal/clean_html.rb create mode 100644 lib/docs/filters/drupal/entries.rb create mode 100644 lib/docs/filters/drupal/internal_urls.rb create mode 100644 lib/docs/filters/drupal/normalize_paths.rb create mode 100644 lib/docs/scrapers/drupal.rb create mode 100644 public/icons/docs/drupal/16.png create mode 100644 public/icons/docs/drupal/16@2x.png create mode 100644 public/icons/docs/drupal/SOURCE diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss index 749ffa94..c507b95d 100644 --- a/assets/stylesheets/application.css.scss +++ b/assets/stylesheets/application.css.scss @@ -37,6 +37,7 @@ 'pages/clojure', 'pages/coffeescript', 'pages/d3', + 'pages/drupal', 'pages/ember', 'pages/express', 'pages/git', diff --git a/assets/stylesheets/pages/_drupal.scss b/assets/stylesheets/pages/_drupal.scss new file mode 100644 index 00000000..d1aa236e --- /dev/null +++ b/assets/stylesheets/pages/_drupal.scss @@ -0,0 +1,10 @@ +._drupal { + h1#page-subtitle { + margin-top: 0; + @extend %lined-heading; + } + + h3 { @extend %block-heading; } + + .signature { @extend %note, %note-blue; } +} \ No newline at end of file diff --git a/lib/docs/filters/drupal/clean_html.rb b/lib/docs/filters/drupal/clean_html.rb new file mode 100644 index 00000000..f44214db --- /dev/null +++ b/lib/docs/filters/drupal/clean_html.rb @@ -0,0 +1,24 @@ +module Docs + class Drupal + class CleanHtmlFilter < Filter + def call + root_page? ? root : other + doc + end + + def root + doc.inner_html = ' ' + end + + def other + css('#page-title-tools', '.element-invisible', '.breadcrumb', '#sidebar-first', '#api-alternatives').remove + css('#aside', '#api-function-signature tr:not(.active)', '.comments').remove + # Replaces the signature table from api.drupal.org with a simple pre tag + css('#api-function-signature').each do |table| + signature = table.css('.signature').first.inner_html + table.replace '
' + signature + '
' + end + end + end + end +end diff --git a/lib/docs/filters/drupal/entries.rb b/lib/docs/filters/drupal/entries.rb new file mode 100644 index 00000000..95fa5748 --- /dev/null +++ b/lib/docs/filters/drupal/entries.rb @@ -0,0 +1,25 @@ +module Docs + class Drupal + class EntriesFilter < Docs::EntriesFilter + + def get_name + name = css('#page-subtitle').first.content + name.remove! 'function ' + name + end + + def path + Drupal::fixUri(result[:path]) + end + + def get_type + type = css('dl[api-related-topics] dt') + type.first ? type.first.content : nil + end + + def include_default_entry? + !initial_page? + end + end + end +end diff --git a/lib/docs/filters/drupal/internal_urls.rb b/lib/docs/filters/drupal/internal_urls.rb new file mode 100644 index 00000000..bc3e7bb9 --- /dev/null +++ b/lib/docs/filters/drupal/internal_urls.rb @@ -0,0 +1,12 @@ +module Docs + class Drupal + class InternalUrlsFilter < Docs::InternalUrlsFilter + def internal_path_to(url) + url = index_url if url == root_url + path = effective_url.relative_path_to(url) + URL.new(path: Drupal::fixUri(path), query: url.query, fragment: url.fragment).to_s + end + end + end +end + diff --git a/lib/docs/filters/drupal/normalize_paths.rb b/lib/docs/filters/drupal/normalize_paths.rb new file mode 100644 index 00000000..61ad5608 --- /dev/null +++ b/lib/docs/filters/drupal/normalize_paths.rb @@ -0,0 +1,11 @@ +module Docs + class Drupal + class NormalizePathsFilter < Docs::NormalizePathsFilter + + def store_path + p = Drupal::fixUri(@path) + File.extname(p) != '.html' ? "#{p}.html" : p + end + end + end +end \ No newline at end of file diff --git a/lib/docs/scrapers/drupal.rb b/lib/docs/scrapers/drupal.rb new file mode 100644 index 00000000..076c651f --- /dev/null +++ b/lib/docs/scrapers/drupal.rb @@ -0,0 +1,47 @@ +module Docs + class Drupal < UrlScraper + self.name = 'Drupal' + self.type = 'drupal' + self.version = '7.36' + self.base_url = 'https://api.drupal.org/api/drupal' + self.initial_paths = %w( + groups + groups?page=1) + + html_filters.replace 'normalize_paths', 'drupal/normalize_paths' + html_filters.replace 'internal_urls', 'drupal/internal_urls' + + html_filters.push 'drupal/entries', 'drupal/clean_html', 'title' + + options[:container] = '#page' + options[:title] = false + options[:root_title] = 'Drupal - Open Source CMS | Drupal.org' + + options[:only_patterns] = [ + /\/group\/[^\/]+\/7/, + /\/function\/[^\/]+\/7/] + + options[:skip_link] = ->(link) { + begin + return unless q = URL.parse(link['href']).query + Hash[URI.decode_www_form(q)].has_key? "order" + rescue URI::InvalidURIError + false + end + } + + options[:attribution] = <<-HTML + © 2000–2015 by the individual contributors.
+ Licensed under the Creative Commons License, Attribution-ShareAlike2.0.
+ Drupal is a registered trademark of Dries Buytaert. + HTML + + # Method used at several places to fix special characters at urls from api.drupal.org + def self.fixUri(path) + p = path.gsub /%21|!|%2b|%3b|%3a/i, '-' # !+;: + p.gsub! /\./, '_' # dots + p.gsub /__/, '..' # revert doble dots to prevent breaking relative urls + end + + end +end diff --git a/public/docs/docs.json b/public/docs/docs.json index 0637a088..a89a3473 100644 --- a/public/docs/docs.json +++ b/public/docs/docs.json @@ -1 +1 @@ -[] \ No newline at end of file +[{"name":"Angular.js","slug":"angular","type":"angular","version":"1.3.14","index_path":"angular/index.json","db_path":"angular/db.json","links":null,"mtime":1425223535,"db_size":891254},{"name":"Apache HTTP Server","slug":"apache_http_server","type":"apache","version":"2.4.12","index_path":"apache_http_server/index.json","db_path":"apache_http_server/db.json","links":{"home":"http://httpd.apache.org/"},"mtime":1430087732,"db_size":2806035},{"name":"Backbone.js","slug":"backbone","type":"underscore","version":"1.1.2","index_path":"backbone/index.json","db_path":"backbone/db.json","links":null,"mtime":1420139786,"db_size":77738},{"name":"Bower","slug":"bower","type":"bower","version":"1.4.1","index_path":"bower/index.json","db_path":"bower/db.json","links":{"home":"http://bower.io/","code":"https://github.com/bower/bower"},"mtime":1428072346,"db_size":30834},{"name":"C","slug":"c","type":"c","version":null,"index_path":"c/index.json","db_path":"c/db.json","links":null,"mtime":1420139786,"db_size":2715778},{"name":"Chai","slug":"chai","type":"chai","version":"2.2.0","index_path":"chai/index.json","db_path":"chai/db.json","links":null,"mtime":1427640231,"db_size":128007},{"name":"Clojure","slug":"clojure","type":"clojure","version":"1.6","index_path":"clojure/index.json","db_path":"clojure/db.json","links":null,"mtime":1424027537,"db_size":510607},{"name":"CoffeeScript","slug":"coffeescript","type":"coffeescript","version":"1.9.2","index_path":"coffeescript/index.json","db_path":"coffeescript/db.json","links":null,"mtime":1429455255,"db_size":52919},{"name":"Cordova","slug":"cordova","type":"cordova","version":"5.0.0","index_path":"cordova/index.json","db_path":"cordova/db.json","links":{"home":"http://cordova.apache.org/"},"mtime":1430070295,"db_size":534308},{"name":"C++","slug":"cpp","type":"c","version":null,"index_path":"cpp/index.json","db_path":"cpp/db.json","links":null,"mtime":1420139788,"db_size":16633717},{"name":"CSS","slug":"css","type":"mdn","version":null,"index_path":"css/index.json","db_path":"css/db.json","links":null,"mtime":1426472759,"db_size":4744530},{"name":"D3.js","slug":"d3","type":"d3","version":"3.5.5","index_path":"d3/index.json","db_path":"d3/db.json","links":null,"mtime":1430071727,"db_size":618295},{"name":"Django","slug":"django","type":"sphinx","version":"1.8.0","index_path":"django/index.json","db_path":"django/db.json","links":{"home":"https://www.djangoproject.com/","code":"https://github.com/django/django"},"mtime":1428074662,"db_size":4876714},{"name":"DOM","slug":"dom","type":"mdn","version":null,"index_path":"dom/index.json","db_path":"dom/db.json","links":null,"mtime":1428268443,"db_size":13474757},{"name":"DOM Events","slug":"dom_events","type":"mdn","version":null,"index_path":"dom_events/index.json","db_path":"dom_events/db.json","links":null,"mtime":1426472705,"db_size":919535},{"name":"Drupal","slug":"drupal","type":"drupal","version":"7.36","index_path":"drupal/index.json","db_path":"drupal/db.json","links":null,"mtime":1430781180,"db_size":50666550},{"name":"Ember.js","slug":"ember","type":"ember","version":"1.11.0","index_path":"ember/index.json","db_path":"ember/db.json","links":{"home":"http://emberjs.com/","code":"https://github.com/emberjs/ember.js"},"mtime":1427641891,"db_size":1279267},{"name":"Express","slug":"express","type":"express","version":"4.12.0","index_path":"express/index.json","db_path":"express/db.json","links":null,"mtime":1425224254,"db_size":160029},{"name":"Git","slug":"git","type":"git","version":"2.3.1","index_path":"git/index.json","db_path":"git/db.json","links":null,"mtime":1425224354,"db_size":1363050},{"name":"Go","slug":"go","type":"go","version":"1.4.1","index_path":"go/index.json","db_path":"go/db.json","links":null,"mtime":1422824401,"db_size":2419398},{"name":"Grunt","slug":"grunt","type":"grunt","version":"0.4.5","index_path":"grunt/index.json","db_path":"grunt/db.json","links":null,"mtime":1420139790,"db_size":116977},{"name":"Haskell","slug":"haskell","type":"haskell","version":"7.8.4","index_path":"haskell/index.json","db_path":"haskell/db.json","links":null,"mtime":1422824623,"db_size":6774712},{"name":"HTML","slug":"html","type":"mdn","version":null,"index_path":"html/index.json","db_path":"html/db.json","links":null,"mtime":1426472784,"db_size":1903322},{"name":"HTTP","slug":"http","type":"rfc","version":null,"index_path":"http/index.json","db_path":"http/db.json","links":null,"mtime":1424635284,"db_size":1183973},{"name":"io.js","slug":"iojs","type":"node","version":"1.8.1","index_path":"iojs/index.json","db_path":"iojs/db.json","links":{"home":"https://iojs.org/en/index.html","code":"https://github.com/iojs/io.js"},"mtime":1430071490,"db_size":632404},{"name":"JavaScript","slug":"javascript","type":"mdn","version":null,"index_path":"javascript/index.json","db_path":"javascript/db.json","links":null,"mtime":1426473778,"db_size":4598905},{"name":"jQuery","slug":"jquery","type":"jquery","version":"up to 2.1.0","index_path":"jquery/index.json","db_path":"jquery/db.json","links":null,"mtime":1420139791,"db_size":1783170},{"name":"jQuery Mobile","slug":"jquerymobile","type":"jquery","version":"1.4.0","index_path":"jquerymobile/index.json","db_path":"jquerymobile/db.json","links":null,"mtime":1420139791,"db_size":1033621},{"name":"jQuery UI","slug":"jqueryui","type":"jquery","version":"1.10.4","index_path":"jqueryui/index.json","db_path":"jqueryui/db.json","links":null,"mtime":1420139791,"db_size":826305},{"name":"Knockout.js","slug":"knockout","type":"knockout","version":"3.3.0","index_path":"knockout/index.json","db_path":"knockout/db.json","links":null,"mtime":1424535229,"db_size":394621},{"name":"Laravel","slug":"laravel","type":"laravel","version":"5.0.0","index_path":"laravel/index.json","db_path":"laravel/db.json","links":null,"mtime":1423421754,"db_size":6771984},{"name":"Less","slug":"less","type":"less","version":"2.5.0","index_path":"less/index.json","db_path":"less/db.json","links":{"home":"http://lesscss.org/","code":"https://github.com/less/less.js"},"mtime":1428071398,"db_size":144435},{"name":"lodash","slug":"lodash","type":"lodash","version":"3.7.0","index_path":"lodash/index.json","db_path":"lodash/db.json","links":{"home":"https://lodash.com/","code":"https://github.com/lodash/lodash/"},"mtime":1429455396,"db_size":238366},{"name":"Lua","slug":"lua","type":"lua","version":"5.3","index_path":"lua/index.json","db_path":"lua/db.json","links":null,"mtime":1424016672,"db_size":314005},{"name":"Marionette.js","slug":"marionette","type":"marionette","version":"2.4.1","index_path":"marionette/index.json","db_path":"marionette/db.json","links":null,"mtime":1425224881,"db_size":302115},{"name":"Markdown","slug":"markdown","type":"markdown","version":null,"index_path":"markdown/index.json","db_path":"markdown/db.json","links":null,"mtime":1420139791,"db_size":31338},{"name":"MaxCDN","slug":"maxcdn","type":"maxcdn","version":null,"index_path":"maxcdn/index.json","db_path":"maxcdn/db.json","links":null,"mtime":1429455761,"db_size":381917},{"name":"Meteor","slug":"meteor","type":"meteor","version":"1.1.0","index_path":"meteor/index.json","db_path":"meteor/db.json","links":{"home":"https://www.meteor.com/","code":"https://github.com/meteor/meteor/"},"mtime":1428071920,"db_size":397414},{"name":"Ruby / Minitest","slug":"minitest","type":"rdoc","version":"5.6.0","index_path":"minitest/index.json","db_path":"minitest/db.json","links":null,"mtime":1429455019,"db_size":163280},{"name":"mocha","slug":"mocha","type":"mocha","version":"2.2.1","index_path":"mocha/index.json","db_path":"mocha/db.json","links":{"home":"http://mochajs.org/","code":"https://github.com/mochajs/mocha"},"mtime":1427040187,"db_size":34704},{"name":"Modernizr","slug":"modernizr","type":"modernizr","version":"2.8.3","index_path":"modernizr/index.json","db_path":"modernizr/db.json","links":null,"mtime":1420139791,"db_size":35933},{"name":"Moment.js","slug":"moment","type":"moment","version":"2.10.2","index_path":"moment/index.json","db_path":"moment/db.json","links":null,"mtime":1429454707,"db_size":153981},{"name":"Mongoose","slug":"mongoose","type":"mongoose","version":"3.8.19","index_path":"mongoose/index.json","db_path":"mongoose/db.json","links":null,"mtime":1420139791,"db_size":434220},{"name":"nginx","slug":"nginx","type":"nginx","version":"1.8.0","index_path":"nginx/index.json","db_path":"nginx/db.json","links":{"home":"http://nginx.org/","code":"http://hg.nginx.org/nginx"},"mtime":1430071381,"db_size":880848},{"name":"Node.js","slug":"node","type":"node","version":"0.12.1","index_path":"node/index.json","db_path":"node/db.json","links":{"home":"https://nodejs.org/","code":"https://github.com/joyent/node"},"mtime":1427640721,"db_size":595207},{"name":"Nokogiri","slug":"nokogiri","type":"rdoc","version":"1.6.4","index_path":"nokogiri/index.json","db_path":"nokogiri/db.json","links":null,"mtime":1420139792,"db_size":463492},{"name":"npm","slug":"npm","type":"npm","version":"2.8.4","index_path":"npm/index.json","db_path":"npm/db.json","links":{"home":"https://www.npmjs.com/","code":"https://github.com/npm/npm"},"mtime":1430079997,"db_size":341035},{"name":"PHP","slug":"php","type":"php","version":"up to 5.6.6","index_path":"php/index.json","db_path":"php/db.json","links":null,"mtime":1424537130,"db_size":20696713},{"name":"PHPUnit","slug":"phpunit","type":"phpunit","version":"4.6","index_path":"phpunit/index.json","db_path":"phpunit/db.json","links":null,"mtime":1429454793,"db_size":402365},{"name":"PostgreSQL","slug":"postgresql","type":"postgres","version":"9.4","index_path":"postgresql/index.json","db_path":"postgresql/db.json","links":null,"mtime":1420139795,"db_size":3815543},{"name":"Python","slug":"python","type":"sphinx","version":"3.4.2","index_path":"python/index.json","db_path":"python/db.json","links":null,"mtime":1420139795,"db_size":6901990},{"name":"Python 2","slug":"python2","type":"sphinx","version":"2.7.8","index_path":"python2/index.json","db_path":"python2/db.json","links":null,"mtime":1420139795,"db_size":7605038},{"name":"Ruby on Rails","slug":"rails","type":"rdoc","version":"4.2.1","index_path":"rails/index.json","db_path":"rails/db.json","links":{"home":"http://rubyonrails.org/","code":"https://github.com/rails/rails"},"mtime":1427036547,"db_size":3699249},{"name":"React","slug":"react","type":"react","version":"0.13.2","index_path":"react/index.json","db_path":"react/db.json","links":{"home":"http://facebook.github.io/react/","code":"https://github.com/facebook/react"},"mtime":1429455671,"db_size":247301},{"name":"Redis","slug":"redis","type":"redis","version":"up to 3.0.0","index_path":"redis/index.json","db_path":"redis/db.json","links":{"home":"http://redis.io/","code":"https://github.com/antirez/redis"},"mtime":1428073052,"db_size":559294},{"name":"RequireJS","slug":"requirejs","type":"requirejs","version":"2.1.15","index_path":"requirejs/index.json","db_path":"requirejs/db.json","links":null,"mtime":1420139796,"db_size":167002},{"name":"RethinkDB","slug":"rethinkdb","type":"rethinkdb","version":"2.0.1","index_path":"rethinkdb/index.json","db_path":"rethinkdb/db.json","links":{"home":"http://rethinkdb.com/","code":"https://github.com/rethinkdb/rethinkdb"},"mtime":1429456533,"db_size":478086},{"name":"Ruby","slug":"ruby","type":"rdoc","version":"2.2.1","index_path":"ruby/index.json","db_path":"ruby/db.json","links":{"home":"https://www.ruby-lang.org/","code":"https://github.com/ruby/ruby"},"mtime":1427644483,"db_size":6652108},{"name":"Sass","slug":"sass","type":"yard","version":"3.4.11","index_path":"sass/index.json","db_path":"sass/db.json","links":null,"mtime":1422826089,"db_size":203816},{"name":"Sinon","slug":"sinon","type":"sinon","version":"1.14.0","index_path":"sinon/index.json","db_path":"sinon/db.json","links":{"home":"http://sinonjs.org/","code":"https://github.com/cjohansen/Sinon.JS"},"mtime":1426424879,"db_size":72648},{"name":"Socket.IO","slug":"socketio","type":"socketio","version":"1.3.4","index_path":"socketio/index.json","db_path":"socketio/db.json","links":null,"mtime":1424535350,"db_size":43048},{"name":"SVG","slug":"svg","type":"mdn","version":null,"index_path":"svg/index.json","db_path":"svg/db.json","links":null,"mtime":1429457144,"db_size":1629057},{"name":"Symfony","slug":"symfony","type":"laravel","version":"2.6","index_path":"symfony/index.json","db_path":"symfony/db.json","links":null,"mtime":1424038595,"db_size":11761036},{"name":"Underscore.js","slug":"underscore","type":"underscore","version":"1.8.3","index_path":"underscore/index.json","db_path":"underscore/db.json","links":null,"mtime":1429455200,"db_size":52523},{"name":"XPath","slug":"xpath","type":"mdn","version":null,"index_path":"xpath/index.json","db_path":"xpath/db.json","links":null,"mtime":1420139796,"db_size":93695},{"name":"Yii","slug":"yii","type":"yii","version":"2.0.2","index_path":"yii/index.json","db_path":"yii/db.json","links":null,"mtime":1423414038,"db_size":14309051},{"name":"Yii 1","slug":"yii1","type":"yii","version":"1.1.16","index_path":"yii1/index.json","db_path":"yii1/db.json","links":null,"mtime":1424012029,"db_size":13066030}] \ No newline at end of file diff --git a/public/icons/docs/drupal/16.png b/public/icons/docs/drupal/16.png new file mode 100644 index 0000000000000000000000000000000000000000..f731b7d3ff74900e85d3ac0fb4cbb8f64b3f9560 GIT binary patch literal 704 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