docubot 0.0.1 → 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. data/bin/docubot +83 -14
  2. data/lib/docubot.rb +33 -10
  3. data/lib/docubot/bundle.rb +68 -0
  4. data/lib/docubot/converter.rb +13 -9
  5. data/lib/docubot/converters/haml.rb +9 -0
  6. data/lib/docubot/converters/html.rb +5 -0
  7. data/lib/docubot/converters/markdown.rb +12 -4
  8. data/lib/docubot/converters/raw_code.rb +5 -0
  9. data/lib/docubot/converters/textile.rb +10 -0
  10. data/lib/docubot/glossary.rb +44 -0
  11. data/lib/docubot/index.rb +66 -0
  12. data/lib/docubot/page.rb +142 -18
  13. data/lib/docubot/shells/default/0_License.md +60 -0
  14. data/lib/docubot/shells/default/Appendix/Glossary.md +5 -0
  15. data/lib/docubot/shells/default/Appendix/Index_Page.md +8 -0
  16. data/lib/docubot/shells/default/Appendix/Table of Contents.md +5 -0
  17. data/lib/docubot/shells/default/_static/logo.png +0 -0
  18. data/lib/docubot/shells/default/index.txt +3 -0
  19. data/lib/docubot/shells/docubot-help/0_License.md +21 -0
  20. data/lib/docubot/shells/docubot-help/1_Getting_Started.md +48 -0
  21. data/lib/docubot/templates/default/page.haml b/data/lib/docubot/shells/docubot-help/2_Basic_Concepts/0 The → Metasection.md +0 -0
  22. data/lib/docubot/shells/docubot-help/2_Basic_Concepts/1 Interpage Links.md +1 -0
  23. data/lib/docubot/shells/docubot-help/2_Basic_Concepts/2 Generating the Output.md +1 -0
  24. data/lib/docubot/shells/docubot-help/2_Basic_Concepts/3 Customizing Templates.md +1 -0
  25. data/lib/docubot/shells/docubot-help/2_Basic_Concepts/4 Adding Images.md +2 -0
  26. data/lib/docubot/shells/docubot-help/2_Basic_Concepts/index.md +6 -0
  27. data/lib/docubot/shells/docubot-help/3_Advanced_Topics/Controlling Glossary.md +3 -0
  28. data/lib/docubot/shells/docubot-help/3_Advanced_Topics/Controlling Indexing.md +10 -0
  29. data/lib/docubot/shells/docubot-help/3_Advanced_Topics/Controlling the Table of Contents.md +7 -0
  30. data/lib/docubot/shells/docubot-help/3_Advanced_Topics/Switching Page Templates.md +1 -0
  31. data/lib/docubot/shells/docubot-help/4_Appendix/Glossary.md +5 -0
  32. data/lib/docubot/shells/docubot-help/4_Appendix/Index_Page.md +6 -0
  33. data/lib/docubot/shells/docubot-help/4_Appendix/Table of Contents.md +7 -0
  34. data/lib/docubot/shells/docubot-help/_glossary/Template.md +1 -0
  35. data/lib/docubot/shells/docubot-help/_static/glider.png +0 -0
  36. data/lib/docubot/shells/docubot-help/index.txt +8 -0
  37. data/lib/docubot/shells/nvphysx/0_License.md +3 -0
  38. data/lib/docubot/shells/nvphysx/1_Getting_Started.haml +51 -0
  39. data/lib/docubot/shells/nvphysx/Appendix/Glossary.md +7 -0
  40. data/lib/docubot/shells/nvphysx/_glossary/APEX.md +1 -0
  41. data/lib/docubot/shells/nvphysx/_glossary/NVIDIA.md +1 -0
  42. data/lib/docubot/shells/nvphysx/_glossary/PhysX.textile +3 -0
  43. data/lib/docubot/shells/nvphysx/_static/NVBadge_3D.png +0 -0
  44. data/lib/docubot/shells/nvphysx/_static/PhysXbyNV_Black.png +0 -0
  45. data/lib/docubot/shells/nvphysx/_templates/_root/bg_green_bar_revised.gif +0 -0
  46. data/lib/docubot/shells/nvphysx/_templates/_root/close.png +0 -0
  47. data/lib/docubot/shells/nvphysx/_templates/_root/common.css +264 -0
  48. data/lib/docubot/shells/nvphysx/_templates/_root/glossary.css +4 -0
  49. data/lib/docubot/shells/nvphysx/_templates/_root/glossary.js +24 -0
  50. data/lib/docubot/shells/nvphysx/_templates/_root/nvdevtools.js +31 -0
  51. data/lib/docubot/shells/nvphysx/_templates/_root/nvidia-logo.gif +0 -0
  52. data/lib/docubot/shells/nvphysx/_templates/_root/right-sidebar.png +0 -0
  53. data/lib/docubot/shells/nvphysx/_templates/top.haml +28 -0
  54. data/lib/docubot/shells/nvphysx/index.txt +5 -0
  55. data/lib/docubot/snippet.rb +4 -3
  56. data/lib/docubot/snippets/glossary.rb +6 -3
  57. data/lib/docubot/snippets/index_entries.rb +7 -0
  58. data/lib/docubot/templates/_root/common.css +107 -0
  59. data/lib/docubot/templates/_root/toc.css +5 -0
  60. data/lib/docubot/templates/_root/toc.js +4 -0
  61. data/lib/docubot/templates/glossary.haml +5 -0
  62. data/lib/docubot/templates/index.haml +14 -0
  63. data/lib/docubot/templates/page.haml +1 -0
  64. data/lib/docubot/templates/section.haml +10 -0
  65. data/lib/docubot/templates/toc.haml +10 -0
  66. data/lib/docubot/templates/top.haml +25 -0
  67. data/lib/docubot/writer.rb +24 -0
  68. data/lib/docubot/writers/chm.rb +73 -0
  69. data/lib/docubot/writers/chm/hhc.erb +27 -0
  70. data/lib/docubot/writers/chm/hhk.erb +28 -0
  71. data/lib/docubot/writers/chm/hhp.erb +23 -0
  72. data/lib/docubot/writers/html.rb +75 -0
  73. data/test/all.rb +2 -0
  74. data/test/site1/A Slight Change of Heart/3_more_crap.haml +17 -0
  75. data/test/site1/appendices/gkheadftw.html +2 -0
  76. data/test/site1/appendices/index.md +2 -0
  77. data/test/site1/preamble.haml +4 -0
  78. data/test/site1/raw.textile +10 -0
  79. metadata +88 -14
  80. data/lib/docubot/generator.rb +0 -35
  81. data/lib/docubot/section.rb +0 -16
  82. data/lib/docubot/template.rb +0 -13
  83. data/lib/docubot/templates/default/section.haml +0 -0
  84. data/test/site1/A Slight Change of Heart/3_more_crap.md +0 -5
  85. data/test/site1/raw.md +0 -3
