rpub 0.4.0 → 0.5.0

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.
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,32 @@
1
+ module Rpub
2
+ class Command
3
+ attr_reader :args, :options
4
+
5
+ def initialize(args, options)
6
+ @args, @options = args, options
7
+ run
8
+ end
9
+
10
+ protected
11
+
12
+ def run
13
+ raise 'Must be implemented by subclass'
14
+ end
15
+
16
+ def book
17
+ @book ||= Book.new(context)
18
+ end
19
+
20
+ def context
21
+ @context ||= Context.new({
22
+ :layout => options.layout,
23
+ :styles => options.styles,
24
+ :config => options.config
25
+ })
26
+ end
27
+
28
+ def source
29
+ @source ||= Rpub.source
30
+ end
31
+ end
32
+ end
@@ -1,54 +1,9 @@
1
1
  module Rpub
2
2
  module Commands
3
- class Clean < Base
4
- include CompilationHelpers
5
-
6
- identifier 'clean'
7
-
8
- def invoke
9
- super
10
- remove create_book.filename
11
- remove 'preview.html'
12
- end
13
-
14
- private
15
-
16
- def parser
17
- OptionParser.new do |opts|
18
- opts.banner = <<-EOS
19
- Usage: rpub clean [-d]'
20
-
21
- Clean up all generated files, such as the standard generated .epub
22
- file, package files and preview files.
23
-
24
- Options:
25
- EOS
26
-
27
- opts.separator ''
28
-
29
- opts.on '-d', '--dry-run', 'Dry-run: only list files to be removed' do
30
- @dry_run = true
31
- end
32
-
33
- opts.separator ''
34
- opts.separator 'Generic options:'
35
- opts.separator ''
36
-
37
- opts.on_tail '-h', '--help', 'Display this message' do
38
- puts opts
39
- exit
40
- end
41
- end
42
- end
43
-
44
- def remove(filename)
45
- if File.exist?(filename)
46
- unless @dry_run
47
- File.unlink(filename)
48
- else
49
- puts filename
50
- end
51
- end
3
+ class Clean < Command
4
+ def run
5
+ source.remove book.filename, options.dryrun
6
+ source.remove 'preview.html', options.dryrun
52
7
  end
53
8
  end
54
9
  end
@@ -1,54 +1,9 @@
1
1
  module Rpub
2
2
  module Commands
3
- class Compile < Base
4
- include CompilationHelpers
5
-
6
- identifier 'compile'
7
-
8
- def invoke
9
- super
10
- book = create_book
11
- Compressor.open(book.filename) do |zip|
12
- Epub.new(book, File.read(styles)).manifest_in(zip)
13
- end
14
- end
15
-
16
- private
17
-
18
- def parser
19
- OptionParser.new do |opts|
20
- opts.banner = <<-EOS
21
- Usage: rpub compile [options]
22
-
23
- Compile your Markdown-formatted input files to a valid .epub output
24
- file using the options described in config.yml. This will use the
25
- layout.html and styles.css files in your project directory if
26
- present.
27
-
28
- Options:
29
- EOS
30
- opts.separator ''
31
-
32
- opts.on '-l', '--layout FILENAME', 'Specify an explicit layout file to use' do |filename|
33
- @layout = filename
34
- end
35
-
36
- opts.on '-s', '--styles FILENAME', 'Specify an explicit stylesheet file to use' do |filename|
37
- @styles = filename
38
- end
39
-
40
- opts.on '-c', '--config FILENAME', 'Specify an explicit configuration file to use' do |filename|
41
- @config_file = filename
42
- end
43
-
44
- opts.separator ''
45
- opts.separator 'Generic options:'
46
- opts.separator ''
47
-
48
- opts.on_tail '-h', '--help', 'Display this message' do
49
- puts opts
50
- exit
51
- end
3
+ class Compile < Command
4
+ def run
5
+ Rpub::Compressor.open(book.filename) do |zip|
6
+ Rpub::Epub.new(book, source.read(context.styles)).manifest_in(zip)
52
7
  end
53
8
  end
54
9
  end
@@ -1,78 +1,21 @@
1
1
  module Rpub
2
2
  module Commands
3
- class Generate < Base
4
- identifier 'generate'
5
-
6
- def initialize(*args)
7
- super
8
- @all = true
9
- end
10
-
11
- def invoke
12
- super
13
-
14
- if (@styles.nil? && @all) || (!@styles.nil? && @styles)
15
- write_file Rpub.support_file('styles.css')
3
+ class Generate < Command
4
+ def run
5
+ all = [options.styles, options.layout, options.config].all? do |b|
6
+ b.nil? || b == false
16
7
  end
17
8
 
18
- if (@layout.nil? && @all) || (!@layout.nil? && @layout)
19
- write_file Rpub.support_file('layout.html')
9
+ if (options.styles.nil? && all) || (!options.styles.nil? && options.styles)
10
+ source.write 'styles.css', source.read(Rpub.support_file('styles.css'))
20
11
  end
