docubot 0.2.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/bin/docubot +4 -0
  2. data/lib/docubot.rb +5 -1
  3. data/lib/docubot/bundle.rb +10 -5
  4. data/lib/docubot/index.rb +5 -4
  5. data/lib/docubot/page.rb +25 -4
  6. data/lib/docubot/templates/index.haml +20 -13
  7. data/lib/docubot/templates/toc.haml +2 -0
  8. data/lib/docubot/writers/chm.rb +5 -1
  9. data/lib/docubot/writers/html.rb +3 -0
  10. data/test/site1_html/A Slight Change of Heart/1 Ze First Page in Ze Section.html +30 -0
  11. data/test/site1_html/A Slight Change of Heart/2 Another Page in the Section.html +30 -0
  12. data/test/site1_html/A Slight Change of Heart/3_more_crap.html +42 -0
  13. data/test/site1_html/A Slight Change of Heart/3_more_crap.html#frist-post +29 -0
  14. data/test/site1_html/A Slight Change of Heart/3_more_crap.html#moar +29 -0
  15. data/test/site1_html/A Slight Change of Heart/index.html +28 -0
  16. data/test/site1_html/_index.html +17 -0
  17. data/test/site1_html/_toc.html +73 -0
  18. data/test/site1_html/appendices/gkheadftw.html +32 -0
  19. data/test/site1_html/appendices/index.html +28 -0
  20. data/test/site1_html/common.css +108 -0
  21. data/test/site1_html/glossary-terms.js +1 -0
  22. data/test/site1_html/headers.html +42 -0
  23. data/test/site1_html/preamble.html +36 -0
  24. data/test/site1_html/raw.html +33 -0
  25. data/test/site1_html/toc.css +0 -0
  26. data/test/site1_html/toc.js +0 -0
  27. metadata +38 -28
  28. data/lib/docubot/shells/nvphysx/0_License.md +0 -3
  29. data/lib/docubot/shells/nvphysx/1_Getting_Started.haml +0 -51
  30. data/lib/docubot/shells/nvphysx/Appendix/Glossary.md +0 -7
  31. data/lib/docubot/shells/nvphysx/_glossary/APEX.md +0 -1
  32. data/lib/docubot/shells/nvphysx/_glossary/NVIDIA.md +0 -1
  33. data/lib/docubot/shells/nvphysx/_glossary/PhysX.textile +0 -3
  34. data/lib/docubot/shells/nvphysx/_static/NVBadge_3D.png +0 -0
  35. data/lib/docubot/shells/nvphysx/_static/PhysXbyNV_Black.png +0 -0
  36. data/lib/docubot/shells/nvphysx/_templates/_root/bg_green_bar_revised.gif +0 -0
  37. data/lib/docubot/shells/nvphysx/_templates/_root/close.png +0 -0
  38. data/lib/docubot/shells/nvphysx/_templates/_root/common.css +0 -264
  39. data/lib/docubot/shells/nvphysx/_templates/_root/glossary.css +0 -4
  40. data/lib/docubot/shells/nvphysx/_templates/_root/glossary.js +0 -24
  41. data/lib/docubot/shells/nvphysx/_templates/_root/nvdevtools.js +0 -31
  42. data/lib/docubot/shells/nvphysx/_templates/_root/nvidia-logo.gif +0 -0
  43. data/lib/docubot/shells/nvphysx/_templates/_root/right-sidebar.png +0 -0
  44. data/lib/docubot/shells/nvphysx/_templates/top.haml +0 -28
  45. data/lib/docubot/shells/nvphysx/index.txt +0 -5
@@ -99,7 +99,11 @@ if ARGS[:create]
99
99
  end
100
100
  end
101
101
  else
102
+ start = Time.now
102
103
  bundle = DocuBot::Bundle.new( ARGS[:directory] )
104
+ lap = Time.now
105
+ puts "%.2fs to prepare the bundle..." % (lap-start)
103
106
  bundle.write( ARGS[:writer], ARGS[:output] )
107
+ puts "%.2fs to write everything." % (Time.now-lap)
104
108
  end
105
109
 
@@ -20,12 +20,16 @@ module FileUtils
20
20
  end
21
21
 
22
22
  module DocuBot
