rpub 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -1
  3. data/.rspec +0 -1
  4. data/.travis.yml +3 -4
  5. data/.yardopts +1 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +70 -46
  8. data/Guardfile +6 -0
  9. data/HISTORY.md +10 -0
  10. data/README.md +1 -1
  11. data/Rakefile +7 -2
  12. data/bin/rpub +64 -1
  13. data/doc/.gitignore +8 -0
  14. data/doc/api/Rpub.html +339 -0
  15. data/doc/api/Rpub/Book.html +983 -0
  16. data/doc/api/Rpub/Chapter.html +737 -0
  17. data/doc/api/Rpub/Command.html +356 -0
  18. data/doc/api/Rpub/Commands.html +117 -0
  19. data/doc/api/Rpub/Commands/Clean.html +216 -0
  20. data/doc/api/Rpub/Commands/Compile.html +218 -0
  21. data/doc/api/Rpub/Commands/Generate.html +242 -0
  22. data/doc/api/Rpub/Commands/Package.html +230 -0
  23. data/doc/api/Rpub/Commands/Preview.html +216 -0
  24. data/doc/api/Rpub/Commands/Stats.html +226 -0
  25. data/doc/api/Rpub/Compressor.html +687 -0
  26. data/doc/api/Rpub/Context.html +553 -0
  27. data/doc/api/Rpub/Document.html +647 -0
  28. data/doc/api/Rpub/Document/OutlineElement.html +388 -0
  29. data/doc/api/Rpub/Epub.html +465 -0
  30. data/doc/api/Rpub/Epub/Container.html +224 -0
  31. data/doc/api/Rpub/Epub/Content.html +344 -0
  32. data/doc/api/Rpub/Epub/Cover.html +236 -0
  33. data/doc/api/Rpub/Epub/HtmlToc.html +240 -0
  34. data/doc/api/Rpub/Epub/Toc.html +244 -0
  35. data/doc/api/Rpub/FilesystemSource.html +544 -0
  36. data/doc/api/Rpub/HashDelegation.html +281 -0
  37. data/doc/api/Rpub/HashDelegation/ClassMethods.html +175 -0
  38. data/doc/api/Rpub/MediaType.html +192 -0
  39. data/doc/api/Rpub/Preview.html +464 -0
  40. data/doc/api/Rpub/XmlFile.html +457 -0
  41. data/doc/api/_index.html +405 -0
  42. data/doc/api/class_list.html +54 -0
  43. data/doc/api/css/common.css +1 -0
  44. data/doc/api/css/full_list.css +57 -0
  45. data/doc/api/css/style.css +339 -0
  46. data/doc/api/file.HISTORY.html +131 -0
  47. data/doc/api/file.LICENSE.html +92 -0
  48. data/doc/api/file.README.html +337 -0
  49. data/doc/api/file_list.html +62 -0
  50. data/doc/api/frames.html +26 -0
  51. data/doc/api/index.html +337 -0
  52. data/doc/api/js/app.js +219 -0
  53. data/doc/api/js/full_list.js +178 -0
  54. data/doc/api/js/jquery.js +4 -0
  55. data/doc/api/method_list.html +533 -0
  56. data/doc/api/top-level-namespace.html +112 -0
  57. data/doc/index.html +312 -0
  58. data/doc/javascripts/scale.fix.js +17 -0
  59. data/doc/params.json +1 -0
  60. data/doc/stylesheets/pygment_trac.css +69 -0
  61. data/doc/stylesheets/styles.css +255 -0
  62. data/features/clean.feature +31 -0
  63. data/features/compile.feature +49 -0
  64. data/features/embedded_assets.feature +51 -0
  65. data/features/generate.feature +63 -0
  66. data/features/layout.feature +41 -0
  67. data/features/package.feature +30 -0
  68. data/features/previews.feature +66 -0
  69. data/features/stats.feature +18 -0
  70. data/features/step_definitions/general_steps.rb +60 -0
  71. data/features/styles.feature +33 -0
  72. data/features/support/env.rb +7 -0
  73. data/features/table_of_contents.feature +35 -0
  74. data/lib/rpub.rb +28 -31
  75. data/lib/rpub/book.rb +9 -16
  76. data/lib/rpub/chapter.rb +4 -54
  77. data/lib/rpub/command.rb +32 -0
  78. data/lib/rpub/commands/clean.rb +4 -49
  79. data/lib/rpub/commands/compile.rb +4 -49
  80. data/lib/rpub/commands/generate.rb +10 -67
  81. data/lib/rpub/commands/package.rb +9 -37
  82. data/lib/rpub/commands/preview.rb +4 -54
  83. data/lib/rpub/commands/stats.rb +6 -10
  84. data/lib/rpub/compressor.rb +3 -3
  85. data/lib/rpub/context.rb +48 -0
  86. data/lib/rpub/document.rb +68 -0
  87. data/lib/rpub/epub.rb +8 -7
  88. data/lib/rpub/epub/content.rb +9 -30
  89. data/lib/rpub/epub/cover.rb +1 -8
  90. data/lib/rpub/epub/html_toc.rb +4 -9
  91. data/lib/rpub/epub/toc.rb +16 -13
  92. data/lib/rpub/filesystem_source.rb +47 -0
  93. data/lib/rpub/media_type.rb +16 -0
  94. data/lib/rpub/preview.rb +29 -0
  95. data/lib/rpub/version.rb +1 -1
  96. data/lib/rpub/xml_file.rb +4 -1
  97. data/rpub.gemspec +6 -7
  98. data/spec/rpub/book_spec.rb +45 -45
  99. data/spec/rpub/chapter_spec.rb +87 -22
  100. data/spec/rpub/epub/container_spec.rb +3 -5
  101. data/spec/rpub/epub/content_spec.rb +62 -41
  102. data/spec/rpub/epub/cover_spec.rb +3 -5
  103. data/spec/rpub/epub/html_toc_spec.rb +8 -8
  104. data/spec/rpub/epub/toc_spec.rb +20 -22
  105. data/spec/rpub_spec.rb +1 -3
  106. data/spec/spec_helper.rb +28 -0
  107. data/support/config.yml +1 -0
  108. data/support/styles.css +3 -3
  109. metadata +131 -120
  110. data/lib/rpub/commander.rb +0 -23
  111. data/lib/rpub/commands/base.rb +0 -33
  112. data/lib/rpub/commands/help.rb +0 -37
  113. data/lib/rpub/commands/main.rb +0 -45
  114. data/lib/rpub/compilation_helpers.rb +0 -73
  115. data/lib/rpub/subclass_tracker.rb +0 -53
  116. data/spec/rpub/commands/clean_spec.rb +0 -46
  117. data/spec/rpub/commands/generate_spec.rb +0 -52
  118. data/spec/rpub/commands/main_spec.rb +0 -26
  119. data/spec/rpub/commands/package_spec.rb +0 -33
  120. data/spec/rpub/commands/preview_spec.rb +0 -43