21
12
 
22
- if (@config.nil? && @all) || (!@config.nil? && @config)
23
- write_file Rpub.support_file('config.yml')
24
- end
25
- end
26
-
27
- private
28
-
29
- def write_file(file)
30
- output_file = File.basename(file)
31
- if File.exist?(output_file)
32
- puts "Not overriding #{output_file}"
33
- return
34
- end
35
- File.open(output_file, 'w') do |f|
36
- f.write File.read(file)
13
+ if (options.layout.nil? && all) || (!options.layout.nil? && options.layout)
14
+ source.write 'layout.html', source.read(Rpub.support_file('layout.html'))
37
15
  end
38
- end
39
-
40
- def parser
41
- OptionParser.new do |opts|
42
- opts.banner = <<-EOS
43
- Usage: rpub generate [-slach]
44
-
45
- Generate one or more standard files to get started with a new project. By
46
- default an entire skeleton project is generated, but by passing the -s, -l, -c
47
- options you can generate just a single file.
48
-
49
- Options:
50
- EOS
51
- opts.separator ' '
52
-
53
- opts.on '-s', '--[no-]styles', 'Generate default stylesheet' do |v|
54
- @all = false if v
55
- @styles = v
56
- end
57
-
58
- opts.on '-l', '--[no-]layout', 'Generate default HTML layout' do |v|
59
- @all = false if v
60
- @layout = v
61
- end
62
-
63
- opts.on '-c', '--[no-]config', 'Generate default configuration' do |v|
64
- @all = false if v
65
- @config = v
66
- end
67
-
68
- opts.separator ''
69
- opts.separator 'Generic options:'
70
- opts.separator ''
71
16
 
72
- opts.on_tail '-h', '--help', 'Display this message' do
73
- puts opts
74
- exit
75
- end
17
+ if (options.config.nil? && all) || (!options.config.nil? && options.config)
18
+ source.write 'config.yml', source.read(Rpub.support_file('config.yml'))
76
19
  end
77
20
  end
78
21
  end
@@ -1,42 +1,14 @@
1
1
  module Rpub
2
2
  module Commands
3
- class Package < Base
4
- include CompilationHelpers
5
-
6
- identifier 'package'
7
-
8
- def invoke
9
- super
10
- Compile.new(options).invoke
11
- return unless config.has_key?('package_file')
12
- Compressor.open(config.fetch('package_file')) do |zip|
13
- zip.store_file create_book.filename, File.read(create_book.filename)
14
- config.fetch('package') { [] }.each do |file|
15
- zip.compress_file file, File.read(file)
16
- end
17
- end
18
- end
19
-
20
- private
21
-
22
- def parser
23
- OptionParser.new do |opts|
24
- opts.banner = <<-EOS
25
- Usage: rpub package
26
-
27
- Compile your ebook to an ePub file and package it into an archive together with
28
- optional other files for easy distibution. You might want to include a README
29
- file, a license or other promotion material.
30
-
31
- Options:
32
- EOS
33
- opts.separator ''
34
- opts.separator 'Generic options:'
35
- opts.separator ''
36
-
37
- opts.on_tail '-h', '--help', 'Display this message' do
38
- puts opts
39
- exit
3
+ class Package < Command
4
+ def run
5
+ Compile.new(args, options)
6
+ if context.config.package_file
7
+ Rpub::Compressor.open(context.config.package_file) do |zip|
8
+ zip.store_file book.filename, source.read(book.filename)
9
+ Array(context.config.package).each do |file|
10
+ zip.compress_file file, source.read(file)
11
+ end
40
12
  end
41
13
  end
42
14
  end
@@ -1,59 +1,9 @@
1
1
  module Rpub
2
2
  module Commands