23
- VERSION = '0.2.2'
23
+ VERSION = '0.3'
24
24
  DIR = File.expand_path( File.dirname( __FILE__ ) )
25
25
 
26
26
  TEMPLATE_DIR = DIR / 'docubot/templates'
27
27
  SHELL_DIR = DIR / 'docubot/shells'
28
28
  Dir.chdir( SHELL_DIR ){ SHELLS = Dir['*'] }
29
+
30
+ def self.id_from_text( text )
31
+ text.strip.gsub(/[^\w.:-]+/,'-').gsub(/^-|-$/,'')
32
+ end
29
33
  end
30
34
 
31
35
  require 'docubot/snippet'
@@ -34,11 +34,16 @@ class DocuBot::Bundle
34
34
 
35
35
  # TODO: Move this bloat elsewhere.
36
36
  if page.toc?
37
- html = page.to_html
38
- page.toc.scan /[a-z][\w.:-]*/i do |id|
39
- # TODO: Maybe a lightweight HTML parser would be faster here? (Certainly more robust.)
40
- if title = html[/\b(?:id|ID) *= *['"]#{id}['"][^>]*>([^<]+)/,1]
41
- page << DocuBot::SubLink.new( page, title.strip, id )
37
+ ndoc = page.nokodoc
38
+ toc = page.toc
39
+ ids = if toc[','] # Comma-delimited toc interpreted as generated ids
40
+ toc.split(/,\s*/).map{ |title| DocuBot.id_from_text(title) }
41
+ else
42
+ toc.scan /[a-z][\w.:-]*/i
43
+ end
44
+ ids.each do |id|
45
+ if ele = ndoc.at_css("##{id}")
46
+ page << DocuBot::SubLink.new( page, ele.inner_text, id )
42
47
  else
43
48
  warn "Could not find requested toc anchor '##{id}' on #{page.html_path}"
44
49
  end
@@ -29,14 +29,15 @@ class DocuBot::Index
29
29
  def process_page( page )
30
30
  page.keywords.split(/,\s*/).each{ |key| add( key, page ) } if page.keywords?
31
31
 
32
- html = page.to_html
32
+ # FIXME: This is substantially slower (but way more correct) than regexp only.
33
33
  unless page['no-index'] && page['no-index'].include?( 'headings' )
34
- #TODO: Fix the regex to use a backreference to ensure the correct closing tag, once 1.8x support is not necessary
35
- html.scan( %r{<h[1-6][^>]*>(.+?)</h[1-6]>}im ){ |captures| add( captures.first, page ) }
34
+ %w[h1 h2 h3 h4 h5 h6].each do |hn|
35
+ page.nokodoc.css(hn).each{ |head| add( head.inner_text, page ) }
36
+ end
36
37
  end
37
38
 
38
39
  unless page['no-index'] && page['no-index'].include?( 'definitions' )
39
- html.scan( %r{<dt[^>]*>(.+?)</dt>}im ){ |captures| add captures.first, page }
40
+ page.nokodoc.css("dt").each{ |defn| add( defn.inner_text, page ) }
40
41
  end
41
42
  end
42
43
 
@@ -1,7 +1,10 @@
1
1
  # encoding: UTF-8
2
2
  require 'yaml'
3
+ require 'nokogiri'
4
+
3
5
  class DocuBot::Page
4
6
  META_SEPARATOR = /^\+\+\+\s*$/ # Sort of like +++ATH0
7
+ AUTO_ID_ELEMENTS = %w[ h1 h2 h3 h4 h5 h6 legend caption dt ].join(',')
5
8
 
6
9
  attr_reader :pages, :type, :folder, :file, :meta
7
10
  attr_accessor :parent, :bundle
@@ -32,7 +35,9 @@ class DocuBot::Page
32
35
  end
33
36
 
34
37
  # Raw markup, untransformed
35
- @raw = parts.last
38
+ if @raw = parts.last && parts.last.strip
39
+ @raw = @raw
40
+ end
36
41
  end
37
42
  end
38
43
  def []( key )
@@ -89,8 +94,9 @@ class DocuBot::Page
89
94
  def to_html
90
95
  return @cached_html if @cached_html
91
96
 
92
- contents = if @raw
97
+ contents = if @raw && !@raw.empty?
93
98
  # Directories with no index.* file will not have any @raw
99
+ # TODO: Swap the order of these once we're sure that all converters will pass raw HTML through.
94
100
  html = DocuBot::convert_to_html( self, @raw, @type )
95
101
  DocuBot::process_snippets( self, html )
96
102
  end
@@ -104,14 +110,29 @@ class DocuBot::Page
104
110
  haml = master_templates / "#{template}.haml" unless File.exists?( haml )
105
111
  haml = master_templates / "page.haml" unless File.exists?( haml )
106
112
  haml = Haml::Engine.new( IO.read( haml ), DocuBot::Writer::HAML_OPTIONS )
107
- contents = haml.render( Object.new, :contents=>contents, :page=>self, :global=>@bundle.toc, :root=>root )
113
+ html = haml.render( Object.new, :contents=>contents, :page=>self, :global=>@bundle.toc, :root=>root )
114
+
115
+ # Add IDs to elements, only if a toc entry might reference one.
116
+ if @raw && @meta['toc'] && @meta['toc'][',']
117
+ nokodoc( html ).css( AUTO_ID_ELEMENTS ).each do |node|
118
+ next if node.has_attribute?('id')
119
+ node['id'] = DocuBot.id_from_text(node.inner_text)
120
+ end
121
+ html = @nokodoc.at_css('body').children.to_html
122
+ end
108
123
 
109
- @cached_html = contents
124
+ @cached_html = html
110
125
  end
111
126
  def to_html!
112
127
  @cached_html=nil
113
128
  to_html
114
129
  end
130
+ def nokodoc( html=nil )
131
+ @nokodoc ||= Nokogiri::HTML(html || to_html)
132
+ end
133
+ def nokodoc!
134
+ @nokodoc = Nokogiri::HTML(to_html!)
135
+ end
115
136
  end
116
137
 
117
138
  class DocuBot::SubLink
@@ -1,14 +1,21 @@
1
- -# TODO: Breakdown by letter.
2
- %ul#index
3
- - global.index.entries.sort_by{ |k,p| k.downcase }.each do |keyword,pages|
4
- - if pages.length == 1
5
- %li
6
- %a{ :href => pages.first.html_path }= keyword
7
- - else
8
- %li
9
- = keyword
10
- %ul
11
- - pages.each do |page|
12
- %li
13
- %a{ :href => page.html_path }= page.title
1
+ !!! Strict
2
+ %html
3
+ %head
4
+ %meta(http-equiv='Content-Type' content='text/html; charset=utf-8')
5
+ %title= global.title + " Index"
6
+ %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}common.css", :media=>'all'}
7
+ %body
8
+ -# TODO: Breakdown by letter.
9
+ %ul#index
10
+ - global.index.entries.sort_by{ |k,p| k.downcase }.each do |keyword,pages|
11
+ - if pages.length == 1
12
+ %li
13
+ %a{ :href => pages.first.html_path }= keyword
14
+ - else
15
+ %li
16
+ = keyword
17
+ %ul
18
+ - pages.each do |page|
19
+ %li
20
+ %a{ :href => page.html_path }= page.title
14
21
 
@@ -1,7 +1,9 @@
1
1
  !!! Strict
2
2
  %html
3
3
  %head
4
+ %meta(http-equiv='Content-Type' content='text/html; charset=utf-8')
4
5
  %title= global.title
6
+ %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}common.css", :media=>'all'}
5
7
  %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}toc.css", :media=>'all'}
