docubot 0.3 → 0.3.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.
- 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
|
+
|