3
- class Preview < Base
4
- include CompilationHelpers
5
-
6
- identifier 'preview'
7
-
8
- def initialize(*args)
9
- super
10
- @filename = 'preview.html'
11
- end
12
-
13
- def invoke
14
- super
15
- return unless markdown_files.any?
16
- File.open(@filename, 'w') do |f|
17
- f.write move_styles_inline(Typogruby.improve(concatenated_document.to_html))
18
- end
19
- end
20
-
21
- private
22
-
23
- def move_styles_inline(html)
24
- style_block = %Q{<style>\n#{File.read(styles)}\n</style>}
25
- html.gsub %r{</head>}, style_block + "\n</head>"
26
- end
27
-
28
- def parser
29
- OptionParser.new do |opts|
30
- opts.banner = <<-EOS
31
- Usage: rpub preview [options]
32
-
33
- Generate a single-page HTML file for easy previewing of your content with the
34
- layout and styles used when generating .epub files. By default, the output
35
- file will be named "preview.html".
36
-
37
- Options:
38
- EOS
39
- opts.separator ''
40
- opts.on '-l', '--layout FILENAME', 'Specify an explicit layout file to use' do |filename|
41
- @layout = filename
42
- end
43
-
44
- opts.on '-o', '--output FILENAME', 'Specify an explicit output file' do |filename|
45
- @filename = filename
46
- end
47
-
48
- opts.separator ''
49
- opts.separator 'Generic options:'
50
- opts.separator ''
51
-
52
- opts.on_tail '-h', '--help', 'Display this message' do
53
- puts opts
54
- exit
55
- end
56
- end
3
+ class Preview < Command
4
+ def run
5
+ options.default :output => 'preview.html'
6
+ source.force_write options.output, Rpub::Preview.new(context, source).formatted
57
7
  end
58
8
  end
59
9
  end
@@ -1,18 +1,14 @@
1
1
  module Rpub
2
2
  module Commands
3
- class Stats < Base
4
- identifier 'stats'
5
- include CompilationHelpers
6
-
7
- def invoke
8
- super
9
- text = Nokogiri::HTML(concatenated_document.to_html).xpath('//text()').to_s
3
+ class Stats < Command
4
+ def run
5
+ text = Rpub::Preview.new(context, source).text
10
6
  puts "#{text.words.size} words"
11
- puts "#{text.words.size / 500} pages"
7
+ puts "#{(text.words.size.to_f / 500).ceil} pages"
12
8
  puts "#{text.sentences} sentences"
13
9
  puts "#{text.avg_sentence_length} avg sentence length"
14
- puts "#{text.ari} ari"
15
- puts "#{text.clf} clf"
10
+ puts format("%.2f ari", text.ari)
11
+ puts format("%.2f clf", text.clf)
16
12
  end
17
13
  end
18
14
  end
@@ -17,7 +17,7 @@ module Rpub
17
17
 
18
18
  # @param [String] filename of the archive to write to disk
19
19
  def initialize(filename)
20
- @zip = Zip::ZipOutputStream.new(filename)
20
+ @zip = Zip::OutputStream.new(filename)
21
21
  end
22
22
 
23
23
  # Close the zip stream and write the file to disk.
@@ -30,7 +30,7 @@ module Rpub
30
30
  # @param [String] filename under the which the data should be stored
31
31
  # @param [#to_s] content to be compressed
32
32
  def store_file(filename, content)
33
- zip.put_next_entry filename, nil, nil, Zip::ZipEntry::STORED, Zlib::NO_COMPRESSION
33
+ zip.put_next_entry filename, nil, nil, Zip::Entry::STORED, Zlib::NO_COMPRESSION
34
34
  zip.write content.to_s
35
35
  end
36
36
 
@@ -39,7 +39,7 @@ module Rpub
39
39
  # @param [String] filename under the which the data should be stored
40
40
  # @param [#to_s] content to be compressed
41
41
  def compress_file(filename, content)
42
- zip.put_next_entry filename, nil, nil, Zip::ZipEntry::DEFLATED, Zlib::BEST_COMPRESSION
42
+ zip.put_next_entry filename, nil, nil, Zip::Entry::DEFLATED, Zlib::BEST_COMPRESSION
43
43
  zip.write content.to_s
44
44
  end
45
45
  end
@@ -0,0 +1,48 @@
1
+ module Rpub
2
+ class Context
3
+ include Rpub.source
4
+
5
+ def initialize(options = {})
6
+ @config_file = options[:config]
7
+ @layout = options[:layout]
8
+ @styles = options[:styles]
9
+ end
10
+
11
+ def config
12
+ @config ||= OpenStruct.new(YAML.load_file(config_file) || {})
13
+ end
14
+
15
+ # @return [String] path to the current layout file (defaulting to built-in)
16
+ def layout
17
+ @layout ||= own_or_support_file('layout.html')
18
+ end
19
+
20
+ # @return [String] path to the current stylesheet file (defaulting to built-in)
21
+ def styles
22
+ @styles ||= own_or_support_file('styles.css')
23
+ end
24
+
25
+ def fonts
26
+ @fonts ||= read(styles).scan(/url\((?:'|")?([^'")]+\.[ot]tf)(?:'|")?\)/i).flatten
27
+ end
28
+
29
+ # All chapter input files loaded into strings. This does not include any of
30
+ # the files listed in the +ignore+ configuration key.
31
+ #
32
+ # @return [Array<String>]
33
+ def chapter_files
34
+ @chapter_files ||= filter_exceptions(source_files).sort.map(&method(:read))
35
+ end
36
+
37
+ private
38
+
39
+ def config_file
40
+ @config_file ||= own_or_support_file('config.yml')
41
+ end
42
+
43
+ def filter_exceptions(filenames)
44
+ return filenames unless config.ignore
45
+ filenames.reject(&config.ignore.method(:include?))
46
+ end
47
+ end
48
+ end