6
8
  %script{:type=>'text/javascript', :src=>"#{root}toc.js"}
7
9
  %body
@@ -8,11 +8,14 @@ class DocuBot::CHMWriter < DocuBot::HTMLWriter
8
8
 
9
9
  def write( destination=nil )
10
10
  super( nil )
11
+ lap = Time.now
11
12
  @chm_path = destination || "#{@bundle.source}.chm"
12
13
  @toc = @bundle.toc
13
14
  write_hhc
14
15
  write_hhk
15
16
  write_hhp
17
+ puts "...%.2fs to write the CHM support files" % ((lap=Time.now)-lap)
18
+
16
19
  # This will fail if a handle is open to it on Windows
17
20
  begin
18
21
  FileUtils.rm( @chm_path ) if File.exists?( @chm_path )
@@ -22,12 +25,13 @@ class DocuBot::CHMWriter < DocuBot::HTMLWriter
22
25
  process.Terminate if process.CommandLine.include? @chm_path.gsub('/','\\')
23
26
  end
24
27
  end
25
- # TODO: output timing and progress results
26
28
  `hhc.exe "#{FileUtils.win_path @hhp}"`.gsub( /[\r\n]+/, "\n" )
29
+ puts "...%.2fs to create the CHM" % ((lap=Time.now)-lap)
27
30
 