@@ -0,0 +1,41 @@
1
+ Feature: page layout
2
+ As an author
3
+ I want to wrap my content in a template file
4
+ In order to spice up my book's looks
5
+
6
+ Background:
7
+ Given a file named "chapter1.md" with:
8
+ """
9
+ # Hello, world
10
+ """
11
+
12
+ Scenario: default layout
13
+ When I successfully run `rpub compile`
14
+ And I successfully run `unzip untitled-book-0.0.0.epub`
15
+ Then the file "OEBPS/chapter-0-hello-world.html" should contain "<body>"
16
+
17
+ Scenario: overriding layout by filename
18
+ Given a file named "layout.html" with:
19
+ """
20
+ foo
21
+ <%= @body %>
22
+ bar
23
+ """
24
+ When I successfully run `rpub compile`
25
+ And I successfully run `unzip untitled-book-0.0.0.epub`
26
+ Then the file "OEBPS/chapter-0-hello-world.html" should contain "foo"
27
+ And the file "OEBPS/chapter-0-hello-world.html" should contain "bar"
28
+
29
+ Scenario: overriding layout by option
30
+ Given a file named "template.html" with:
31
+ """
32
+ foo
33
+ <%= @body %>
34
+ bar
35
+ """
36
+ When I successfully run `rpub compile -l template.html`
37
+ And I successfully run `unzip untitled-book-0.0.0.epub`
38
+ Then the file "OEBPS/chapter-0-hello-world.html" should contain "foo"
39
+ And the file "OEBPS/chapter-0-hello-world.html" should contain "bar"
40
+
41
+
@@ -0,0 +1,30 @@
1
+ Feature: packaging
2
+ As an author
3
+ I want to package my book and other files into a single archive
4
+ So I can easily distribute it over the internet
5
+
6
+ Background:
7
+ Given a basic project
8
+
9
+ Scenario: compressing book
10
+ When I successfully run `rpub package`
11
+ Then a file named "untitled_book.zip" should exist
12
+ And the archive "untitled_book.zip" should contain file "untitled-book-0.0.0.epub"
13
+
14
+ Scenario: custom package filename
15
+ Given the default "config.yml" file with "package_file" set to "my_book.zip"
16
+ When I successfully run `rpub package`
17
+ Then a file named "my_book.zip" should exist
18
+
19
+ Scenario: uncompiled book
20
+ When I successfully run `rpub package`
21
+ Then a file named "untitled-book-0.0.0.epub" should exist
22
+
23
+ Scenario: help
24
+ When I successfully run `rpub package -h`
25
+ Then the output should contain "Compile your ebook to an ePub file and package it into an archive"
26
+
27
+ Scenario: additional files
28
+ When I successfully run `rpub package`
29
+ Then a file named "untitled_book.zip" should exist
30
+ And the archive "untitled_book.zip" should contain file "README.md"
@@ -0,0 +1,66 @@
1
+ Feature: previews
2
+ As an author
3
+ I want to quickly see my words in an HTML file with the final formatting
4
+ So I can see how my work will look without having to use a special e-reader
5
+
6
+ Scenario: when there is no content
7
+ Given the default "config.yml" file
8
+ When I successfully run `rpub preview`
9
+ Then a file named "preview.html" should not exist
10
+
11
+ Scenario: concatenating content and styles
12
+ Given the default "config.yml" file
13
+ And a file named "chapter1.md" with:
14
+ """
15
+ Content 1
16
+ """
17
+ And a file named "chapter2.md" with:
18
+ """
19
+ Content 2
20
+ """
21
+ When I successfully run `rpub preview`
22
+ Then a file named "preview.html" should exist
23
+ And the file "preview.html" should contain:
24
+ """
25
+ <?xml version="1.0" encoding="UTF-8"?>
26
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
27
+ <html xmlns="http://www.w3.org/1999/xhtml">
28
+ """
29
+ And the file "preview.html" should contain "Content&nbsp;1"
30
+ And the file "preview.html" should contain "Content&nbsp;2"
31
+ And the file "preview.html" should contain:
32
+ """
33
+ body {
34
+ margin: 3%;
35
+ font-family: Georgia, serif;
36
+ line-height: 1.4em;
37
+ }
38
+ """
39
+
40
+ Scenario: given an explicit filename
41
+ Given the default "config.yml" file
42
+ And a file named "chapter1.md" with:
43
+ """
44
+ Content 1
45
+ """
46
+ When I successfully run `rpub preview -o output.html`
47
+ Then a file named "preview.html" should not exist
48
+ And a file named "output.html" should exist
49
+
50
+ Scenario: given an explicit layout
51
+ Given the default "config.yml" file
52
+ And a file named "chapter1.md" with:
53
+ """
54
+ Content 1
55
+ """
56
+ And a file named "layout.html" with:
57
+ """
58
+ Custom layout
59
+ <%= @body %>
60
+ """
61
+ When I successfully run `rpub preview -l layout.html`
62
+ Then the file "preview.html" should contain "Custom&nbsp;layout"
63
+
64
+ Scenario: getting help
65
+ When I successfully run `rpub preview -h`
66
+ Then the stdout should contain "Generate a single-page HTML file"
@@ -0,0 +1,18 @@
1
+ Feature: text statistics
2
+ As an author
3
+ I want to see some stats about my work
4
+ In order to get a sense of progress
5
+
6
+ Scenario: Lorem ipsum
7
+ Given the default "config.yml" file
8
+ And a file named "chapter1.md" with:
9
+ """
10
+ Lorem ipsum dolor sit amet"
11
+ """
12
+ When I successfully run `rpub stats`
13
+ Then the output should contain "5 words"
14
+ And the output should contain "1 pages"
15
+ And the output should contain "1 sentences"
16
+ And the output should contain "5.0 avg sentence length"
17
+ And the output should contain "ari"
18
+ And the output should contain "clf"
@@ -0,0 +1,60 @@
1
+ def read_support_file(filename)
2
+ File.read(File.join(SUPPORT_PATH, filename))
3
+ end
4
+
5
+ Given /^the default "(.*?)" file$/ do |filename|
6
+ write_file filename, read_support_file(filename)
7
+ end
8
+
9
+ Given /^the default "config.yml" file with "(.*?)" set to "(.*?)"$/ do |key, value|
10
+ config = YAML.load(read_support_file('config.yml'))
11
+ value = false if value == 'false'
12
+ value = value.to_i if value =~ /^\d+$/
13
+ config[key] = value
14
+ write_file 'config.yml', YAML.dump(config)
15
+ end
16
+
17
+ Given /^the default "config.yml" file with:$/ do |settings|
18
+ config = YAML.load(read_support_file('config.yml'))
19
+ config.merge! settings.rows_hash
20
+ write_file 'config.yml', YAML.dump(config)
21
+ end
22
+
23
+ Then /^the default file "(.*?)" should exist$/ do |filename|
24
+ step %Q{a file named "#{filename}" should exist}
25
+ step %Q{the file "#{filename}" should contain exactly:}, read_support_file(filename)
26
+ end
27
+
28
+ Then /^the archive "(.*?)" should contain file "(.*?)"$/ do |filename, entry|
29
+ in_current_dir do
30
+ Zip::File.open(filename, Zip::File::CREATE) do |zipfile|
31
+ zipfile.get_entry(entry)
32
+ end
33
+ end
34
+ end
35
+
36
+ Then /^the archive "(.*?)" should not contain file "(.*?)"$/ do |filename, entry|
37
+ in_current_dir do
38
+ Zip::File.open(filename, Zip::File::CREATE) do |zipfile|
39
+ expect(zipfile.find_entry(entry)).to be_nil
40
+ end
41
+ end
42
+ end
43
+
44
+ Given /^a basic project$/ do
45
+ steps %Q{
46
+ Given a file named "README.md" with:
47
+ """
48
+ README file
49
+ """
50
+ And the default "layout.html" file
51
+ And the default "styles.css" file
52
+ And the default "config.yml" file
53
+ And a file named "chapter1.md" with:
54
+ """
55
+ # Chapter 1
56
+
57
+ Hello, world
58
+ """
59
+ }
60
+ end
@@ -0,0 +1,33 @@
1
+ Feature: page layout
2
+ As an author
3
+ I want to format my text with CSS
4
+ In order to spice up my book's looks
5
+
6
+ Background:
7
+ Given a file named "chapter1.md" with:
8
+ """
9
+ Hello, world
10
+ """
11
+
12
+ Scenario: default styles
13
+ When I successfully run `rpub compile`
14
+ Then the archive "untitled-book-0.0.0.epub" should contain file "OEBPS/styles.css"
15
+
16
+ Scenario: overriding styles
17
+ Given a file named "styles.css" with:
18
+ """
19
+ foo bar
20
+ """
21
+ When I successfully run `rpub compile`
22
+ And I successfully run `unzip untitled-book-0.0.0.epub`
23
+ Then the file "OEBPS/styles.css" should contain "foo bar"
24
+
25
+ Scenario: custom styles
26
+ Given a file named "formatting.css" with:
27
+ """
28
+ foo bar
29
+ """
30
+ When I successfully run `rpub compile -s formatting.css`
31
+ And I successfully run `unzip untitled-book-0.0.0.epub`
32
+ Then the file "OEBPS/styles.css" should contain "foo bar"
33
+
@@ -0,0 +1,7 @@
1
+ require 'aruba/cucumber'
2
+ require 'zip'
3
+ SUPPORT_PATH = File.expand_path(File.join(*%w[.. .. .. support]), __FILE__)
4
+
5
+ Before do
6
+ @aruba_timeout_seconds = 5
7
+ end
@@ -0,0 +1,35 @@
1
+ Feature: automatic table of contents
2
+ As an author
3
+ I want to have my table of contents automatically generated
4
+ So I don't have to do it manually
5
+
6
+ Background:
7
+ Given a file named "chapter1.md" with:
8
+ """
9
+ # Chapter 1
10
+
11
+ ## Subheading
12
+
13
+ Lorem ipsum
14
+ """
15
+
16
+ Scenario: skipping human-readable table of contents
17
+ When I successfully run `rpub compile`
18
+ And I run `unzip untitled-book-0.0.0.epub`
19
+ Then a file named "OEBPS/toc.html" should exist
20
+ And the file "OEBPS/toc.html" should contain "Chapter 1"
21
+ And the file "OEBPS/toc.html" should contain "Subheading"
22
+
23
+ Scenario: human-readable table of contents
24
+ Given the default "config.yml" file with "toc" set to "false"
25
+ When I successfully run `rpub compile`
26
+ And I run `unzip untitled-book-0.0.0.epub`
27
+ Then the file "OEBPS/toc.html" should not exist
28
+
29
+ Scenario: custom table of contents depth
30
+ Given the default "config.yml" file with "max_level" set to "1"
31
+ When I successfully run `rpub compile`
32
+ And I run `unzip untitled-book-0.0.0.epub`
33
+ Then the file "OEBPS/toc.html" should contain "Chapter 1"
34
+ And the file "OEBPS/toc.html" should not contain "Subheading"
35
+
@@ -4,29 +4,45 @@ require 'yaml'
4
4
  require 'digest'