@@ -0,0 +1,4 @@
1
+ #glossary-box { display:none; position:absolute; width:30%; background:#e0efcc; border:1px solid #82a851; padding:0.5em 0.9em; font-size:9pt; font-family:Calibri, Tahoma; }
2
+ #glossary-close { width:24px; height:24px; background:url(close.png) no-repeat; position:absolute; right:-12px; top:-12px; cursor:pointer; }
3
+ #glossary-box * { margin:0 }
4
+ span.glossary { color:#36401C; border-bottom:1px dashed #6e8e34; cursor:help; }
@@ -0,0 +1,24 @@
1
+ function glossaryClick(evt){
2
+ if (!evt) evt=event;
3
+ var target = evt.target || evt.srcElement;
4
+ var term = target.getAttribute('term') || target.innerHTML;
5
+ var box = document.getElementById('glossary-box');
6
+ box.style.display = 'block';
7
+ var scroll = (document.documentElement.scrollTop || document.body.scrollTop )*1;
8
+ box.style.left = (evt.clientX+5) + 'px';
9
+ box.style.top = (evt.clientY+5) + scroll + 'px';
10
+
11
+ var html = $glossaryTerms[term.toLowerCase()];
12
+ document.getElementById('glossary-defn').innerHTML = html;
13
+ }
14
+
15
+ handleEvent(window,'load',function(){
16
+ for ( var spans=document.getElementsByTagName('span'),i=spans.length-1; i>=0; --i ){
17
+ if (cssClass.has(spans[i],'glossary')) handleEvent(spans[i],'click',glossaryClick);
18
+ }
19
+ var box = document.getElementById('glossary-box');
20
+ var close = document.getElementById('glossary-close');
21
+ handleEvent( close, 'click', function(){
22
+ box.style.display = 'none';
23
+ });
24
+ });
@@ -0,0 +1,31 @@
1
+ function handleEvent(obj,eventName,callback,useCapture){
2
+ return obj.addEventListener ? obj.addEventListener(eventName,callback,useCapture||false) : obj.attachEvent("on"+eventName,callback);
3
+ }
4
+
5
+ cssClass = {
6
+ _killCache : {},
7
+ _findCache : {},
8
+ add : function cssClassAdd(obj,className){
9
+ this.kill(obj,className);
10
+ obj.className+=(obj.className.length?' ':'')+className;
11
+ },
12
+ kill : function cssClassKill(obj,className){
13
+ var re = this._killCache[className] || (this._killCache[className]=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)','g') );
14
+ obj.className = obj.className.replace(re,'');
15
+ },
16
+ has : function cssClassHas(obj,className){
17
+ var re = this._findCache[className] || (this._findCache[className]=new RegExp('(?:^|\\s+)'+className+'(?:\\s+|$)') );
18
+ return re.test( obj.className );
19
+ }
20
+ };
21
+ function isFirstChild(node){
22
+ return node.parentNode.firstChild==node;
23
+ }
24
+ handleEvent(window,'load',function(){
25
+ // Add first-child CSS class since :first-child pseudo-class doesn't work for old IE
26
+ for ( var tags=['h2','h3','p','ul','dl','ol'],i=tags.length-1; i>=0; --i ){
27
+ for ( var all=document.getElementsByTagName(tags[i]),j=all.length-1; j>=0; --j ){
28
+ if (isFirstChild(all[j])) cssClass.add(all[j],'first-child');
29
+ }
30
+ }
31
+ });
@@ -0,0 +1,28 @@
1
+ !!! Strict
2
+ %html
3
+ %head
4
+ %meta(http-equiv='Content-Type' content='text/html; charset=utf-8')
5
+ %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}common.css", :media=>'all'}
6
+ %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}glossary.css", :media=>'all'}
7
+ %script{:type=>'text/javascript', :src=>"#{root}nvdevtools.js"}
8
+ %script{:type=>'text/javascript', :src=>"#{root}glossary-terms.js"}
9
+ %script{:type=>'text/javascript', :src=>"#{root}glossary.js"}
10
+ %title= page.title
11
+ %body{ :class=>page.style }
12
+ #pagetop
13
+ #breadcrumb
14
+ - toc = page.ancestors.first # The TOC has no page to link to
15
+ = toc.short_title || toc.title
16
+ %span.sep >
17
+ - page.ancestors[1..-1].each do |dad|
18
+ %a{ :href=>root/dad.html_path }= dad.short_title || dad.title
19
+ %span.sep >
20
+ = page.title
21
+ %h1#title= page.title
22
+ #pagebody
23
+ #glossary-box
24
+ #glossary-close
25
+ #glossary-defn
26
+ #mainbody= contents
27
+ #pagefooter
28
+ Copyright ©#{Time.now.year}#{ " #{global.company}" if global.company? }.
@@ -0,0 +1,5 @@
1
+ company : NVIDIA Corporation
2
+ title : NVIDIA Reference Manual
3
+ short_title: NVIDIA Reference
4
+ default : Getting Started
5
+ +++
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module DocuBot
2
3
  @snippets = {}