28
31
  # Clean out the intermediary files
29
32
  FileUtils.rm( [ @hhc, @hhp, @hhk ] )
30
33
  FileUtils.rm_r( @html_path )
34
+ puts "...%.2fs to clean up temporary files" % ((lap=Time.now)-lap)
31
35
 
32
36
  # Spin a new thread so it doesn't hold up the Ruby process, but sleep long enough for it to get going.
33
37
  Thread.new{ `hh.exe "#{FileUtils.win_path @chm_path}"` }
@@ -3,6 +3,8 @@ class DocuBot::HTMLWriter < DocuBot::Writer
3
3
 
4
4
  # Specify nil for destination to place "<source>_html" next to the source.
5
5
  def write( destination=nil )
6
+ start = Time.now
7
+
6
8
  source = @bundle.source
7
9
  @html_path = destination || File.dirname(source)/"#{File.basename source}_html"
8
10
  FileUtils.rm_rf(@html_path) if File.exists?(@html_path)
@@ -54,6 +56,7 @@ class DocuBot::HTMLWriter < DocuBot::Writer
54
56
  File.open( 'glossary-terms.js', 'w' ){ |f| f << @bundle.glossary.to_js }
55
57
  end
56
58
 
59
+ puts "...%.2fs to write the HTML" % (Time.now - start)
57
60
  end
58
61
  end