5
5
  require 'ostruct'
6
6
  require 'erb'
7
+ require 'forwardable'
7
8
 
8
9
  require 'builder'
9
10
  require 'kramdown'
10
- require 'zip/zip'
11
+ require 'zip'
11
12
  require 'nokogiri'
12
13
  require 'textstats'
13
14
  require 'typogruby'
14
15
 
16
+ module Rpub
17
+ GEM_ROOT = File.expand_path('../../', __FILE__)
18
+
19
+ # @return [String] full path to a file that was relative to the gem support directory
20
+ def self.support_file(path)
21
+ File.join(GEM_ROOT, 'support', path)
22
+ end
23
+
24
+ def self.source
25
+ FilesystemSource
26
+ end
27
+
28
+ def self.document_factory
29
+ Rpub::Document.method(:new)
30
+ end
31
+ end
32
+
15
33
  require 'rpub/version'
16
- require 'rpub/subclass_tracker'
17
- require 'rpub/commander'
18
- require 'rpub/compilation_helpers'
19
- require 'rpub/commands/base'
20
- require 'rpub/commands/main'
21
- require 'rpub/commands/compile'
34
+ require 'rpub/filesystem_source'
35
+ require 'rpub/context'
36
+ require 'rpub/command'
22
37
  require 'rpub/commands/clean'
