docubot 0.7.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,7 +20,7 @@ module FileUtils
20
20
  end
21
21
 
22
22
  module DocuBot
23
- VERSION = '0.7.1'
23
+ VERSION = '1.0.0'
24
24
  DIR = File.expand_path( File.dirname( __FILE__ ) )
25
25
 
26
26
  TEMPLATE_DIR = DIR / 'docubot/templates'
@@ -32,12 +32,12 @@ module DocuBot
32
32
  end
33
33
  end
34
34
 
35
- require 'docubot/link_tree'
36
- require 'docubot/metasection'
37
- require 'docubot/snippet'
38
- require 'docubot/converter'
39
- require 'docubot/writer'
40
- require 'docubot/page'
41
- require 'docubot/glossary'
42
- require 'docubot/index'
43
- require 'docubot/bundle'
35
+ require_relative 'docubot/link_tree'
36
+ require_relative 'docubot/metasection'
37
+ require_relative 'docubot/snippet'
38
+ require_relative 'docubot/converter'
39
+ require_relative 'docubot/writer'
40
+ require_relative 'docubot/page'
41
+ require_relative 'docubot/glossary'
42
+ require_relative 'docubot/index'
43
+ require_relative 'docubot/bundle'
@@ -83,11 +83,25 @@ class DocuBot::Bundle
83
83
  unless page.hide
84
84
  @toc.add_to_link_hierarchy( page.title, page.html_path, page )
85
85
  page.toc.as_list.each do |id_or_text|
86
- id = id_or_text[0..0] == '#' ? id_or_text : DocuBot.id_from_text(id_or_text)
87
- if ele = page.nokodoc.at_css(id)
88
- @toc.add_to_link_hierarchy( ele.inner_text, page.html_path + id, page )
86
+ if id_or_text[0..0] == '#'
87
+ if ele = page.nokodoc.at_css(id_or_text)
88
+ @toc.add_to_link_hierarchy( ele.inner_text, page.html_path + id_or_text, page )
89
+ else
90
+ warn "Could not find requested toc anchor #{id_or_text.inspect} on #{page.html_path}"
91
+ end
89
92
  else