59
62
 
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
+ <link href='../common.css' media='all' rel='stylesheet' type='text/css'>
6
+ <title>Ze First Page in Ze Section</title>
7
+ </head>
8
+ <body>
9
+ <div id='content'>
10
+ <div id='pagetop'>
11
+ <div id='breadcrumb'>
12
+ Table of Contents
13
+ <span class='sep'>&gt;</span>
14
+ <a href='../A Slight Change of Heart/index.html'>A Slight Change of Heart</a>
15
+ <span class='sep'>&gt;</span>
16
+ Ze First Page in Ze Section
17
+ </div>
18
+ <h1 id='title'>Ze First Page in Ze Section</h1>
19
+ </div>
20
+ <div id='pagebody'>
21
+ <div id='mainbody'><p>The title of this should be "Ze First Page in Ze Section"</p>
22
+ </div>
23
+ <div id='pagefooter'>
24
+ Copyright ©2010.
25
+ All Rights Reserved.
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </body>
30
+ </html>
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
+ <link href='../common.css' media='all' rel='stylesheet' type='text/css'>
6
+ <title>Another Page in the Section</title>
7
+ </head>
8
+ <body>
9
+ <div id='content'>
10
+ <div id='pagetop'>
11
+ <div id='breadcrumb'>
12
+ Table of Contents
13
+ <span class='sep'>&gt;</span>
14
+ <a href='../A Slight Change of Heart/index.html'>A Slight Change of Heart</a>
15
+ <span class='sep'>&gt;</span>
16
+ Another Page in the Section
17
+ </div>
18
+ <h1 id='title'>Another Page in the Section</h1>
19
+ </div>
20
+ <div id='pagebody'>
21
+ <div id='mainbody'><p>The title of this page should be "Another Page in the Section".</p>
22
+ </div>
23
+ <div id='pagefooter'>
24
+ Copyright ©2010.
25
+ All Rights Reserved.
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </body>
30
+ </html>
@@ -0,0 +1,42 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
+ <link href='../common.css' media='all' rel='stylesheet' type='text/css'>
6
+ <title>Additional Helpful Information</title>
7
+ </head>
8
+ <body>
9
+ <div id='content'>
10
+ <div id='pagetop'>
11
+ <div id='breadcrumb'>
12
+ Table of Contents
13
+ <span class='sep'>&gt;</span>
14
+ <a href='../A Slight Change of Heart/index.html'>A Slight Change of Heart</a>
15
+ <span class='sep'>&gt;</span>
16
+ Additional Helpful Information
17
+ </div>
18
+ <h1 id='title'>Additional Helpful Information</h1>
19
+ <div id='author'>Gavin Kistner</div>
20
+ </div>
21
+ <div id='pagebody'>
22
+ <div id='mainbody'><h2 id='frist-post'>Title Verification</h2>
23
+ <p>The title of this page should be "Additional Helpful Information", not "More Crap".</p>
24
+ <h2 id='moar'>TOC Verification</h2>
25
+ <p>The TOC for this page should have sub-entries for the referenced headings.</p>
26
+
27
+ <ul>
28
+ <li>The links should be named for the headings.</li>
29
+ <li>The links should link to the headings.</li>
30
+ </ul>
31
+ <h2 id='dumb'>Exclusivity</h2>
32
+ <p>The TOC should not, however, have this last heading.</p>
33
+
34
+ </div>
35
+ <div id='pagefooter'>
36
+ Copyright ©2010.
37
+ All Rights Reserved.
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </body>
42
+ </html>
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
+ <link href='../common.css' media='all' rel='stylesheet' type='text/css'>
6
+ <title>Title Verification</title>
7
+ </head>
8
+ <body>
9
+ <div id='content'>
10
+ <div id='pagetop'>
11
+ <div id='breadcrumb'>
12
+ Table of Contents
13
+ <span class='sep'>&gt;</span>
14
+ <a href='../A Slight Change of Heart/index.html'>A Slight Change of Heart</a>
15
+ <span class='sep'>&gt;</span>
16
+ Title Verification
17
+ </div>
18
+ <h1 id='title'>Title Verification</h1>
19
+ </div>
20
+ <div id='pagebody'>
21
+ <div id='mainbody'></div>
22
+ <div id='pagefooter'>
23
+ Copyright ©2010.
24
+ All Rights Reserved.
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </body>
29
+ </html>
@@ -0,0 +1,29 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
+ <link href='../common.css' media='all' rel='stylesheet' type='text/css'>
6
+ <title>TOC Verification</title>
7
+ </head>
8
+ <body>
9
+ <div id='content'>
10
+ <div id='pagetop'>
11
+ <div id='breadcrumb'>
12
+ Table of Contents
13
+ <span class='sep'>&gt;</span>
14
+ <a href='../A Slight Change of Heart/index.html'>A Slight Change of Heart</a>
15
+ <span class='sep'>&gt;</span>
16
+ TOC Verification
17
+ </div>
18
+ <h1 id='title'>TOC Verification</h1>
19
+ </div>
20
+ <div id='pagebody'>
21
+ <div id='mainbody'></div>
22
+ <div id='pagefooter'>
23
+ Copyright ©2010.
24
+ All Rights Reserved.
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </body>
29
+ </html>
@@ -0,0 +1,28 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
5
+ <link href='../common.css' media='all' rel='stylesheet' type='text/css'>
6
+ <title>A Slight Change of Heart</title>
7
+ </head>
8
+ <body>
9
+ <div id='content'>
10
+ <div id='pagetop'>
11
+ <div id='breadcrumb'>
12
+ Table of Contents
13
+ <span class='sep'>&gt;</span>
14
+ A Slight Change of Heart
15
+ </div>
16
+ <h1 id='title'>A Slight Change of Heart</h1>
17
+ </div>
18
+ <div id='pagebody'>
19
+ <div id='mainbody'>
20
+ </div>
21
+ <div id='pagefooter'>
22
+ Copyright ©2010.
23
+ All Rights Reserved.
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </body>
28
+ </html>
@@ -0,0 +1,17 @@
1
+ <ul id='index'>
2
+ <li>
3
+ <a href='headers.html'>Delivery Options</a>
4
+ </li>
5
+ <li>
6
+ <a href='A Slight Change of Heart/3_more_crap.html'>Exclusivity</a>
7
+ </li>
8
+ <li>
9
+ <a href='headers.html'>I like Chicken, I like Liver</a>
10
+ </li>
11
+ <li>
12
+ <a href='A Slight Change of Heart/3_more_crap.html'>Title Verification</a>
13
+ </li>
14
+ <li>
15
+ <a href='A Slight Change of Heart/3_more_crap.html'>TOC Verification</a>
16
+ </li>
17
+ </ul>