23
- require 'rpub/commands/preview'
24
- require 'rpub/commands/package'
25
- require 'rpub/commands/help'
38
+ require 'rpub/commands/compile'
26
39
  require 'rpub/commands/generate'
40
+ require 'rpub/commands/package'
41
+ require 'rpub/commands/preview'
27
42
  require 'rpub/commands/stats'
28
43
  require 'rpub/hash_delegation'
29
44
  require 'rpub/book'
45
+ require 'rpub/preview'
30
46
  require 'rpub/chapter'
31
47
  require 'rpub/compressor'
32
48
  require 'rpub/epub'
@@ -36,24 +52,5 @@ require 'rpub/epub/toc'
36
52
  require 'rpub/epub/content'
37
53
  require 'rpub/epub/html_toc'
38
54
  require 'rpub/epub/cover'
39
-
40
- module Rpub
41
- GEM_ROOT = File.expand_path('../../', __FILE__)
42
-
43
- NoConfiguration = Class.new(StandardError)
44
-
45
- class InvalidSubcommand < StandardError
46
- def initialize(subcommand)
47
- super "Unknown subcommand: #{subcommand}"
48
- end
49
- end
50
-
51
- # @return [String] full path to a file that was relative to the gem support directory
52
- def self.support_file(path)
53
- File.join(GEM_ROOT, 'support', path)
54
- end
55
-
56
- KRAMDOWN_OPTIONS = {
57
- :coderay_line_numbers => nil
58
- }
59
- end
55
+ require 'rpub/media_type'
56
+ require 'rpub/document'
@@ -3,25 +3,18 @@ module Rpub
3
3
  # ordering, the book metadata from the configuration file and the book output