90
- warn "Could not find requested toc anchor #{id.inspect} based on #{id_or_text.inspect} on #{page.html_path}"
93
+ # TODO: Find an elegant way to handle quotes in XPath, for speed
94
+ # Kramdown 'helpfully' converts quotes in the body to be curly, breaking direct text matching
95
+ quotes = /['‘’"“”]+/
96
+ quoteless = id_or_text.gsub(quotes,'')
97
+ if t=page.nokodoc.xpath('text()|.//text()').find{ |t| t.content.gsub(quotes,'')==quoteless }
98
+ ele = t.parent
99
+ # FIXME: better unique ID generator
100
+ ele['id'] = "item-#{Time.now.to_i}-#{rand 999999}" unless ele['id']
101
+ @toc.add_to_link_hierarchy( id_or_text, page.html_path + '#' + ele['id'], page )
102
+ else
103
+ warn "Could not find requested toc anchor for #{id_or_text.inspect} on #{page.html_path}"
104
+ end
91
105
  end
92
106
  end
93
107
  end
@@ -1,5 +1,4 @@
1
1
  # encoding: UTF-8
2
- require 'rubygems'
3
2
  require 'haml'
4
3
  options = { :format=>:html4, :ugly=>true }
5
4
  options.merge!( :encoding=>'utf-8' ) if Object.const_defined? "Encoding"
@@ -1,5 +1,4 @@
1
1
  # encoding: UTF-8
2
- require 'rubygems'
3
2
  begin
4
3
  require 'kramdown'
5
4
  DocuBot::Converter.to_convert :md, :markdown do |page, source|
@@ -10,5 +9,6 @@ begin
10
9
  end
11
10
  rescue LoadError
12
11
  warn "Unable to load kramdown gem; *.markdown/*.md markup will not be recognized as a page."
12
+ warn "(Use gem install kramdown to fix this, if you need Markdown processing.)"
13
13
  end
14
14
 
@@ -1,5 +1,4 @@
1
1
  # encoding: UTF-8
2
- require 'rubygems'
3
2
  begin
4
3
  require 'redcloth'
5
4
  DocuBot::Converter.to_convert :textile, :rc do |page, source|
@@ -7,4 +6,5 @@ begin
7
6
  end
8
7
  rescue LoadError
9
8
  warn "Unable to load RedCloth gem; *.textile/*.rc markup will not be recognized as a page."
9
+ warn "(Use gem install RedCloth to fix this, if you need Textile processing.)"
10
10
  end
@@ -25,7 +25,7 @@ class DocuBot::MetaSection
25
25
  @attrs = {}
26
26
  attrs.each{ |key,value| self[key]=value }
27
27
  if file_path && File.exists?( file_path )
28
- parts = IO.read( file_path ).split( META_SEPARATOR, 2 )
28
+ parts = IO.read( file_path, encoding:'utf-8' ).split( META_SEPARATOR, 2 )
29
29
  if parts.length > 1
30
30
  parts.first.scan(/.+/) do |line|
31
31
  next if line =~ /^\s*#/
@@ -155,7 +155,7 @@ class DocuBot::Page
155
155
  tmpl = source_templates / "#{template}.haml"
156
156
  tmpl = master_templates / "#{template}.haml" unless File.exists?( tmpl )
157
157
  tmpl = master_templates / "page.haml" unless File.exists?( tmpl )
158
- tmpl = IO.read( tmpl )
158
+ tmpl = IO.read( tmpl, encoding:'utf-8' )
159
159
  haml = Haml::Engine.new( tmpl, DocuBot::Writer::HAML_OPTIONS )
160
160
  haml.render( Object.new, :contents=>content_html, :page=>self, :global=>@bundle.global, :root=>root )
161
161
  end
@@ -72,12 +72,12 @@ class DocuBot::CHMWriter < DocuBot::HTMLWriter
72
72
  lap = Time.now
73
73
 
74
74
  # Clean out the intermediary files
75
- FileUtils.rm( [ @hhc, @hhp, @hhk ] ) unless ARGS[:logfile]
75
+ FileUtils.rm( [ @hhc, @hhp, @hhk ] ) unless defined?(ARGS) && ARGS[:logfile]
76
76
  FileUtils.rm_r( @html_path )
77
77
  puts "...%.2fs to clean up temporary files" % (Time.now-lap)
78
78
  lap = Time.now
79
79
 
80
- unless ARGS[:nopreview]
80
+ unless defined?(ARGS) && ARGS[:nopreview]
81
81
  # Spin a new thread so it doesn't hold up the Ruby process, but sleep long enough for it to get going.
82
82
  Thread.new{ `hh.exe "#{FileUtils.win_path @chm_path}"` }
83
83
  sleep 0.1 if Object.const_defined? "Encoding" # This sleep does not help on 1.8.6
@@ -88,19 +88,19 @@ class DocuBot::CHMWriter < DocuBot::HTMLWriter
88
88
 
89
89
  def write_hhc
90
90
  File.open( @hhc, 'w' ) do |f|
91
- f << ERB.new( IO.read( SUPPORT / 'hhc.erb' ) ).result( binding )
91
+ f << ERB.new( IO.read( SUPPORT / 'hhc.erb', encoding:'utf-8' ) ).result( binding )
92
92
  end
93
93
  end
94
94
 
95
95
  def write_hhp
96
96
  File.open( @hhp, 'w' ) do |f|
97
- f << ERB.new( IO.read( SUPPORT / 'hhp.erb' ) ).result( binding )
97
+ f << ERB.new( IO.read( SUPPORT / 'hhp.erb', encoding:'utf-8' ) ).result( binding )
98
98
  end
99
99
  end
100
100
 
101
101
  def write_hhk
102
102
  File.open( @hhk, 'w' ) do |f|
103
- f << ERB.new( IO.read( SUPPORT / 'hhk.erb' ) ).result( binding )
103
+ f << ERB.new( IO.read( SUPPORT / 'hhk.erb', encoding:'utf-8' ) ).result( binding )
104
104
  end
105
105
  end
106
106
  end
@@ -36,7 +36,7 @@ class DocuBot::HTMLWriter < DocuBot::Writer
36
36
 
37
37
  # Write out every page
38
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 )
39
+ top = Haml::Engine.new( IO.read( top, encoding:'utf-8' ), HAML_OPTIONS )
40
40
  @bundle.toc.descendants.each do |node|