3
4
 
@@ -5,11 +6,11 @@ module DocuBot
5
6
  @snippets[ regexp ] = handler
6
7
  end
7
8
 
8
- def self.process_snippets( html )
9
- @snippets.inject(html){ |html,regexp,handler| html.gsub( regexp, &handler ) }
9
+ def self.process_snippets( page, html )
10
+ @snippets.inject(html){ |h,(regexp,handler)| h.gsub( regexp ){ |str| handler[ str, page ] } }
10
11
  end
11
12
 
12
- Dir[ File.join( DocuBot::DIR, 'docubot/snippets/*.rb' ) ].each do |snippet|
13
+ Dir[ DocuBot::DIR/'docubot/snippets/*.rb' ].each do |snippet|
13
14
  require snippet
14
15
  end
15
16
 
@@ -1,4 +1,7 @@
1
- DocuBot.handle_snippet /\$\$(\w[\w ]*\w)\$\$/ do
2
- # TODO: look up glossary terms
3
- "<span class='glossary'>#{$1}</span>"
1
+ # encoding: UTF-8
2
+ pattern = /\$\$(\w[\w: ]*\w)\$\$/
3
+ DocuBot.handle_snippet pattern do |match, page|
4
+ parts = match[ 2..-3 ].split(':',2)
5
+ text, term = parts.first, parts.last
6
+ "<span class='glossary' term='#{term}'>#{text}</span>"
4
7
  end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+ pattern = /@@(\w[\w ]*?)@@/
