History

Add SQLite documentation

Thibaut Courouble committed 9 years ago

Commit 0c8ca4e1 parent be1390321 files · +332 −4Browse files

Unified · Split

21 files
  1. assets/images/docs.png +0 −0
  2. assets/images/docs@2x.png +0 −0
  3. assets/javascripts/news.json +3 −0
  4. assets/javascripts/templates/pages/about_tmpl.coffee +5 −0
  5. assets/javascripts/views/pages/sqlite.coffee +17 −0
  6. assets/stylesheets/application-dark.css.scss +1 −0
  7. assets/stylesheets/application.css.scss +1 −0
  8. assets/stylesheets/components/_content.scss +13 −0
  9. assets/stylesheets/global/_icons.scss +1 −0
  10. assets/stylesheets/pages/_sqlite.scss +6 −0
  11. lib/docs/core/parser.rb +4 −4
  12. lib/docs/core/scraper.rb +6 −2
  13. lib/docs/filters/core/clean_html.rb +1 −1
  14. lib/docs/filters/git/entries.rb +1 −1
  15. lib/docs/filters/sqlite/clean_html.rb +92 −0
  16. lib/docs/filters/sqlite/clean_js_tables.rb +42 −0
  17. lib/docs/filters/sqlite/entries.rb +79 −0
  18. lib/docs/scrapers/sqlite.rb +52 −0
  19. public/icons/docs/sqlite/16.png +0 −0
  20. public/icons/docs/sqlite/16@2x.png +0 −0
  21. test/lib/docs/core/parser_test.rb +12 −0
assets/images/docs.png+0−0

Binary file not shown.

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

Binary file not shown.