41
41
  next if node.anchor
42
42
 
@@ -1,13 +1,12 @@
1
1
  #encoding: UTF-8
2
- $: << '..'
3
- require 'spec/global'
4
- require 'spec/bundle'
5
- require 'spec/toc'
6
- require 'spec/converters'
7
- require 'spec/page'
8
- require 'spec/glossary'
9
- require 'spec/index'
10
- require 'spec/templates'
11
- require 'spec/command'
12
- require 'spec/writer/html'
13
- require 'spec/writer/chm'
2
+ require_relative 'global'
3
+ require_relative 'bundle'
4
+ require_relative 'toc'
5
+ require_relative 'converters'
6
+ require_relative 'page'
7
+ require_relative 'glossary'
8
+ require_relative 'index'
9
+ require_relative 'templates'
10
+ require_relative 'command'
11
+ require_relative 'writer/html'
12
+ require_relative 'writer/chm'
@@ -1,8 +1,5 @@
1
- $: << File.join( File.dirname(__FILE__), '..' )
2
- $: << File.join( File.dirname(__FILE__), '..', 'lib' )
3
- require 'rubygems'
4
1
  require 'minitest/spec'
5
- require 'docubot'
2
+ require_relative '../lib/docubot'
6
3
  SAMPLES = File.dirname(__FILE__)/'samples'
7
4
  MiniTest::Unit.autorun
8
5
 
@@ -1,5 +1,5 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
4
  describe "AbusedBundle" do
5
5
  it 'requires a valid path' do
@@ -1,5 +1,5 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
4
  describe "CHM Writer default topic" do
5
5
  it "should pick the first valid page as the default if not specified" do
@@ -1,3 +1,3 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
@@ -1,2 +1,3 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
+
@@ -1,5 +1,5 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
4
  # http://www.w3.org/TR/html4/types.html#type-id
5
5
  # We disallow colons or periods in the ID because they mess up CSS selectors
@@ -1,5 +1,5 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
4
  describe "Glossary Scanner" do
5
5
  before do
@@ -1,2 +1,2 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
@@ -1,5 +1,5 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
4
  describe "Validating page titles" do
5
5
  before do
@@ -2,7 +2,7 @@ title: Combo the Other
2
2
  keywords: explicit, metasection, attributes/specifying
3
3
  no-index: headings
4
4
  auto-section:true
5
- toc: Heading 1, #h1-1, Giggity, #h0
5
+ toc: Heading 1, #h1-1, Giggity, #h0, Oh No No No
6
6
  +++
7
7
  %h2#h1 Heading 1
8
8
  %p#p1-1 Paragraph Number 1.1
@@ -0,0 +1,6 @@
1
+ title: Combo Mr. Markdown
2
+ toc: It's a Heading!
3
+ +++
4
+ ## It's a Heading!
5
+
6
+ The above has mixed casing, punctuation, and inline apostrophes.
@@ -0,0 +1 @@
1
+ _Hello_, **World!**
@@ -1,5 +1,5 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
4
  describe "Variety Hour" do
5
5
  before do
@@ -1,6 +1,7 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "_helper")
2
+ require_relative '_helper'
3
3
 
4
+ # *************************************************************************************************
4
5
  describe "Simplest Table of Contents" do
5
6
  before do
6
7
  Dir.chdir SAMPLES/'simplest' do
@@ -43,12 +44,14 @@ describe "Simplest Table of Contents" do
43
44
  end
44
45
  end
45
46
 
47
+ # *************************************************************************************************
46
48
  describe "Renamed Table of Contents" do
47
49
  it "honors the title of the root index file" do
48
50
  DocuBot::Bundle.new(SAMPLES/'titles').global.title.must_equal "Title Changin'"
49
51
  end
50
52
  end
51
53
 
54
+ # *************************************************************************************************
52
55
  describe "Sub-page Links in the Table of Contents" do
53
56
  before do
54
57
  @out, @err = capture_io do