3
+ DocuBot.handle_snippet pattern do |match, page|
4
+ keyword = match[ 2..-3 ]
5
+ page.bundle.index.add( keyword, page )
6
+ keyword
7
+ end
@@ -0,0 +1,107 @@
1
+ html, body
2
+ {
3
+ margin:0;
4
+ padding:0;
5
+ background:white;
6
+ }
7
+
8
+ #breadcrumb
9
+ {
10
+ margin:0;
11
+ background:black;
12
+ padding-left:1em;
13
+ font-family: 'Arial', sans-serif;
14
+ font-size:14px; font-weight:bold;
15
+ white-space:nowrap;
16
+ height:40px; line-height:40px; color:white; overflow:hidden;
17
+ color:#fff;
18
+ }
19
+
20
+ #breadcrumb a
21
+ {
22
+ color:#fff; text-decoration:none
23
+ }
24
+
25
+ #breadcrumb a:hover
26
+ {
27
+ color:#74b71b
28
+ }
29
+ #breadcrumb .sep
30
+ {
31
+ color:#999; font-weight:normal; padding:0 0.2em
32
+ }
33
+
34
+ div#mainbody
35
+ {
36
+ padding-right:0 ! important; padding-bottom:2em;
37
+ }
38
+
39
+ div.section
40
+ {
41
+ margin-left:2em
42
+ }
43
+
44
+ a:link, a:visited { white-space:nowrap; color:#6e8e34 }
45
+ a:hover { color:#74b71b }
46
+
47
+ h1 {
48
+ margin:0;
49
+ padding-left:14px;
50
+ padding-right:50px;
51
+ font-family: 'Arial', sans-serif;
52
+ white-space:nowrap;
53
+ font-size:18px;
54
+ background:#6eb103 url(images/bg_green_bar_revised.gif) repeat-x;
55
+ height:30px; line-height:30px; color:white; overflow:hidden;
56
+ border-bottom:1px solid #999
57
+ }
58
+
59
+ h2
60
+ {
61
+ clear:both;
62
+ margin-top:4em;
63
+ }
64
+ h2, h3, h4
65
+ {
66
+ border-bottom:1px solid #dddddd;
67
+ font-size:100%
68
+ }
69
+ h2.first-child, h3.first-child, h4.first-child
70
+ {
71
+ margin-top:0
72
+ }
73
+ h3, h4
74
+ {
75
+ margin-top:2em;
76
+ font-style:italic
77
+ }
78
+
79
+ .moreinfo
80
+ {
81
+ font-style:italic;
82
+ color:#666;
83
+ }
84
+
85
+ .moreinfo a
86
+ {
87
+ color: #6e8e34
88
+ }
89
+ .moreinfo a:hover
90
+ {
91
+ color: #76b900
92
+ }
93
+
94
+ sup
95
+ {
96
+ font-size:85%
97
+ }
98
+ #pagebody { margin:1em 2em }
99
+ #pagebody h1 {
100
+ background:#666; color:#ccc; border:1px solid #333; font-size:100%; padding:0.2em 1em; line-height:1em ! important;
101
+ height:auto ! important; margin-top:1.5em
102
+ }
103
+
104
+ div#pagefooter {
105
+ margin-top:10em ! important; margin-bottom:1em ! important; width:25em; overflow:hidden; white-space:nowrap;
106
+ background:#eee; border:1px solid #ccc; border-left:none; color:#999; font-size:7pt ! important; padding:0.1em 1em
107
+ }
@@ -0,0 +1,5 @@
1
+ /*
2
+ This file is only used for the HTML version of the TOC.
3
+ If you are generating CHMs only, you may delete it.
4
+ */
5
+
@@ -0,0 +1,4 @@
1
+ /*
2
+ This file is only used for the HTML version of the TOC.
3
+ If you are generating CHMs only, you may delete it.
4
+ */
@@ -0,0 +1,5 @@
1
+ -# TODO: Breakdown by letter.
2
+ %dl#glossary
3
+ - global.glossary.each do |term,defn|
4
+ %dt= term
5
+ %dd= defn
@@ -0,0 +1,14 @@
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
14
+
@@ -0,0 +1 @@
1
+ = contents
@@ -0,0 +1,10 @@
1
+ %p The following pages are part of <em>#{page.title}</em>:
2
+ %ul#children
3
+ - page.pages.each do |child_page|
4
+ %li #{child_page.title}#{": #{child_page.summary}" if child_page.summary?}
5
+ - if contents
6
+ %p
7
+ %strong
8
+ Before you go in, you should probably know the following:
9
+ #good-info= contents
10
+
@@ -0,0 +1,10 @@
1
+ !!! Strict
2
+ %html
3
+ %head
4
+ %title= global.title
5
+ %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}toc.css", :media=>'all'}
6
+ %script{:type=>'text/javascript', :src=>"#{root}toc.js"}
7
+ %body
8
+ %ul#toc
9
+ - li_pages_for global
10
+
@@ -0,0 +1,25 @@
1
+ !!! Strict
2
+ %html
3
+ %head
4
+ %meta(http-equiv='Content-Type' content='text/html; charset=utf-8')
5
+ %link{:rel=>'stylesheet', :type=>'text/css', :href=>"#{root}common.css", :media=>'all'}
6
+ %title= page.title
7
+ %body{ :class=>page.style }
8
+ #content
9
+ #pagetop
10
+ #breadcrumb
11
+ - toc = page.ancestors.first # The TOC has no page to link to
12
+ = toc.short_title || toc.title
13
+ %span.sep &gt;
14
+ - page.ancestors[1..-1].each do |dad|
15
+ %a{ :href=>root/dad.html_path }= dad.short_title || dad.title
16
+ %span.sep &gt;
17
+ = page.title
18
+ %h1#title= page.title
19
+ - if page.author?
20
+ #author= page.author
21
+ #pagebody
22
+ #mainbody= contents
23
+ #pagefooter
24
+ Copyright ©#{Time.now.year}#{ " #{global.company}" if global.company? }.
25
+ All Rights Reserved.
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ class DocuBot::Writer
3
+ HAML_OPTIONS = { :format=>:html4, :ugly=>true }
4
+ HAML_OPTIONS.merge!( :encoding=>'utf-8' ) if Object.const_defined? "Encoding"
5
+
6
+ @@by_type = {}
7
+ def self.handles_type( type )
8
+ @@by_type[type.to_s.downcase] = self
9
+ end
10
+ def self.by_type
11
+ @@by_type
12
+ end
13
+ DIR = File.expand_path( DocuBot::DIR / 'docubot/writers' )
14
+
15
+ def initialize( bundle )
16
+ @bundle = bundle
17
+ end
18
+ end
19
+
20
+ Dir[ DocuBot::Writer::DIR/'*.rb' ].each do |writer|
21
+ require writer
22
+ end
23
+
24
+ DocuBot::Writer::INSTALLED_WRITERS = DocuBot::Writer.by_type.keys
@@ -0,0 +1,73 @@
1
+ require DocuBot::Writer::DIR / 'html'
2
+ require 'cgi'
3
+ require 'erb'
4
+ class DocuBot::CHMWriter < DocuBot::HTMLWriter
5
+ handles_type :chm
6
+
7
+ SUPPORT = DocuBot::Writer::DIR / 'chm'
8
+
9
+ def write( destination=nil )
10
+ super( nil )
11
+ @chm_path = destination || "#{@bundle.source}.chm"
12
+ @toc = @bundle.toc
13
+ write_hhc
14
+ write_hhk
15
+ write_hhp
16
+ # This will fail if a handle is open to it on Windows
17
+ begin
18
+ FileUtils.rm( @chm_path ) if File.exists?( @chm_path )
19
+ rescue Errno::EACCES
20
+ require 'win32ole'
21
+ for process in WIN32OLE.connect("winmgmts://").ExecQuery("select Name,CommandLine from win32_process where Name='hh.exe'") do
22
+ process.Terminate if process.CommandLine.include? @chm_path.gsub('/','\\')
23
+ end
24
+ end
25
+ # TODO: output timing and progress results
26
+ `hhc.exe "#{FileUtils.win_path @hhp}"`.gsub( /[\r\n]+/, "\n" )
27
+
28
+ # Clean out the intermediary files
29
+ FileUtils.rm( [ @hhc, @hhp, @hhk ] )
30
+ FileUtils.rm_r( @html_path )
31
+
32
+ # Spin a new thread so it doesn't hold up the Ruby process, but sleep long enough for it to get going.
33
+ Thread.new{ `hh.exe "#{FileUtils.win_path @chm_path}"` }
34
+ sleep 0.1
35
+ end
36
+
37
+ def write_hhc
38
+ @hhc = @chm_path.sub( /[^.]+$/, 'hhc' )
39
+ File.open( @hhc, 'w' ) do |f|
40
+ f << ERB.new( IO.read( SUPPORT / 'hhc.erb' ) ).result( binding )
41
+ end
42
+ end
43
+
44
+ def write_hhp
45
+ @hhp = @chm_path.sub( /[^.]+$/, 'hhp' )
46
+
47
+ if @toc.default?
48
+ # User tried to specify the default page
49
+ @default_topic = @toc.descendants.find{ |page| page.title==@toc.default }
50
+ if @default_topic
51
+ if @default_topic.file =~ /\s/
52
+ warn "'#{@toc.default}' cannot be the default CHM page; it has a space in the file name."
53
+ @default_topic = nil
54
+ end
55
+ else
56
+ warn "The requested default page '#{@toc.default}' could not be found. (Did the title change?)"
57
+ end
58
+ end
59
+ @default_topic ||= @toc.descendants.find{ |page| page.file =~ /^\S+$/ }
60
+ warn "No default page is set, because no page has a file name without spaces." unless @default_topic
61
+
62
+ File.open( @hhp, 'w' ) do |f|
63
+ f << ERB.new( IO.read( SUPPORT / 'hhp.erb' ) ).result( binding )
64
+ end
65
+ end
66
+
67
+ def write_hhk
68
+ @hhk = @chm_path.sub( /[^.]+$/, 'hhk' )
69
+ File.open( @hhk, 'w' ) do |f|
70
+ f << ERB.new( IO.read( SUPPORT / 'hhk.erb' ) ).result( binding )
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,27 @@
1
+ <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
2
+ <HTML>
3
+ <HEAD>
4
+ <meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
5
+ <!-- Sitemap 1.0 -->
6
+ <%@write_section = lambda do |page| %>
7
+ <UL>
8
+ <%page.pages.each do |child|%>
9
+ <%next if child.hide%>
10
+ <LI> <OBJECT type="text/sitemap">
11
+ <param name="Name" value="<%=CGI.escapeHTML child.title%>">
12
+ <param name="Local" value="<%=FileUtils.win_path( @html_path / child.html_path ).gsub('&','%26')%>">
13
+ <%if child.sublink?
14
+ %><param name="ImageNumber" value="17"><%
15
+ elsif child.leaf?
16
+ %><param name="ImageNumber" value="11"><%
17
+ end%>
18
+ </OBJECT>
19
+ <%@write_section[child] unless child.pages.empty?%>
20
+ <%end%>
21
+ </UL>
22
+ <%end%>
23
+ </HEAD><BODY>
24
+
25
+ <%@write_section[@bundle.toc]%>
26
+
27
+ </BODY></HTML>