assets/javascripts/news.json+3−0
@@ -1,5 +1,8 @@
1[1[
2 [2 [
3 "2016-12-04",
4 "New documentation: <a href=\"/sqlite/\">SQLite</a>"
5 ], [
3 "2016-11-20",6 "2016-11-20",
4 "New documentations: <a href=\"/yarn/\">Yarn</a>, <a href=\"/immutable/\">Immutable.js</a> and <a href=\"/async/\">Async</a>"7 "New documentations: <a href=\"/yarn/\">Yarn</a>, <a href=\"/immutable/\">Immutable.js</a> and <a href=\"/async/\">Async</a>"
5 ], [8 ], [
assets/javascripts/templates/pages/about_tmpl.coffee+5−0
@@ -529,6 +529,11 @@ credits = [ · 528 unmodified lines
529 '2014-2015 Automattic',529 '2014-2015 Automattic',
530 'MIT',530 'MIT',
531 'https://raw.githubusercontent.com/Automattic/socket.io/master/LICENSE'531 'https://raw.githubusercontent.com/Automattic/socket.io/master/LICENSE'
532 ], [
533 'SQLite',
534 'n/a',
535 'Public Domain',
536 'https://sqlite.org/copyright.html'
532 ], [537 ], [
533 'Statsmodels',538 'Statsmodels',
534 '2009-2012 Statsmodels Developers<br>&copy; 2006-2008 Scipy Developers<br>&copy; 2006 Jonathan E. Taylor',539 '2009-2012 Statsmodels Developers<br>&copy; 2006-2008 Scipy Developers<br>&copy; 2006 Jonathan E. Taylor',
assets/javascripts/views/pages/sqlite.coffee+17−0
@@ -0,0 +1,17 @@
1#= require views/pages/simple
2
3class app.views.SqlitePage extends app.views.SimplePage
4 @events:
5 click: 'onClick'
6
7 onClick: (event) =>
8 return unless id = event.target.getAttribute('data-toggle')
9 return unless el = @find("##{id}")
10 $.stopEvent(event)
11 if el.style.display == 'none'
12 el.style.display = 'block'
13 event.target.textContent = 'hide'
14 else
15 el.style.display = 'none'
16 event.target.textContent = 'show'
17 return
assets/stylesheets/application-dark.css.scss+1−0
@@ -84,6 +84,7 @@ · 83 unmodified lines
84 'pages/socketio',84 'pages/socketio',
85 'pages/sphinx',85 'pages/sphinx',
86 'pages/sphinx_simple',86 'pages/sphinx_simple',
87 'pages/sqlite',
87 'pages/support_tables',88 'pages/support_tables',
88 'pages/tcl_tk',89 'pages/tcl_tk',
89 'pages/tensorflow',90 'pages/tensorflow',
assets/stylesheets/application.css.scss+1−0
@@ -84,6 +84,7 @@ · 83 unmodified lines
84 'pages/socketio',84 'pages/socketio',
85 'pages/sphinx',85 'pages/sphinx',
86 'pages/sphinx_simple',86 'pages/sphinx_simple',
87 'pages/sqlite',
87 'pages/support_tables',88 'pages/support_tables',
88 'pages/tcl_tk',89 'pages/tcl_tk',
89 'pages/tensorflow',90 'pages/tensorflow',
assets/stylesheets/components/_content.scss+13−0
@@ -391,6 +391,19 @@ · 390 unmodified lines
391 &._pre-clip-error:after { content: 'Error'; }391 &._pre-clip-error:after { content: 'Error'; }
392}392}
393 393
394._btn {
395 white-space: nowrap;
396 padding: .125rem .375rem;
397 background-image: linear-gradient(lighten($boxBackground, 3%), darken($boxBackground, 4%));
398 border: 1px solid $boxBorder;
399 border-radius: 3px;
400
401 &:active {
402 background-color: $boxBackground;
403 box-shadow: inset 0 1px 3px rgba(black, .15);
404 }
405}
406
394._github-btn {407._github-btn {
395 display: inline-block;408 display: inline-block;
396 vertical-align: text-top;409 vertical-align: text-top;
assets/stylesheets/global/_icons.scss+1−0
@@ -56,6 +56,7 @@ · 55 unmodified lines
56%icon-close-white { background-position: -2rem -5rem; }56%icon-close-white { background-position: -2rem -5rem; }
57%icon-back { background-position: -3rem -5rem; @extend %darkIconFix !optional; }57%icon-back { background-position: -3rem -5rem; @extend %darkIconFix !optional; }
58 58
59._icon-sqlite:before { background-position: -5rem 0; @extend %darkIconFix !optional; }
59._icon-async:before { background-position: -6rem 0; @extend %darkIconFix !optional; }60._icon-async:before { background-position: -6rem 0; @extend %darkIconFix !optional; }
60._icon-http:before { background-position: -7rem 0; @extend %darkIconFix !optional; }61._icon-http:before { background-position: -7rem 0; @extend %darkIconFix !optional; }
61._icon-jquery:before { background-position: -8rem 0; @extend %darkIconFix !optional; }62._icon-jquery:before { background-position: -8rem 0; @extend %darkIconFix !optional; }
assets/stylesheets/pages/_sqlite.scss+6−0
@@ -0,0 +1,6 @@
1._sqlite {
2 @extend %simple;
3
4 dt { @extend %block-label, %label-blue; }
5 .todo { @extend %note, %note-red; }
6}
lib/docs/core/parser.rb+4−4
@@ -1,11 +1,10 @@
1module Docs1module Docs
2 class Parser2 class Parser
3 attr_reader :title, :html
4
3 def initialize(content)5 def initialize(content)
4 @content = content6 @content = content
5 end7 @html = document? ? parse_as_document : parse_as_fragment
6
7 def html
8 @html ||= document? ? parse_as_document : parse_as_fragment
9 end8 end
10 9
11 private10 private
@@ -16,6 +15,7 @@ module Docs · 4 unmodified lines
16 15
17 def parse_as_document16 def parse_as_document
18 document = Nokogiri::HTML.parse @content, nil, 'UTF-8'17 document = Nokogiri::HTML.parse @content, nil, 'UTF-8'
18 @title = document.at_css('title').try(:content)
19 document.at_css 'body'19 document.at_css 'body'
20 end20 end
21 21
lib/docs/core/scraper.rb+6−2
@@ -171,7 +171,10 @@ module Docs · 170 unmodified lines
171 171
172 def process_response(response)172 def process_response(response)
173 data = {}173 data = {}
174 pipeline.call(parse(response.body), pipeline_context(response), data)174 html, title = parse(response.body)
175 context = pipeline_context(response)
176 context[:html_title] = title
177 pipeline.call(html, context, data)
175 data178 data
176 end179 end
177 180
@@ -180,7 +183,8 @@ module Docs · 2 unmodified lines
180 end183 end
181 184
182 def parse(string)185 def parse(string)
183 Parser.new(string).html186 parser = Parser.new(string)
187 [parser.html, parser.title]
184 end188 end
185 189
186 def with_filters(*filters)190 def with_filters(*filters)
lib/docs/filters/core/clean_html.rb+1−1
@@ -1,7 +1,7 @@
1module Docs1module Docs
2 class CleanHtmlFilter < Filter2 class CleanHtmlFilter < Filter
3 def call3 def call
4 css('script', 'style').remove4 css('script', 'style', 'link').remove
5 xpath('descendant::comment()').remove5 xpath('descendant::comment()').remove
6 xpath('./text()', './/text()[not(ancestor::pre) and not(ancestor::code) and not(ancestor::div[contains(concat(" ", normalize-space(@class), " "), " prism ")])]').each do |node|6 xpath('./text()', './/text()[not(ancestor::pre) and not(ancestor::code) and not(ancestor::div[contains(concat(" ", normalize-space(@class), " "), " prism ")])]').each do |node|
7 content = node.content7 content = node.content
lib/docs/filters/git/entries.rb+1−1
@@ -15,7 +15,7 @@ module Docs · 14 unmodified lines
15 elsif slug == 'git' || slug.start_with?('git-')15 elsif slug == 'git' || slug.start_with?('git-')
16 'Git'16 'Git'
17 else17 else
18 'Miscellaenous'18 'Miscellaneous'
19 end19 end
20 end20 end
21 end21 end
lib/docs/filters/sqlite/clean_html.rb+92−0
@@ -0,0 +1,92 @@
1module Docs
2 class Sqlite
3 class CleanHtmlFilter < Filter
4 def call
5 at_css('.nosearch').remove
6
7 css('.rightsidebar', 'hr', '.sh_mark', '.fancy_toc > a', '.fancy_toc_mark', 'h[style*="none"]',
8 'a[href$="intro.html"] > h2', 'a[href$="intro"] > h2', '#document_title + #toc_header',
9 '#document_title ~ #toc').remove
10
11 css('.fancy_title', '> h2[align=center]', '#document_title').each do |node|
12 node.name = 'h1'
13 end
14
15 unless at_css('h1')
16 if at_css('h2').content == context[:html_title]
17 at_css('h2').name = 'h1'
18 else
19 doc.child.before("<h1>#{context[:html_title]}</h1>")
20 end
21 end
22
23 if root_page?
24 at_css('h1').content = 'SQLite Documentation'
25 end
26
27 css('.codeblock', '.fancy', '.nosearch', '.optab > blockquote', '.optab').each do |node|
28 node.before(node.children).remove
29 end
30
31 css('blockquote').each do |node|
32 next unless node.at_css('b')
33 node.name = 'pre'
34 node.inner_html = node.inner_html.gsub('<br>', "\n")
35 end
36
37 css('.todo').each do |node|
38 node.inner_html = "TODO: #{node.inner_html}"
39 end
40
41 css('blockquote > pre', 'a > h1', 'a > h2', 'center > table', 'ul > ul').each do |node|
42 node.parent.before(node.parent.children).remove
43 end
44
45 css('table > tr:first-child:last-child > td:first-child:last-child > pre',
46 'table > tr:first-child:last-child > td:first-child:last-child > ul').each do |node|
47 node.ancestors('table').first.replace(node)
48 end
49
50 css('a[name]').each do |node|
51 if node.next_element
52 if node.next_element['id']
53 node.next_element.next_element['id'] ||= node['name']
54 else
55 node.next_element['id'] = node['name']
56 end
57 else
58 node.parent['id'] ||= node['name']
59 end
60 node.remove
61 end
62
63 unless at_css('h2')
64 css('h1 ~ h1').each do |node|
65 node.name = 'h2'
66 end
67 end
68
69 css('tt').each do |node|
70 node.name = 'code'
71 end
72
73 css('pre').each do |node|
74 node.content = node.content
75 node['data-language'] = 'sql'
76 end
77
78 css('button[onclick]').each do |node|
79 node['class'] = '_btn'
80 node['data-toggle'] = node['onclick'][/hideorshow\("\w+","(\w+)"\)/, 1]
81 node.remove_attribute('onclick')
82 end
83
84 css('*[align]').remove_attr('align')
85 css('*[style]:not(.imgcontainer)').remove_attr('style')
86 css('table[border]').remove_attr('border')
87
88 doc
89 end
90 end
91 end
92end
lib/docs/filters/sqlite/clean_js_tables.rb+42−0
@@ -0,0 +1,42 @@
1module Docs
2 class Sqlite
3 class CleanJsTablesFilter < Filter
4 def call
5 css('table[id]:empty + script').each do |node|
6 json_list = JSON.parse(node.inner_html[/\[.+?\]/m])
7 list = '<ul>'
8 json_list.each do |item|
9 list << '<li>'
10
11 unless item['u'].blank? || item['s'] == 2
12 list << %(<a href="#{item['u']}">)
13 link = true
14 end
15
16 if item['s'] == 2 || item['s'] == 3
17 list << "<s>#{item['x']}</s>"
18 else
19 list << item['x']
20 end
21
22 list << '</a>' if link
23
24 if item['s'] == 1
25 list << ' <small><i>(exp)</i></small>'
26 elsif item['s'] == 3
27 list << '&sup1;'
28 elsif item['s'] == 4
29 list << '&sup2;'
30 elsif item['s'] == 5
31 list << '&sup3;'
32 end
33 end
34 list << '</ul>'
35 node.previous_element.replace(list)
36 end
37
38 doc
39 end
40 end
41 end
42end
lib/docs/filters/sqlite/entries.rb+79−0
@@ -0,0 +1,79 @@
1module Docs
2 class Sqlite
3 class EntriesFilter < Docs::EntriesFilter
4 ADDITIONAL_ENTRIES = {}
5
6 def get_name
7 name = context[:html_title]
8 name.remove! 'SQLite Query Language: '
9 name.remove! %r{\.\z}
10 name = at_css('#document_title').content if name == 'No Title'
11 name
12 end
13
14 TYPE_BY_SUBPATH_STARTS_WITH = {
15 'c3ref' => 'C Interface',
16 'capi' => 'C Interface',
17 'session' => 'C Interface: Session Module',
18 'optoverview' => 'Query Planner',
19 'queryplanner' => 'Query Planner',
20 'syntax' => 'Syntax Diagrams',
21 'lang' => 'Language',
22 'pragma' => 'PRAGMA Statements',
23 'cli' => 'CLI',
24 'json' => 'JSON',
25 'fileformat' => 'Database File Format',
26 'tcl' => 'Tcl Interface',
27 'malloc' => 'Dynamic Memory Allocation',
28 'vtab' => 'Virtual Table Mechanism',
29 'datatype' => 'Datatypes',
30 'locking' => 'Locking and Concurrency',
31 'foreignkey' => 'Foreign Key Constraints',
32 'wal' => 'Write-Ahead Logging',
33 'fts' => 'Full-Text Search',
34 'rtree' => 'R*Tree Module',
35 'rbu' => 'RBU Extension',
36 'limits' => 'Limits',
37 'howtocorrupt' => 'How To Corrupt'
38 }
39
40 def get_type
41 TYPE_BY_SUBPATH_STARTS_WITH.each_pair do |key, value|
42 return value if subpath.start_with?(key)
43 end
44
45 if slug.in?(%w(cintro carray c_interface))
46 'C Interface'
47 elsif context[:html_title].start_with?('SQLite Query Language')
48 'Query Language'
49 else
50 'Miscellaneous'
51 end
52 end
53
54 IGNORE_ADDITIONAL_ENTRIES_SLUGS = %w(testing uri getthecode whentouse compile)
55
56 def additional_entries
57 if subpath == 'keyword_index.html'
58 css('li a[href*="#"]').each do |node|
59 slug, id = node['href'].split('#')
60 name = node.content.strip
61 next if name.start_with?('-') || IGNORE_ADDITIONAL_ENTRIES_SLUGS.include?(slug)
62 name.remove! %r{\Athe }
63 name.remove! %r{ SQL function\z}
64 name = 'ORDER BY' if name == 'order by'
65 name.sub!(/\A([a-z])([a-z]+) /) { "#{$1.upcase}#{$2} " }
66 ADDITIONAL_ENTRIES[slug] ||= []
67 ADDITIONAL_ENTRIES[slug] << [name, id]
68 end
69 end
70
71 ADDITIONAL_ENTRIES[slug] || []
72 end
73
74 def include_default_entry?
75 subpath != 'keyword_index.html' && subpath != 'sitemap.html'
76 end
77 end
78 end
79end
lib/docs/scrapers/sqlite.rb+52−0
@@ -0,0 +1,52 @@
1module Docs
2 class Sqlite < FileScraper
3 self.name = 'SQLite'
4 self.type = 'sqlite'
5 self.release = '3.15.2'
6 self.dir = '/Users/Thibaut/DevDocs/Docs/sqlite/'
7 self.base_url = 'https://sqlite.org/'
8 self.root_path = 'docs.html'
9 self.initial_paths = %w(keyword_index.html)
10 self.links = {
11 home: 'https://sqlite.org/',
12 code: 'https://www.sqlite.org/src/'
13 }
14
15 html_filters.insert_before 'clean_html', 'sqlite/clean_js_tables'
16 html_filters.push 'sqlite/entries', 'sqlite/clean_html'
17
18 options[:only_patterns] = [/\.html\z/]
19 options[:skip_patterns] = [/releaselog/, /consortium/]
20 options[:skip] = %w(
21 index.html
22 about.html
23 download.html
24 copyright.html
25 support.html
26 prosupport.html
27 hp1.html
28 news.html
29 oldnews.html
30 doclist.html
31 dev.html
32 chronology.html
33 not-found.html
34 famous.html
35 books.html
36 crew.html
37 mostdeployed.html
38 requirements.html
39 session/intro.html
40 syntax.html
41 )
42
43 options[:attribution] = 'SQLite is in the Public Domain.'
44
45 private
46
47 def parse(html)
48 html.gsub! %r{(<h2[^>]*>[^<]+)</h1>}, '\1</h2>'
49 super
50 end
51 end
52end
public/icons/docs/sqlite/16.png+0−0

Binary file not shown.

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

Binary file not shown.

test/lib/docs/core/parser_test.rb+12−0
@@ -28,4 +28,16 @@ class DocsParserTest < MiniTest::Spec · 27 unmodified lines
28 end28 end
29 end29 end
30 end30 end
31
32 describe "#title" do
33 it "returns nil when there is no <title>" do
34 body = '<!doctype html><meta charset=utf-8><div>Test</div>'
35 assert_nil parser(body).title
36 end
37
38 it "returns the <title> when there is one" do
39 body = '<!doctype html><meta charset=utf-8><title>Title</title><div>Test</div>'
40 assert_equal 'Title', parser(body).title
41 end
42 end
31end43end