@@ -75,37 +78,50 @@ describe "Sub-page Links in the Table of Contents" do
75
78
  it "should warn about failed TOC requests" do
76
79
  # explicit2.haml has an existing ID on the element for "Heading 1",
77
80
  # so it can't update the HTML id or the TOC request to match.
78
- @err.must_include "Heading 1"
81
+ @err.must_include "Oh No No No"
79
82
  end
80
83
 
81
84
  it "should have sub-entries" do
82
85
  e2 = @toc.find('explicit2.html')
83
86
 
84
- e2.children.length.must_equal 3
87
+ e2.children.length.must_equal 4
85
88
 
86
- # The first sub-link is not "Heading 1" because explicit2.haml has an existing ID on that element
87
- # and so cannot (at this time) change either the HTML id or the TOC request to match.
88
- # It is ignored.
89
89
  kid = e2.children[0]
90
+ kid.title.must_equal "Heading 1"
91
+ # No assumptions are made about the generated id.
92
+ kid.page.must_equal e2.page
93
+
94
+ kid = e2.children[1]
90
95
  kid.title.must_equal "Heading 1.1"
91
96
  kid.link.must_equal 'explicit2.html#h1-1'
92
97
  kid.page.must_equal e2.page
93
98
 
94
- kid = e2.children[1]
99
+ kid = e2.children[2]
95
100
  kid.title.must_equal "Giggity"
96
101
  kid.file.must_equal 'explicit2.html'
97
102
  # No assumptions are made about the generated id.
98
103
  kid.page.must_equal e2.page
99
104
 
100
- kid = e2.children[2]
105
+ kid = e2.children[3]
101
106
  kid.title.must_equal "Heading 0"
102
107
  kid.file.must_equal 'explicit2.html'
103
108
  kid.anchor.must_equal 'h0'
104
109
  kid.link.must_equal 'explicit2.html#h0'
105
110
  kid.page.must_equal e2.page
106
111
  end
112
+
113
+ it "should work for Markdown headers with mixed casing" do
114
+ e3 = @toc.find('explicit3.html')
115
+ e3.children.length.must_equal 1
116
+
117
+ kid = e3.children[0]
118
+ kid.title.must_equal "It's a Heading!"
119
+ kid.file.must_equal 'explicit3.html'
120
+ kid.page.must_equal e3.page
121
+ end
107
122
  end
108
123
 
124
+ # *************************************************************************************************
109
125
  describe "ToC with Deep Hierarchy" do
110
126
  before do
111
127
  @bundle = DocuBot::Bundle.new SAMPLES/'hierarchy'
@@ -1,2 +1,2 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "..", "_helper")
2
+ require_relative '../_helper'
@@ -1,2 +1,2 @@
1
1
  #encoding: UTF-8
2
- require File.join(File.dirname(__FILE__), "..", "_helper")
2
+ require_relative '../_helper'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docubot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -169,6 +169,7 @@ files:
169
169
  - spec/samples/attributes/defaults.haml
170
170
  - spec/samples/attributes/explicit1.haml
171
171
  - spec/samples/attributes/explicit2.haml
172
+ - spec/samples/attributes/explicit3.md
172
173
  - spec/samples/attributes/hidden.haml
173
174
  - spec/samples/attributes/index.md
174
175
  - spec/samples/collisions/page1.md
@@ -245,6 +246,8 @@ files:
245
246
  - spec/samples/underscores/Home.md
246
247
  - spec/samples/underscores/subsection/_andignoreme.md
247
248
  - spec/samples/underscores/_ignoreme.md
249
+ - spec/samples/underscores/_static/Foo/_ignoremore.txt
250
+ - spec/samples/underscores/_static/_Bar/_ignoreevenmore.txt
248
251
  - spec/templates.rb
249
252
  - spec/toc.rb
250
253
  - spec/writer/chm.rb
@@ -277,7 +280,7 @@ requirements:
277
280
  - RedCloth gem for Textile conversion.
278
281
  - MiniTest gem for running specifications.
279
282
  rubyforge_project:
280
- rubygems_version: 1.8.23
283
+ rubygems_version: 1.8.24
281
284
  signing_key:
282
285
  specification_version: 3
283
286
  summary: Create documentation from a hierarchy of text files.