4
4
  # filename.
5
5
  class Book
6
+ extend Forwardable
6
7
  include Enumerable
7
- include HashDelegation
8
8
 
9
- delegate_to_hash :config
10
-
11
- # @return [Hash] The hash of configuration options read from the config.yml file.
12
- attr_reader :config
9
+ def_delegators :@context, :fonts, :config, :layout
13
10
 
14
11
  # @return [Array<Chapter>] List of chapters, one for every input markdown file.
15
12
  attr_reader :chapters
16
13
 
17
- # @return [Array<String>] all the fonts referred to in the stylesheet
18
- attr_reader :fonts
19
-
20
- # @return [String] the path the layout HTML file to use to wrap the chapter in.
21
- attr_reader :layout
22
-
23
- def initialize(layout, config = {}, fonts = [])
24
- @chapters, @config, @layout, @fonts = [], config, layout, fonts
14
+ def initialize(context)
15
+ @chapters = []
16
+ @context = context
17
+ @context.chapter_files.each(&method(:<<))
25
18
  end
26
19
 
27
20
  def each(&block)
@@ -33,11 +26,11 @@ module Rpub
33
26
  end
34
27
 
35
28
  def has_toc?
36
- !!config.fetch('toc') { false }
29
+ !!config.toc
37
30
  end
