docubot 0.3.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/docubot +5 -1
- data/lib/docubot.rb +4 -2
- data/lib/docubot/bundle.rb +109 -61
- data/lib/docubot/converter.rb +4 -1
- data/lib/docubot/converters/haml.rb +1 -1
- data/lib/docubot/glossary.rb +3 -0
- data/lib/docubot/link_tree.rb +109 -0
- data/lib/docubot/metasection.rb +61 -0
- data/lib/docubot/page.rb +40 -118
- data/lib/docubot/shells/docubot-help/3_Advanced_Topics/Controlling the Table of Contents.md +2 -4
- data/lib/docubot/shells/nvphysx/_templates/_root/common.css +10 -5
- data/lib/docubot/shells/nvphysx/_templates/_root/glossary.css +1 -0
- data/lib/docubot/shells/nvphysx/_templates/_root/glossary.js +11 -1
- data/lib/docubot/shells/nvphysx/_templates/section.haml +9 -0
- data/lib/docubot/templates/index.haml +13 -20
- data/lib/docubot/templates/section.haml +1 -4
- data/lib/docubot/templates/toc.haml +2 -11
- data/lib/docubot/templates/top.haml +7 -4
- data/lib/docubot/writers/chm.rb +6 -5
- data/lib/docubot/writers/chm/hhc.erb +35 -12
- data/lib/docubot/writers/chm/hhk.erb +1 -1
- data/lib/docubot/writers/chm/hhp.erb +2 -2
- data/lib/docubot/writers/html.rb +33 -23
- data/spec/_all.rb +1 -0
- data/spec/_helper.rb +10 -0
- data/spec/bundle.rb +193 -2
- data/spec/global.rb +28 -0
- data/spec/glossary.rb +13 -11
- data/spec/page.rb +35 -9
- data/spec/samples/attributes/defaults.haml +34 -0
- data/spec/samples/attributes/explicit1.haml +43 -0
- data/spec/samples/attributes/explicit2.haml +42 -0
- data/spec/samples/attributes/hidden.haml +40 -0
- data/spec/samples/attributes/index.md +8 -0
- data/spec/samples/collisions/page1.md +3 -0
- data/spec/samples/collisions/page1.textile +3 -0
- data/spec/samples/collisions/page2.haml +4 -0
- data/spec/samples/collisions/page2.html +3 -0
- data/spec/samples/collisions/page2.txt +3 -0
- data/spec/samples/collisions/page3.bin +1 -0
- data/spec/samples/collisions/page3.md +3 -0
- data/spec/samples/{link_test/sub2/bozo.bin → files/BUILDING.txt} +0 -0
- data/spec/samples/{titletest/1 First One.txt → files/_static/Thumbs.db} +0 -0
- data/spec/samples/{titletest/2_Second_One.txt → files/_static/foo.ai} +0 -0
- data/spec/samples/{titletest/4 Fourth_One.txt → files/_static/foo.png} +0 -0
- data/spec/samples/{titletest/5_Fifth One.txt → files/_static/foo.psd} +0 -0
- data/spec/samples/files/another.md +0 -0
- data/spec/samples/files/common.css +0 -0
- data/spec/samples/files/first.textile +0 -0
- data/spec/samples/files/index.md +2 -0
- data/spec/samples/files/section/foo.jpg +0 -0
- data/spec/samples/files/section/page.haml +0 -0
- data/spec/samples/files/section/sub section/Thumbs.db b/data/spec/samples/files/section/sub → section/Thumbs.db +0 -0
- data/spec/samples/files/section/sub section/foo.gif b/data/spec/samples/files/section/sub → section/foo.gif +0 -0
- data/spec/samples/files/section/sub section/page.txt b/data/spec/samples/files/section/sub → section/page.txt +0 -0
- data/spec/samples/{link_test → links}/index.txt +0 -0
- data/spec/samples/{link_test → links}/root.md +0 -0
- data/spec/samples/{link_test → links}/sub1/inner1.md +0 -0
- data/spec/samples/{link_test → links}/sub2.md +0 -0
- data/spec/samples/links/sub2/bozo.bin +0 -0
- data/spec/samples/{link_test → links}/sub2/inner2.md +0 -0
- data/spec/samples/templates/_templates/404.haml +1 -0
- data/spec/samples/templates/_templates/doubler.haml +7 -0
- data/spec/samples/templates/_templates/page.haml +2 -0
- data/spec/samples/templates/goaway.txt +3 -0
- data/spec/samples/templates/onepara_html.html +3 -0
- data/spec/samples/templates/onepara_md.md +5 -0
- data/spec/samples/templates/twopara_haml.haml +7 -0
- data/spec/samples/templates/twopara_textile.textile +6 -0
- data/spec/samples/titles/1 First One.txt b/data/spec/samples/titles/1 First → One.txt +0 -0
- data/spec/samples/titles/2_Second_One.txt +0 -0
- data/spec/samples/{titletest → titles}/3_renamed.txt +0 -0
- data/spec/samples/titles/4 Fourth_One.txt b/data/spec/samples/titles/4 → Fourth_One.txt +0 -0
- data/spec/samples/titles/5_Fifth One.txt b/data/spec/samples/titles/5_Fifth → One.txt +0 -0
- data/spec/samples/titles/911.txt +0 -0
- data/spec/samples/titles/index.txt +2 -0
- data/spec/templates.rb +42 -0
- data/spec/toc.rb +64 -30
- metadata +53 -14
- data/spec/samples/titletest/index.txt +0 -2
@@ -3,22 +3,45 @@
|
|
3
3
|
<HEAD>
|
4
4
|
<meta name="GENERATOR" content="Microsoft® HTML Help Workshop 4.1">
|
5
5
|
<!-- Sitemap 1.0 -->
|
6
|
-
|
6
|
+
<%
|
7
|
+
ICON = {
|
8
|
+
:book => 1,
|
9
|
+
:folder => 5,
|
10
|
+
:question => 9,
|
11
|
+
:page => 11,
|
12
|
+
:internet => 13,
|
13
|
+
:info => 17,
|
14
|
+
:shortcut => 19,
|
15
|
+
:letter => 23,
|
16
|
+
:attachment => 25,
|
17
|
+
:contact => 27,
|
18
|
+
:sound => 29,
|
19
|
+
:cd => 31,
|
20
|
+
:movie => 33,
|
21
|
+
:list => 35,
|
22
|
+
:idea => 37,
|
23
|
+
:note => 39,
|
24
|
+
:tool => 41
|
25
|
+
}
|
26
|
+
|
27
|
+
@write_section = lambda do |node|
|
28
|
+
%>
|
7
29
|
<UL>
|
8
|
-
<%
|
9
|
-
|
30
|
+
<%node.children.each do |child|
|
31
|
+
icon = if child.anchor
|
32
|
+
ICON[:info]
|
33
|
+
elsif child.page.icon
|
34
|
+
ICON[ child.page.icon.downcase.to_sym ] || child.page.icon
|
35
|
+
else
|
36
|
+
child.leaf? ? ICON[:page] : ICON[:book]
|
37
|
+
end
|
38
|
+
%>
|
10
39
|
<LI> <OBJECT type="text/sitemap">
|
11
40
|
<param name="Name" value="<%=CGI.escapeHTML child.title%>">
|
12
|
-
<param name="Local" value="<%=FileUtils.win_path( @html_path / child.
|
13
|
-
|
14
|
-
%><param name="ImageNumber" value="<%=child.icon%>"><%
|
15
|
-
elsif child.sublink?
|
16
|
-
%><param name="ImageNumber" value="17"><%
|
17
|
-
elsif child.leaf?
|
18
|
-
%><param name="ImageNumber" value="11"><%
|
19
|
-
end%>
|
41
|
+
<param name="Local" value="<%=FileUtils.win_path( @html_path / child.link ).gsub('&','%26')%>">
|
42
|
+
<param name="ImageNumber" value="<%=icon%>">
|
20
43
|
</OBJECT>
|
21
|
-
<%@write_section[child] unless child.
|
44
|
+
<%@write_section[child] unless child.children.empty?%>
|
22
45
|
<%end%>
|
23
46
|
</UL>
|
24
47
|
<%end%>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<param name="FrameName" value="right">
|
9
9
|
</OBJECT>
|
10
10
|
<UL>
|
11
|
-
<%@
|
11
|
+
<%@global.index.each do |entry,pages|%>
|
12
12
|
<LI> <OBJECT type="text/sitemap">
|
13
13
|
<param name="Name" value="<%=entry%>">
|
14
14
|
<param name="Local" value="<%=FileUtils.win_path( @html_path/pages.first.html_path )%>">
|
@@ -7,11 +7,11 @@ Index file="<%=FileUtils.win_path @hhk%>"
|
|
7
7
|
<%end%>Display compile progress=No
|
8
8
|
Full-text search=Yes
|
9
9
|
Language=0x409 English (United States)
|
10
|
-
Title=<%=@
|
10
|
+
Title=<%=@global.title%>
|
11
11
|
|
12
12
|
|
13
13
|
[FILES]
|
14
|
-
<%@
|
14
|
+
<%@bundle.pages.each do |page|
|
15
15
|
%><%=FileUtils.win_path( @html_path/page.html_path) %>
|
16
16
|
<%end
|
17
17
|
@bundle.extras.each do |file|
|
data/lib/docubot/writers/html.rb
CHANGED
@@ -12,6 +12,8 @@ class DocuBot::HTMLWriter < DocuBot::Writer
|
|
12
12
|
|
13
13
|
master_templates = DocuBot::TEMPLATE_DIR
|
14
14
|
source_templates = source/'_templates'
|
15
|
+
master_root = master_templates/'_root'
|
16
|
+
source_root = source_templates/'_root'
|
15
17
|
|
16
18
|
# Copy any files found in the source directory that weren't made into pages
|
17
19
|
@bundle.extras.each do |file|
|
@@ -33,26 +35,34 @@ class DocuBot::HTMLWriter < DocuBot::Writer
|
|
33
35
|
o = Object.new
|
34
36
|
|
35
37
|
# Write out every page
|
36
|
-
|
37
|
-
|
38
|
-
@bundle.toc.descendants.each do |
|
39
|
-
next if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
FileUtils.mkdir_p( File.dirname( page.html_path ) )
|
44
|
-
File.open( page.html_path, 'w' ){ |f| f << html }
|
45
|
-
end
|
38
|
+
top = File.exists?( source_templates/'top.haml' ) ? source_templates/'top.haml' : master_templates/'top.haml'
|
39
|
+
top = Haml::Engine.new( IO.read( top ), HAML_OPTIONS )
|
40
|
+
@bundle.toc.descendants.each do |node|
|
41
|
+
next if node.anchor
|
42
|
+
|
43
|
+
contents = node.page.to_html
|
44
|
+
template = node.page.template # Call page.to_html first to ensure page.template is set
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
46
|
+
custom_js = "#{template}.js"
|
47
|
+
custom_js = nil unless File.exists?( source_root/custom_js ) || File.exists?( master_root/custom_js )
|
48
|
+
|
49
|
+
custom_css = "#{template}.css"
|
50
|
+
custom_css = nil unless File.exists?( source_root/custom_css ) || File.exists?( master_root/custom_css )
|
51
|
+
|
52
|
+
variables = {
|
53
|
+
:page => node.page,
|
54
|
+
:contents => contents,
|
55
|
+
:global => @bundle.global,
|
56
|
+
:root => node.root,
|
57
|
+
:breadcrumb => node.ancestors,
|
58
|
+
:custom_js => custom_js,
|
59
|
+
:custom_css => custom_css
|
60
|
+
}
|
61
|
+
html = top.render( o, variables )
|
62
|
+
FileUtils.mkdir_p( File.dirname( node.file ) )
|
63
|
+
File.open( node.file, 'w' ){ |f| f << html }
|
54
64
|
end
|
55
|
-
|
65
|
+
|
56
66
|
File.open( 'glossary-terms.js', 'w' ){ |f| f << @bundle.glossary.to_js }
|
57
67
|
end
|
58
68
|
|
@@ -61,13 +71,13 @@ class DocuBot::HTMLWriter < DocuBot::Writer
|
|
61
71
|
end
|
62
72
|
|
63
73
|
module Haml::Helpers
|
64
|
-
def li_pages_for(
|
65
|
-
|
66
|
-
haml_tag :li do
|
67
|
-
haml_tag :a, :href=>child.
|
74
|
+
def li_pages_for( node )
|
75
|
+
node.children.each do |child|
|
76
|
+
haml_tag :li, :class=>(child.anchor ? 'sublink' : child.children.empty? ? 'section' : 'page' ) do
|
77
|
+
haml_tag :a, :href=>child.link do
|
68
78
|
haml_concat child.title
|
69
79
|
end
|
70
|
-
unless child.
|
80
|
+
unless child.children.empty?
|
71
81
|
haml_tag :ul do
|
72
82
|
li_pages_for child
|
73
83
|
end
|
data/spec/_all.rb
CHANGED
data/spec/_helper.rb
CHANGED
@@ -4,3 +4,13 @@ require 'minitest/spec'
|
|
4
4
|
require 'docubot'
|
5
5
|
SAMPLES = File.dirname(__FILE__)/'samples'
|
6
6
|
MiniTest::Unit.autorun
|
7
|
+
|
8
|
+
class MiniTest::Spec
|
9
|
+
class << self
|
10
|
+
alias_method :__it__, :it
|
11
|
+
end
|
12
|
+
def self.it desc, &block
|
13
|
+
block ||= proc{ skip "(no tests defined)" }
|
14
|
+
__it__( desc, &block )
|
15
|
+
end
|
16
|
+
end
|
data/spec/bundle.rb
CHANGED
@@ -18,7 +18,7 @@ describe "Bundle from empty directory" do
|
|
18
18
|
|
19
19
|
it "should have an empty TOC" do
|
20
20
|
@bundle.toc.wont_be_nil
|
21
|
-
@bundle.toc.
|
21
|
+
@bundle.toc.descendants.must_be_empty
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should have an empty index" do
|
@@ -61,7 +61,7 @@ end
|
|
61
61
|
describe "Gathering links" do
|
62
62
|
before do
|
63
63
|
@out, @err = capture_io do
|
64
|
-
@bundle = DocuBot::Bundle.new SAMPLES/'
|
64
|
+
@bundle = DocuBot::Bundle.new SAMPLES/'links'
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -140,3 +140,194 @@ describe "Gathering links" do
|
|
140
140
|
end
|
141
141
|
end
|
142
142
|
end
|
143
|
+
|
144
|
+
describe "Identifying Conflicts" do
|
145
|
+
it "should raise when multiple pages will write to the same html" do
|
146
|
+
proc{
|
147
|
+
@bundle = DocuBot::Bundle.new( SAMPLES/'collisions' )
|
148
|
+
}.must_raise(DocuBot::Bundle::PageCollision)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should include the title and filename of every conflicting page" do
|
152
|
+
begin
|
153
|
+
@bundle = DocuBot::Bundle.new( SAMPLES/'collisions' )
|
154
|
+
rescue DocuBot::Bundle::PageCollision => e
|
155
|
+
e.message.must_include "page1.md"
|
156
|
+
e.message.must_include "page1.textile"
|
157
|
+
e.message.must_include "Page 1 (from Markdown)"
|
158
|
+
e.message.must_include "Page 1 (from Textile)"
|
159
|
+
e.message.must_include "page2.html"
|
160
|
+
e.message.must_include "page2.txt"
|
161
|
+
e.message.must_include "page2.haml"
|
162
|
+
e.message.must_include "Page 2 (from html)"
|
163
|
+
e.message.must_include "Page 2 (from text)"
|
164
|
+
e.message.must_include "Page 2 (from haml)"
|
165
|
+
e.message.wont_include "page3.md"
|
166
|
+
e.message.wont_include "page3.bin"
|
167
|
+
e.message.wont_include "Page 3"
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "Bundle with Extra Files" do
|
174
|
+
before do
|
175
|
+
@out, @err = capture_io do
|
176
|
+
@bundle = DocuBot::Bundle.new( SAMPLES/'files' )
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should keep track of extra files seen" do
|
181
|
+
@bundle.extras.wont_be_nil
|
182
|
+
static_files = %w[ common.css _static/foo.png section/foo.jpg ]
|
183
|
+
static_files << "section/sub section/foo.gif"
|
184
|
+
static_files.each do |path|
|
185
|
+
@bundle.extras.must_include path
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should not count page sources as extra files" do
|
190
|
+
page_files = %w[ index.md another.md first.textile section/page.haml ]
|
191
|
+
page_files << "section/sub section/page.txt"
|
192
|
+
page_files.each do |path|
|
193
|
+
@bundle.extras.wont_include path
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should skip files specified by global glob matches" do
|
198
|
+
@bundle.global.ignore.as_list.must_equal %w[ **/*.psd **/*.ai **/Thumbs.db BUILDING.txt ]
|
199
|
+
bad_files = %w[ _static/foo.ai _static/foo.psd _static/Thumbs.db ]
|
200
|
+
bad_files << "section/sub section/Thumbs.db"
|
201
|
+
bad_files.each do |path|
|
202
|
+
@bundle.extras.wont_include path
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should not count ignored files as the source for pages" do
|
207
|
+
@bundle.pages.find{ |page| page.file == 'BUILDING.txt' }.must_be_nil
|
208
|
+
@bundle.page_by_file_path['BUILDING.txt'].must_be_nil
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
describe "Pages in bundles" do
|
213
|
+
before do
|
214
|
+
@titles = [ 'First One', 'Second One', 'Third One', 'Fourth One', 'Fifth One', '911' ]
|
215
|
+
Dir.chdir SAMPLES/'links' do
|
216
|
+
@files = Dir['**/*'] - %w[ index.txt sub2/bozo.bin ]
|
217
|
+
@htmls = @files.map{ |path|
|
218
|
+
path[/\.[^.]+$/] ? path.gsub(/\.[^.]+$/,'.html') : path/'index.html'
|
219
|
+
}
|
220
|
+
end
|
221
|
+
@out, @err = capture_io do
|
222
|
+
@titles_bundle = DocuBot::Bundle.new SAMPLES/'titles'
|
223
|
+
@links_bundle = DocuBot::Bundle.new SAMPLES/'links'
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should allow you to find arrays of pages by title" do
|
228
|
+
@titles_bundle.pages_by_title.wont_be_nil
|
229
|
+
@titles.each do |page_title|
|
230
|
+
pages = @titles_bundle.pages_by_title[page_title]
|
231
|
+
pages.must_be_kind_of Array
|
232
|
+
pages.length.must_equal 1
|
233
|
+
pages.first.must_be_kind_of DocuBot::Page
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should return an empty array for a non-existent page" do
|
238
|
+
pages = @titles_bundle.pages_by_title['NONE SUCH']
|
239
|
+
pages.must_be_kind_of Array
|
240
|
+
pages.length.must_equal 0
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should not include the main index file in the titles" do
|
244
|
+
pages = @titles_bundle.pages_by_title["Title Changin'"]
|
245
|
+
pages.must_be_kind_of Array
|
246
|
+
pages.length.must_equal 0
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should give access to pages by source file path" do
|
250
|
+
@links_bundle.page_by_file_path.wont_be_nil
|
251
|
+
@files.each do |path|
|
252
|
+
@links_bundle.page_by_file_path[path].must_be_kind_of DocuBot::Page
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should return nil for an unfound file path" do
|
257
|
+
@links_bundle.page_by_file_path['NONE SUCH'].must_be_nil
|
258
|
+
end
|
259
|
+
|
260
|
+
it "should not include raw files in the file paths" do
|
261
|
+
@links_bundle.page_by_file_path['sub2/bozo.bin'].must_be_nil
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should give access to pages by html file path" do
|
265
|
+
@links_bundle.page_by_html_path.wont_be_nil
|
266
|
+
@htmls.each do |path|
|
267
|
+
p path unless @links_bundle.page_by_html_path[path]
|
268
|
+
@links_bundle.page_by_html_path[path].wont_be_nil
|
269
|
+
@links_bundle.page_by_html_path[path].must_be_kind_of DocuBot::Page
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
it "should return nil for an unfound html path" do
|
274
|
+
@links_bundle.page_by_html_path['NONE SUCH'].must_be_nil
|
275
|
+
end
|
276
|
+
|
277
|
+
it "should not include raw files in the html paths" do
|
278
|
+
@links_bundle.page_by_html_path['sub2/bozo.bin'].must_be_nil
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "Global bundle attributes" do
|
283
|
+
before do
|
284
|
+
@out, @err = capture_io do
|
285
|
+
@bundle = DocuBot::Bundle.new SAMPLES/'attributes'
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should have a global object" do
|
290
|
+
@bundle.global.wont_be_nil
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should be indexable by method and return strings" do
|
294
|
+
@bundle.global.author.must_equal "Gavin Kistner"
|
295
|
+
@bundle.global.default.must_equal "All About Mr. Friggles"
|
296
|
+
@bundle.global.quotes.must_equal %q{"It's all about Mr. Benjamin", "I have never seen this cat before in my life!"}
|
297
|
+
@bundle.global.awesome.must_equal "true"
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should be indexable by string" do
|
301
|
+
@bundle.global['author.email'].must_equal "!@phrogz.net"
|
302
|
+
@bundle.global['author website'].must_equal "http://phrogz.net"
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should use utf8 for the strings" do
|
306
|
+
if Object.const_defined? :Encoding
|
307
|
+
Encoding.compatible?( @bundle.global.title, "UTF-8™")
|
308
|
+
end
|
309
|
+
@bundle.global.title.must_equal "Friggles® The Cat, ©2009"
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should allow casting values to boolean" do
|
313
|
+
@bundle.global.awesome.as_boolean.must_equal true
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should allow casting values to arrays of strings" do
|
317
|
+
quotes = @bundle.global.quotes.as_list
|
318
|
+
quotes.must_be_kind_of Array
|
319
|
+
quotes.must_equal [ "It's all about Mr. Benjamin", "I have never seen this cat before in my life!" ]
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe "Page attributes" do
|
324
|
+
before do
|
325
|
+
@out, @err = capture_io do
|
326
|
+
@bundle = DocuBot::Bundle.new SAMPLES/'attributes'
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
it "does something" do
|
331
|
+
|
332
|
+
end
|
333
|
+
end
|
data/spec/global.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
require File.join(File.dirname(__FILE__), "_helper")
|
3
|
+
|
4
|
+
# http://www.w3.org/TR/html4/types.html#type-id
|
5
|
+
# We disallow colons or periods in the ID because they mess up CSS selectors
|
6
|
+
# We require an octothorpe at the front because it makes life easier
|
7
|
+
VALID_ID = /#[a-z][\w-]*/i
|
8
|
+
|
9
|
+
describe "Generating IDs from Text" do
|
10
|
+
it "must create a valid identifier from a variety of input" do
|
11
|
+
DocuBot.id_from_text("foo").must_match VALID_ID
|
12
|
+
DocuBot.id_from_text("foo-bar").must_match VALID_ID
|
13
|
+
DocuBot.id_from_text("Foo-Bar").must_match VALID_ID
|
14
|
+
DocuBot.id_from_text("foo bar").must_match VALID_ID
|
15
|
+
DocuBot.id_from_text(" foo").must_match VALID_ID
|
16
|
+
DocuBot.id_from_text("foo ").must_match VALID_ID
|
17
|
+
DocuBot.id_from_text(" foo ").must_match VALID_ID
|
18
|
+
DocuBot.id_from_text("foo:bar").must_match VALID_ID
|
19
|
+
DocuBot.id_from_text("foo.bar").must_match VALID_ID
|
20
|
+
DocuBot.id_from_text("foo!bar").must_match VALID_ID
|
21
|
+
DocuBot.id_from_text("foo?!bar").must_match VALID_ID
|
22
|
+
DocuBot.id_from_text("foo(bar)").must_match VALID_ID
|
23
|
+
DocuBot.id_from_text("(foo)bar").must_match VALID_ID
|
24
|
+
DocuBot.id_from_text("!foo bar").must_match VALID_ID
|
25
|
+
DocuBot.id_from_text("foo: bar").must_match VALID_ID
|
26
|
+
DocuBot.id_from_text("!!!").wont_match VALID_ID
|
27
|
+
end
|
28
|
+
end
|
data/spec/glossary.rb
CHANGED
@@ -13,8 +13,8 @@ describe "Glossary Scanner" do
|
|
13
13
|
@out, @err = capture_io do
|
14
14
|
@bundle = DocuBot::Bundle.new SAMPLES/'glossary'
|
15
15
|
@glossary = @bundle.glossary
|
16
|
-
@page = @bundle.
|
17
|
-
@fulldoc = Nokogiri::HTML( @page.to_html )
|
16
|
+
@page = @bundle.pages_by_title['Glossary'].first
|
17
|
+
@fulldoc = Nokogiri::HTML::DocumentFragment.parse( @page.to_html )
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -34,9 +34,9 @@ describe "Glossary Scanner" do
|
|
34
34
|
@glossary.entries.values.each do |defn|
|
35
35
|
defn.must_be_kind_of DocuBot::Page
|
36
36
|
end
|
37
|
-
@glossary.entries["Secret Term"].hide.must_equal true
|
37
|
+
@glossary.entries["Secret Term"].hide.as_boolean.must_equal true
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "supports iterating over the entries with each" do
|
41
41
|
count = 0
|
42
42
|
@glossary.each do |page,defn|
|
@@ -47,26 +47,28 @@ describe "Glossary Scanner" do
|
|
47
47
|
count.must_equal @all_terms.length
|
48
48
|
end
|
49
49
|
|
50
|
-
|
51
50
|
it "uses converters for page content" do
|
52
51
|
@expected_paragraphs.each do |term,paras|
|
53
|
-
@glossary.entries[term].nokodoc.xpath('
|
52
|
+
@glossary.entries[term].nokodoc.xpath('.//p').length.must_equal paras
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
56
|
it "supports a glossary template that generates HTML for terms" do
|
58
|
-
definitions = @fulldoc.xpath('
|
57
|
+
definitions = @fulldoc.xpath('.//dt')
|
59
58
|
@expected_paragraphs.each do |term,paras|
|
60
59
|
dt = definitions.find{ |node| node.inner_text==term }
|
61
60
|
dt.wont_be_nil
|
62
|
-
dt.next_element.xpath('.//p').length
|
61
|
+
if dt.next_element.xpath('.//p').length != paras
|
62
|
+
puts dt.next_element.to_html
|
63
|
+
end
|
64
|
+
dt.next_element.xpath('.//p').length.must_equal paras
|
63
65
|
end
|
64
66
|
end
|
65
|
-
|
67
|
+
|
66
68
|
it "does not include hidden pages in the output" do
|
67
|
-
definitions = @fulldoc.xpath('
|
69
|
+
definitions = @fulldoc.xpath('.//dt')
|
68
70
|
@hidden_terms.each do |term|
|
69
|
-
@fulldoc.at_xpath("
|
71
|
+
@fulldoc.at_xpath(".//dt[text()='#{term}']").must_be_nil
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|