docubot 0.3 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/docubot +0 -0
- data/lib/docubot/bundle.rb +75 -11
- data/lib/docubot/glossary.rb +19 -14
- data/lib/docubot/page.rb +114 -56
- data/lib/docubot/shells/nvphysx/0_License.md +3 -0
- data/lib/docubot/shells/nvphysx/1_Getting_Started.haml +51 -0
- data/lib/docubot/shells/nvphysx/Appendix/Glossary.md +7 -0
- data/lib/docubot/shells/nvphysx/_glossary/APEX.md +1 -0
- data/lib/docubot/shells/nvphysx/_glossary/NVIDIA.md +1 -0
- data/lib/docubot/shells/nvphysx/_glossary/PhysX.textile +3 -0
- data/lib/docubot/shells/nvphysx/_static/NVBadge_3D.png +0 -0
- data/lib/docubot/shells/nvphysx/_static/PhysXbyNV_Black.png +0 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/bg_green_bar_revised.gif +0 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/close.png +0 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/common.css +264 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/glossary.css +4 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/glossary.js +24 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/nvdevtools.js +31 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/nvidia-logo.gif +0 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/right-sidebar.png +0 -0
- data/lib/docubot/shells/nvphysx/_templates/top.haml +28 -0
- data/lib/docubot/shells/nvphysx/index.txt +5 -0
- data/lib/docubot/snippet.rb +1 -0
- data/lib/docubot/snippets/glossary.rb +1 -0
- data/lib/docubot/templates/_root/glossary.css +4 -0
- data/lib/docubot/templates/_root/glossary.js +58 -0
- data/lib/docubot/templates/glossary.haml +3 -2
- data/lib/docubot/templates/top.haml +4 -0
- data/lib/docubot/writers/chm.rb +6 -3
- data/lib/docubot/writers/html.rb +1 -1
- data/spec/_all.rb +12 -0
- data/spec/_helper.rb +6 -0
- data/spec/bundle.rb +142 -0
- data/spec/command.rb +3 -0
- data/spec/converters.rb +2 -0
- data/spec/glossary.rb +93 -0
- data/spec/index.rb +2 -0
- data/spec/page.rb +24 -0
- data/spec/samples/glossary/Glossary.txt +5 -0
- data/spec/samples/glossary/Some Page.md +3 -0
- data/spec/samples/glossary/_glossary/Simple Term.md +3 -0
- data/spec/samples/glossary/_glossary/complex.haml +8 -0
- data/spec/samples/glossary/_glossary/project_x.md +4 -0
- data/spec/samples/link_test/index.txt +11 -0
- data/spec/samples/link_test/root.md +14 -0
- data/spec/samples/link_test/sub1/inner1.md +11 -0
- data/spec/samples/link_test/sub2.md +3 -0
- data/{test/site1_html/toc.css → spec/samples/link_test/sub2/bozo.bin} +0 -0
- data/spec/samples/link_test/sub2/inner2.md +7 -0
- data/spec/samples/simplest/HTML.html +10 -0
- data/spec/samples/simplest/Haml.haml +13 -0
- data/spec/samples/simplest/Markdown.md +10 -0
- data/spec/samples/simplest/Text.txt +10 -0
- data/spec/samples/simplest/Textile.textile +10 -0
- data/test/site1_html/toc.js b/data/spec/samples/titletest/1 First → One.txt +0 -0
- data/spec/samples/titletest/2_Second_One.txt +0 -0
- data/spec/samples/titletest/3_renamed.txt +2 -0
- data/spec/samples/titletest/4 Fourth_One.txt b/data/spec/samples/titletest/4 → Fourth_One.txt +0 -0
- data/spec/samples/titletest/5_Fifth One.txt b/data/spec/samples/titletest/5_Fifth → One.txt +0 -0
- data/spec/samples/titletest/index.txt +2 -0
- data/spec/templates.rb +2 -0
- data/spec/toc.rb +73 -0
- data/spec/writer/chm.rb +2 -0
- data/spec/writer/html.rb +2 -0
- metadata +74 -35
- data/test/all.rb +0 -8
- data/test/site1/A Slight Change of Heart/1 Ze First Page in Ze Section.md +0 -1
- data/test/site1/A Slight Change of Heart/2 Another Page in the Section.md +0 -1
- data/test/site1/A Slight Change of Heart/3_more_crap.haml +0 -17
- data/test/site1/appendices/gkheadftw.html +0 -2
- data/test/site1/appendices/index.md +0 -2
- data/test/site1/headers.md +0 -10
- data/test/site1/preamble.haml +0 -4
- data/test/site1/raw.textile +0 -10
- data/test/site1_html/A Slight Change of Heart/1 Ze First Page in Ze Section.html +0 -30
- data/test/site1_html/A Slight Change of Heart/2 Another Page in the Section.html +0 -30
- data/test/site1_html/A Slight Change of Heart/3_more_crap.html +0 -42
- data/test/site1_html/A Slight Change of Heart/3_more_crap.html#frist-post +0 -29
- data/test/site1_html/A Slight Change of Heart/3_more_crap.html#moar +0 -29
- data/test/site1_html/A Slight Change of Heart/index.html +0 -28
- data/test/site1_html/_index.html +0 -17
- data/test/site1_html/_toc.html +0 -73
- data/test/site1_html/appendices/gkheadftw.html +0 -32
- data/test/site1_html/appendices/index.html +0 -28
- data/test/site1_html/common.css +0 -108
- data/test/site1_html/glossary-terms.js +0 -1
- data/test/site1_html/headers.html +0 -42
- data/test/site1_html/preamble.html +0 -36
- data/test/site1_html/raw.html +0 -33
data/bin/docubot
CHANGED
File without changes
|
data/lib/docubot/bundle.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
+
require 'pathname'
|
2
3
|
class DocuBot::Bundle
|
3
4
|
attr_reader :toc, :extras, :glossary, :index, :source
|
4
|
-
|
5
|
+
attr_reader :internal_links, :external_links, :file_links, :broken_links
|
5
6
|
def initialize( source_directory )
|
6
7
|
@source = File.expand_path( source_directory )
|
7
8
|
raise "DocuBot cannot find directory #{@source}. Exiting." unless File.exists?( @source )
|
@@ -9,8 +10,7 @@ class DocuBot::Bundle
|
|
9
10
|
@glossary = DocuBot::Glossary.new( self, @source/'_glossary' )
|
10
11
|
@index = DocuBot::Index.new( self )
|
11
12
|
Dir.chdir( @source ) do
|
12
|
-
@toc = DocuBot::Page.new( ".", "Table of Contents" )
|
13
|
-
@toc.bundle = self
|
13
|
+
@toc = DocuBot::Page.new( self, ".", "Table of Contents" )
|
14
14
|
@toc.meta['glossary'] = @glossary
|
15
15
|
@toc.meta['index'] = @index
|
16
16
|
pages_by_path = { '.'=>@toc }
|
@@ -23,12 +23,11 @@ class DocuBot::Bundle
|
|
23
23
|
item_is_page = File.directory?(item) || DocuBot::Converter.by_type[extension]
|
24
24
|
if item_is_page
|
25
25
|
parent = pages_by_path[ File.dirname( item ) ]
|
26
|
-
page = DocuBot::Page.new( item )
|
27
|
-
page.bundle = self
|
26
|
+
page = DocuBot::Page.new( self, item )
|
28
27
|
pages_by_path[ item ] = page
|
29
28
|
parent << page if parent
|
30
29
|
if item =~ /\b_glossary\b/
|
31
|
-
@glossary << page
|
30
|
+
@glossary << page
|
32
31
|
end
|
33
32
|
@index.process_page( page )
|
34
33
|
|
@@ -56,15 +55,80 @@ class DocuBot::Bundle
|
|
56
55
|
end
|
57
56
|
end
|
58
57
|
end
|
58
|
+
|
59
|
+
# Regenerate pages whose templates require full scaning to have completed
|
60
|
+
# TODO: make this based off of a metasection attribute.
|
61
|
+
@toc.every_page.select do |page|
|
62
|
+
%w[ glossary ].include?( page.template )
|
63
|
+
end.each do |page|
|
64
|
+
page.dirty_template
|
65
|
+
end
|
66
|
+
|
67
|
+
# TODO: make this optional via global variable
|
68
|
+
validate_links
|
69
|
+
@broken_links.each do |page,links|
|
70
|
+
links.each do |link|
|
71
|
+
warn "Broken link on #{page.file}: '#{link}'"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# TODO: make this optional via global variable
|
76
|
+
@glossary.missing_terms.each do |term,referrers|
|
77
|
+
warn "Glossary term '#{term}' never defined."
|
78
|
+
referrers.each do |referring_page|
|
79
|
+
warn "...seen on #{referring_page.file}."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
59
83
|
end
|
60
|
-
|
61
|
-
def
|
84
|
+
|
85
|
+
def validate_links
|
86
|
+
@external_links = Hash.new{ |h,k| h[k]=[] }
|
87
|
+
@internal_links = Hash.new{ |h,k| h[k]=[] }
|
88
|
+
@file_links = Hash.new{ |h,k| h[k]=[] }
|
89
|
+
@broken_links = Hash.new{ |h,k| h[k]=[] }
|
90
|
+
|
91
|
+
page_by_html_path = {}
|
92
|
+
page_by_orig_path = {}
|
93
|
+
@toc.every_page.each do |page|
|
94
|
+
page_by_html_path[page.html_path] = page
|
95
|
+
page_by_orig_path[page.file] = page if page.file
|
96
|
+
end
|
97
|
+
|
98
|
+
Dir.chdir( @source ) do
|
99
|
+
@toc.every_page.each do |page|
|
100
|
+
next unless page.nokodoc # Sub-links don't have documents
|
101
|
+
page.nokodoc.xpath('//a/@href').each do |href|
|
102
|
+
href=href.content
|
103
|
+
if href=~%r{^[a-z]+://}i
|
104
|
+
@external_links[page] << href
|
105
|
+
else
|
106
|
+
id = href[/(#[a-z][\w.:-]*)/i,1]
|
107
|
+
file = href.sub(/#.+/,'')
|
108
|
+
path = file.empty? ? page.html_path : Pathname.new( File.dirname(page.html_path) / file ).cleanpath.to_s
|
109
|
+
if target=page_by_html_path[path]
|
110
|
+
if !id || target.nokodoc.at_css(id)
|
111
|
+
@internal_links[page] << href
|
112
|
+
else
|
113
|
+
@broken_links[page] << href
|
114
|
+
end
|
115
|
+
else
|
116
|
+
if File.file?(path) && !page_by_orig_path[path]
|
117
|
+
@file_links[page] << href
|
118
|
+
else
|
119
|
+
@broken_links[page] << href
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def write( writer_type, destination=nil )
|
62
129
|
writer = DocuBot::Writer.by_type[ writer_type.to_s.downcase ]
|
63
130
|
if writer
|
64
131
|
writer.new( self ).write( destination )
|
65
|
-
unless @glossary.missing_terms.empty?
|
66
|
-
warn "The following glossary terms were never defined:\n#{@glossary.missing_terms.map{|t|t.inspect}.join(', ')}"
|
67
|
-
end
|
68
132
|
else
|
69
133
|
raise "Unknown writer '#{writer_type}'; available types: #{DocuBot::Writer::INSTALLED_WRITERS.join ', '}"
|
70
134
|
end
|
data/lib/docubot/glossary.rb
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
class DocuBot::Glossary
|
3
|
-
attr_accessor :bundle
|
3
|
+
attr_accessor :bundle, :entries
|
4
4
|
def initialize( bundle, dir )
|
5
5
|
@entries = {}
|
6
6
|
@downcased = {}
|
7
7
|
@bundle = bundle
|
8
|
-
@missing = []
|
8
|
+
@missing = Hash.new{ |h,k| h[k]=[] }
|
9
9
|
# .directory? also ensures that the path exists
|
10
10
|
if File.directory?( dir )
|
11
11
|
@directory = File.expand_path( dir )
|
12
12
|
# Dir[ dir/'*' ].each do |item|
|
13
|
-
# page = DocuBot::Page.new( item )
|
14
|
-
# page.bundle = @bundle
|
13
|
+
# page = DocuBot::Page.new( @bundle, item )
|
15
14
|
# self << page
|
16
15
|
# end
|
17
16
|
end
|
@@ -19,26 +18,32 @@ class DocuBot::Glossary
|
|
19
18
|
def []=( term, definition )
|
20
19
|
@entries[ term ] = definition
|
21
20
|
@downcased[ term.downcase ] = term
|
21
|
+
@missing.delete( term.downcase )
|
22
22
|
end
|
23
23
|
def []( term )
|
24
24
|
@entries[ @downcased[ term.downcase ] ]
|
25
25
|
end
|
26
|
-
def
|
27
|
-
|
26
|
+
def term_used( term, referring_page )
|
27
|
+
down = term.downcase
|
28
|
+
unless @downcased[down]
|
29
|
+
@missing[down] << referring_page
|
30
|
+
@missing[down].uniq!
|
31
|
+
end
|
28
32
|
end
|
29
|
-
def
|
30
|
-
|
31
|
-
# File.open( @directory/"#{term}.md", "w" ){ |f| f << "<span class='todo'>TODO: define #{term}</span>" } if @directory
|
33
|
+
def each
|
34
|
+
@entries.each{ |term,page| yield term, page }
|
32
35
|
end
|
33
36
|
def missing_terms
|
34
|
-
|
35
|
-
@missing.reject{ |term| self[term] }.uniq
|
37
|
+
@missing
|
36
38
|
end
|
37
39
|
def <<( page )
|
38
|
-
|
39
|
-
self[ page.title ] = page.to_html
|
40
|
+
self[ page.title ] = page
|
40
41
|
end
|
41
42
|
def to_js
|
42
|
-
"$glossaryTerms = {#{
|
43
|
+
"$glossaryTerms = {#{
|
44
|
+
@entries.reject{ |term,page| page.hide }.map do |term,page|
|
45
|
+
"'#{term.downcase.gsub("'","\\\\'")}':'#{page.to_html.gsub("'","\\\\'").gsub(/[\r\n]/,'\\n')}'"
|
46
|
+
end.join(",\n")
|
47
|
+
}};"
|
43
48
|
end
|
44
49
|
end
|
data/lib/docubot/page.rb
CHANGED
@@ -6,40 +6,96 @@ class DocuBot::Page
|
|
6
6
|
META_SEPARATOR = /^\+\+\+\s*$/ # Sort of like +++ATH0
|
7
7
|
AUTO_ID_ELEMENTS = %w[ h1 h2 h3 h4 h5 h6 legend caption dt ].join(',')
|
8
8
|
|
9
|
-
attr_reader :pages, :type, :folder, :file, :meta
|
10
|
-
attr_accessor :parent
|
9
|
+
attr_reader :pages, :type, :folder, :file, :meta, :nokodoc, :bundle
|
10
|
+
attr_accessor :parent
|
11
11
|
|
12
|
-
def initialize( source_path, title=nil
|
12
|
+
def initialize( bundle, source_path, title=nil )
|
13
13
|
puts "#{self.class}.new( #{source_path.inspect}, #{title.inspect}, #{type.inspect} )" if $DEBUG
|
14
14
|
title ||= File.basename( source_path ).sub( /\.[^.]+$/, '' ).gsub( '_', ' ' ).sub( /^\d+\s/, '' )
|
15
|
+
@bundle = bundle
|
15
16
|
@meta = { 'title'=>title }
|
16
17
|
@pages = []
|
17
18
|
@file = source_path
|
18
19
|
if File.directory?( @file )
|
19
20
|
@folder = @file
|
20
|
-
# WILL SET @file TO NIL FOR DIRECTORIES WITHOUT AN INDEX.* FILE
|
21
21
|
@file = Dir[ source_path/'index.*' ][0]
|
22
|
+
# Directories without an index.* file now have nil @file
|
22
23
|
else
|
23
24
|
@folder = File.dirname( @file )
|
24
25
|
end
|
26
|
+
slurp_file_contents if @file
|
27
|
+
create_nokodoc
|
28
|
+
end
|
29
|
+
|
30
|
+
def slurp_file_contents
|
31
|
+
@type = File.extname( @file )[ 1..-1 ]
|
32
|
+
parts = IO.read( @file ).split( META_SEPARATOR, 2 )
|
33
|
+
|
34
|
+
if parts.length > 1
|
35
|
+
# Make YAML friendler to n00bs
|
36
|
+
yaml = YAML.load( parts.first.gsub( /^\t/, ' ' ) )
|
37
|
+
@meta.merge!( yaml )
|
38
|
+
end
|
39
|
+
|
40
|
+
# Raw markup, untransformed, needs content
|
41
|
+
if @raw = parts.last && parts.last.strip
|
42
|
+
@raw = nil if @raw.empty?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_nokodoc
|
47
|
+
# Directories with no index.* file will not have any @raw
|
48
|
+
# Pages with metasection only will also not have any @raw
|
49
|
+
html = if @raw && !@raw.empty?
|
50
|
+
html = DocuBot::process_snippets( self, @raw )
|
51
|
+
html = DocuBot::convert_to_html( self, html, @type )
|
52
|
+
end
|
53
|
+
@nokodoc = Nokogiri::HTML(html || "")
|
54
|
+
auto_id
|
55
|
+
auto_section
|
56
|
+
@nokodoc
|
57
|
+
end
|
58
|
+
|
59
|
+
def nokodoc
|
60
|
+
@nokodoc ||= create_nokodoc
|
61
|
+
end
|
25
62
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
yaml = YAML.load( parts.first.gsub( /^\t/, ' ' ) )
|
34
|
-
@meta.merge!( yaml )
|
63
|
+
# Add IDs to elements that don't have them
|
64
|
+
def auto_id
|
65
|
+
# ...but only if a toc entry might reference one, or requested.
|
66
|
+
if (@meta['auto-id']==true) || (@meta['toc'] && @meta['toc'][','])
|
67
|
+
@nokodoc.css( AUTO_ID_ELEMENTS ).each do |node|
|
68
|
+
next if node.has_attribute?('id')
|
69
|
+
node['id'] = DocuBot.id_from_text(node.inner_text)
|
35
70
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
71
|
+
dirty_doc
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Wrap siblings of headers in <div class='section'>
|
76
|
+
def auto_section
|
77
|
+
return if @meta['auto-section']==false
|
78
|
+
return unless body = @nokodoc.at_css('body')
|
79
|
+
|
80
|
+
#TODO: Make this a generic nokogiri call on any node (like body) where you can pass in a hierarchy of elements and a wrapper
|
81
|
+
stack = []
|
82
|
+
body.children.each do |node|
|
83
|
+
# non-matching nodes will get level of 0
|
84
|
+
level = node.name[ /h([1-6])/i, 1 ].to_i
|
85
|
+
level = 99 if level == 0
|
86
|
+
|
87
|
+
stack.pop while (top=stack.last) && top[:level]>=level
|
88
|
+
stack.last[:div].add_child( node ) if stack.last
|
89
|
+
if level<99
|
90
|
+
div = Nokogiri::XML::Node.new('div',@nokodoc)
|
91
|
+
div.set_attribute( 'class', 'section' )
|
92
|
+
node.add_next_sibling(div)
|
93
|
+
stack << { :div=>div, :level=>level }
|
40
94
|
end
|
41
95
|
end
|
96
|
+
dirty_doc
|
42
97
|
end
|
98
|
+
|
43
99
|
def []( key )
|
44
100
|
@meta[key]
|
45
101
|
end
|
@@ -48,7 +104,6 @@ class DocuBot::Page
|
|
48
104
|
key=method.to_s
|
49
105
|
case key[-1..-1] # the last character of the method name
|
50
106
|
when '?' then @meta.has_key?( key[0..-2] )
|
51
|
-
#when '=' then @meta[ key[0..-2] ] = args[0]
|
52
107
|
when '!','=' then super
|
53
108
|
else @meta[ key ]
|
54
109
|
end
|
@@ -68,71 +123,75 @@ class DocuBot::Page
|
|
68
123
|
def every_leaf
|
69
124
|
(leafs + sub_sections.map{ |sub| sub.every_leaf }).flatten
|
70
125
|
end
|
126
|
+
|
71
127
|
def every_section
|
72
128
|
(sub_sections + sub_sections.map{ |sub| sub.every_section }).flatten
|
73
129
|
end
|
130
|
+
|
74
131
|
def descendants
|
75
132
|
(@pages + @pages.map{ |page| page.descendants }).flatten
|
76
133
|
end
|
77
134
|
alias_method :every_page, :descendants
|
135
|
+
|
78
136
|
def <<( entry )
|
79
137
|
@pages << entry
|
80
138
|
entry.parent = self
|
81
139
|
end
|
140
|
+
|
82
141
|
def leaf?
|
83
142
|
@pages.empty? || @pages.all?{ |x| x.is_a?(DocuBot::SubLink) }
|
84
143
|
end
|
144
|
+
|
85
145
|
def depth
|
86
|
-
@_depth ||= @file ? @file.count('/') : @folder.count('/') + 1
|
146
|
+
@_depth ||= self==@bundle.toc ? 0 : @file ? @file.count('/') : @folder.count('/') + 1
|
87
147
|
end
|
148
|
+
|
88
149
|
def root
|
89
150
|
@_root ||= "../" * depth
|
90
151
|
end
|
152
|
+
|
91
153
|
def html_path
|
92
154
|
@file ? @file.sub( /[^.]+$/, 'html' ) : ( @folder / 'index.html' )
|
93
155
|
end
|
94
|
-
|
95
|
-
|
156
|
+
|
157
|
+
# Call this if the source generated by the converter would change
|
158
|
+
# THIS DESTROYS ANY CUSTOM CHANGES YOU HAVE MADE TO THE NOKODOC
|
159
|
+
def dirty_source
|
160
|
+
@nokodoc = nil
|
161
|
+
end
|
162
|
+
|
163
|
+
# Call this after modifying the structure of the nokodoc for the page
|
164
|
+
def dirty_doc
|
165
|
+
@content_html = nil
|
166
|
+
end
|
96
167
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
168
|
+
# Call this if the HTML generated by the page template needs to change
|
169
|
+
# e.g. for a glossary page.
|
170
|
+
def dirty_template
|
171
|
+
# to_html doesn't cache anything at this point
|
172
|
+
# so nothing needs to be done here
|
173
|
+
end
|
174
|
+
|
175
|
+
def content_html
|
176
|
+
# Nokogiri 'helpfully' wraps our content in a full HTML page
|
177
|
+
# but apparently doesn't create a body for no content.
|
178
|
+
@content_html ||= (body=nokodoc.at_css('body')) && body.children.to_html
|
179
|
+
end
|
103
180
|
|
181
|
+
def to_html
|
182
|
+
#TODO: cache this is people keep calling to_html and it's a problem
|
104
183
|
@meta['template'] ||= leaf? ? 'page' : 'section'
|
105
184
|
|
106
185
|
master_templates = DocuBot::TEMPLATE_DIR
|
107
186
|
source_templates = @bundle.source / '_templates'
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
haml = Haml::Engine.new( IO.read(
|
113
|
-
|
114
|
-
|
115
|
-
|
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
|
123
|
-
|
124
|
-
@cached_html = html
|
125
|
-
end
|
126
|
-
def to_html!
|
127
|
-
@cached_html=nil
|
128
|
-
to_html
|
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
|
187
|
+
|
188
|
+
tmpl = source_templates / "#{template}.haml"
|
189
|
+
tmpl = master_templates / "#{template}.haml" unless File.exists?( tmpl )
|
190
|
+
tmpl = master_templates / "page.haml" unless File.exists?( tmpl )
|
191
|
+
haml = Haml::Engine.new( IO.read( tmpl ), DocuBot::Writer::HAML_OPTIONS )
|
192
|
+
haml.render( Object.new, :contents=>content_html, :page=>self, :global=>@bundle.toc, :root=>root )
|
193
|
+
end
|
194
|
+
|
136
195
|
end
|
137
196
|
|
138
197
|
class DocuBot::SubLink
|
@@ -165,7 +224,6 @@ class DocuBot::SubLink
|
|
165
224
|
def ancestors
|
166
225
|
@page.ancestors
|
167
226
|
end
|
168
|
-
alias_method :to_html!, :to_html
|
169
227
|
def method_missing(*args)
|
170
228
|
nil
|
171
229
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
keywords: Basics
|
2
|
+
toc : welcome authoring glossary index
|
3
|
+
+++
|
4
|
+
%h2#welcome Welcome to DocuBot for NVIDIA PhysX
|
5
|
+
%p.sidebar
|
6
|
+
%img(width='150' src='_static/NVBadge_3D.png')
|
7
|
+
NVIDIA 3D Badge
|
8
|
+
%span#out
|
9
|
+
:textile
|
10
|
+
This template shows the standard page style, which has a 350px sidebar on the right for including
|
11
|
+
images related to the text.
|
12
|
+
|
13
|
+
To put images (with an optional description) in the sidebar, place them inside a paragraph with
|
14
|
+
the CSS class @sidebar@. They will float to the right next to your content.
|
15
|
+
|
16
|
+
Each header will--by default--wait to begin until all images on the right have finished.
|
17
|
+
|
18
|
+
%h2#authoring Authoring Content
|
19
|
+
<p class="sidebar"><img src="_static/PhysXbyNV_Black.png" width="180"></p>
|
20
|
+
:markdown
|
21
|
+
The headers on each page should start at `h2` (not `h1`); `h1` is used for the title at the top of the page.
|
22
|
+
|
23
|
+
As shown in this template, if you apply HTML `id` attributes to the headers (or any other HTML element), and list those
|
24
|
+
identifiers under a toc entry at the top of the page, the Table of Contents will include sub-links to the headings.
|
25
|
+
|
26
|
+
%h2#glossary Glossary Entries
|
27
|
+
%p
|
28
|
+
To create a reference to a glossary term, surround it in double dollar signs.
|
29
|
+
For example, $$NVIDIA$$ makes $$PhysX$$ and $$APEX Libraries:APEX$$.
|
30
|
+
%p
|
31
|
+
As shown in the APEX link above, you can have the glossary text be different from the term it links to
|
32
|
+
by putting the words you want first, followed by a colon, followed by the actual glossary term to link to.
|
33
|
+
%p
|
34
|
+
This works in all markups. (The processing happens after the markup is converted to HTML.)
|
35
|
+
|
36
|
+
%h2#index Managing the Index
|
37
|
+
%p The index is automatically populated with the text from headings and defintions on the pages.
|
38
|
+
%p To add additional terms, you can:
|
39
|
+
%ul
|
40
|
+
%li
|
41
|
+
Use a <code>keywords</code> section at the top of the page with comma-delimited keywords or
|
42
|
+
phrases that you want the index to associate with the current page.
|
43
|
+
%li
|
44
|
+
:markdown
|
45
|
+
Put two `@` signs around any word or phrase in your text that you wanted added to the index.
|
46
|
+
|
47
|
+
For example, imagine that this page talked about @@sexy code@@; the index now knows about that.
|
48
|
+
|
49
|
+
Note that this syntax doesn't currently work with textile, because it uses single @ characters to
|
50
|
+
denote code. This will be fixed in the future (by processing glossary and index snippets before markup).
|
51
|
+
|