38
31
 
39
32
  def has_cover?
40
- !!config.fetch('cover_image') { false }
33
+ !!config.cover_image
41
34
  end
42
35
 
43
36
  def outline
@@ -71,7 +64,7 @@ module Rpub
71
64
  # @return [String] output filename for epub, based on the book title and
72
65
  # version number.
73
66
  def filename
74
- @filename ||= [config['title'], config['version']].join('-').gsub(/[^\w\.]/i, '-').squeeze('-').downcase.chomp('-') + '.epub'
67
+ @filename ||= [config.title, config.version].join('-').gsub(/[^\w\.]/i, '-').squeeze('-').downcase.chomp('-') + '.epub'
75
68
  end
76
69
  end
77
70
  end
@@ -4,6 +4,9 @@ module Rpub
4
4
  # suitable for writing to the epub archive with the appropriate identifiers
5
5
  # to be listed in the epub manifest files.
6
6
  class Chapter
7
+ extend Forwardable
8
+ def_delegators :@document, :images, :outline, :toc, :title, :to_html
9
+
7
10
  # @return [String] raw textual contents of this chapter
8
11
  attr_reader :content
9
12
 
@@ -15,12 +18,7 @@ module Rpub
15
18
 
16
19
  def initialize(content, number, layout)
17
20
  @content, @number, @layout = content, number, layout
18
- @document = Kramdown::Document.new(content, KRAMDOWN_OPTIONS.merge(:template => layout))
19
- end
20
-
21
- # @return [Kramdown::Element] Toc elements hierarchy
22
- def toc
23
- Kramdown::Converter::Toc.convert(@document.root).first
21
+ @document = Rpub.document_factory.call(content, layout)
24
22
  end
25
23
 
26
24
  # @return [String] Unique identifier for this chapter.
@@ -33,57 +31,9 @@ module Rpub
33
31
  @id ||= "chapter-#{number}"
34
32
  end
35
33
 
36
- # @return [String] content parsed to HTML by the markdown engine.
37
- def to_html
38
- @to_html ||= Typogruby.improve(@document.to_html)
39
- end
40
-
41
34
  # @return [String] name for the file in the zip to use, based on the title
42
35
  def filename
43
36
  @filename ||= xml_id.to_s + '-' + title.gsub(/[^\w\.]/i, '-').squeeze('-').downcase.chomp('-') + '.html'
44
37
  end
45
-
46
- # Ordered headers for this chapter, each header as an object responding
47
- # to #level and #text.
48
- #
49
- # @return [Array<#text,#level>] list of headers for this chapter
50
- def outline
51
- @outline ||= elements(:header).map do |element|
52
- OpenStruct.new({
53
- :level => element.options[:level],
54
- :text => element_text(element),
55
- :html_id => Kramdown::Converter::Html.send(:new, @document, { :auto_id_prefix => '' }).generate_id(element.options[:raw_text])
56
- })
57
- end
58
- end
59
-
60
- # @return [Array<String>] list of all image references
61
- def images
62
- @images ||= elements(:img).map { |e| e.attr['src'] }
63
- end
64
-
65
- # @return [String] Text of the first heading in this chapter
66
- def title
67
- @title ||= begin
68
- (heading = outline.first) ? heading.text : 'untitled'
69
- end
70
- end
71
-
72
- private
73
-
74
- def element_text(element)
75
- elements(:text, element).map { |e| e.value }.join
76
- end
77
-
78
- def elements(type, root = @document.root)
79
- collector = lambda do |element|
80
- element.children.select { |e|
81
- e.type == type
82
- } + element.children.map { |e|
83
- collector.call(e)
84
- }.flatten
85
- end
86
- collector.call(root)
87
- end
88
38
  end
89
39
  end