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
@@ -1,23 +0,0 @@
1
- module Rpub
2
- # The +Commander+ module is responsible for invoking `Command` objects. This is
3
- # the internal part of the library that is used by the CLI.
4
- #
5
- # The +Commander+ takes a list of arguments, which would typically come from the CLI,
6
- # and tries to look up a +Command+ class. If it cannot find anything, it will invoke
7
- # the {Rpub::Commands::Main} command.
8
- #
9
- # @see Rpub::Commands::Base
10
- # @see Rpub::Commands
11
- module Commander
12
- def invoke(args = [])
13
- subcommand, *options = args
14
- Commands::Base.matching(subcommand).new(options).invoke
15
- rescue SubclassTracker::NoSuchSubclass
16
- Commands::Main.new(args).invoke
17
- rescue NoConfiguration
18
- abort 'The current directory does not look like an rpub project.'
19
- end
20
-
21
- extend self
22
- end
23
- end
@@ -1,33 +0,0 @@
1
- module Rpub
2
- module Commands
3
- class Base
4
- extend SubclassTracker
5
-
6
- attr_reader :options
7
-
8
- def initialize(options = [], stdout = $stdout)
9
- @options, @stdout = options, stdout
10
- end
11
-
12
- def invoke
13
- parser.parse!(options)
14
- end
15
-
16
- def help
17
- puts parser
18
- end
19
-
20
- protected
21
-
22
- def parser
23
- OptionParser.new
24
- end
25
-
26
- private
27
-
28
- def puts(*args)
29
- @stdout.puts(*args)
30
- end
31
- end
32
- end
33
- end
@@ -1,37 +0,0 @@
1
- module Rpub
2
- module Commands
3
- class Help < Base
4
- identifier 'help'
5
-
6
- def invoke
7
- if options.empty?
8
- Main.new.invoke
9
- else
10
- Base.matching(options.shift).new.help
11
- end
12
- end
13
-
14
- private
15
-
16
- def parser
17
- OptionParser.new do |opts|
18
- opts.banner = <<-EOS
19
- Usage: rpub help subcommand
20
-
21
- Describe the usage and options for rpub subcommands.
22
-
23
- Options:
24
- EOS
25
- opts.separator ''
26
- opts.separator 'Generic options:'
27
- opts.separator ''
28
-
29
- opts.on_tail '-h', '--help', 'Display this message' do
30
- puts opts
31
- exit
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,45 +0,0 @@
1
- module Rpub
2
- module Commands
3
- class Main < Base
4
-
5
- def invoke
6
- options << '-h' if options.empty?
7
- super
8
- raise InvalidSubcommand, options[0] unless options.empty?
9
- end
10
-
11
- protected
12
-
13
- def parser
14
- OptionParser.new do |opts|
15
- opts.banner = <<-EOS
16
- Usage: rpub [subcommand] [options]
17
-
18
- Compile multiple Markdown-formatted input files into a machine-readable epub
19
- file for distribution as an ebook.
20
-
21
- Available subcommands:
22
-
23
- compile
24
- preview
25
- clean
26
- package
27
- help
28
- EOS
29
-
30
- opts.separator ''
31
- opts.separator 'Generic options:'
32
- opts.separator ''
33
-
34
- opts.on_tail '-v', '--version', 'Display version information' do
35
- puts "rpub #{Rpub::VERSION}"
36
- end
37
-
38
- opts.on_tail '-h', '--help', 'Display command reference' do
39
- puts opts
40
- end
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,73 +0,0 @@
1
- module Rpub
2
- # Provide a set of helper methods that are used across various commands to
3
- # simplify the compilation process. These methods mostly deal with loading files
4
- # from the current project directory.
5
- module CompilationHelpers
6
-
7
- def concatenated_document
8
- Kramdown::Document.new(
9
- markdown_files.join("\n"),
10
- KRAMDOWN_OPTIONS.merge(:template => layout)
11
- )
12
- end
13
-
14
- # Factory method for {Rpub::Book} objects, loading every markdown file as a
15
- # chapter.
16
- #
17
- # @see #markdown_files
18
- # @return [Rpub::Book]
19
- def create_book
20
- book = Book.new(layout, config, fonts)
21
- markdown_files.each(&book.method(:<<))
22
- book
23
- end
24
-
25
- # All chapter input files loaded into strings. This does not include any of
26
- # the files listed in the +ignore+ configuration key.
27
- #
28
- # @return [Array<String>]
29
- def markdown_files
30
- @markdown_files ||= filter_exceptions(Dir['*.md']).sort.map(&File.method(:read))
31
- end
32
-
33
- # @return [String] path to the current layout file (defaulting to built-in)
34
- def layout
35
- @layout ||= own_or_support_file('layout.html')
36
- end
37
-
38
- # @return [String] path to the current stylesheet file (defaulting to built-in)
39
- def styles
40
- @styles ||= own_or_support_file('styles.css')
41
- end
42
-
43
- # Load the contents of +config.yml+ into a +Hash+ object.
44
- #
45
- # @raise [NoConfiguration] when the config file cannot be found.
46
- # @return [Hash] parsed configuration
47
- def config
48
- @config_file ||= begin
49
- raise NoConfiguration unless File.exist?('config.yml')
50
- YAML.load_file('config.yml') || {}
51
- end
52
- end
53
-
54
- private
55
-
56
- def fonts
57
- @fonts ||= File.read(styles).scan(/url\((?:'|")?([^'")]+\.otf)(?:'|")?\)/i).flatten
58
- end
59
-
60
- def filter_exceptions(filenames)
61
- return filenames unless config.has_key?('ignore')
62
- filenames.reject(&config['ignore'].method(:include?))
63
- end
64
-
65
- def own_or_support_file(filename)
66
- if File.exists?(filename)
67
- filename
68
- else
69
- Rpub.support_file(filename)
70
- end
71
- end
72
- end
73
- end
@@ -1,53 +0,0 @@
1
- module Rpub
2
- # Add tracking of subclasses to an existing class by extending it with
3
- # SubclassTracker.
4
- #
5
- # This allows you to set an identifier in a subclass using the +identifier+
6
- # macro, and find subclasses based on that value.
7
- #
8
- # Example:
9
- #
10
- # class ParentClass
11
- # extend SubclassTracker
12
- # end
13
- #
14
- # class ChildClass < ParentClass
15
- # identifier 'foo'
16
- # end
17
- #
18
- # ParentClass.matching('foo') # => ChildClass
19
- # ParentClass.matching('bar') # => raises SubclassTracker::NoSuchSubclass
20
- #
21
- # Note that you don't HAVE to set an identifier. If you don't, your child
22
- # class will never be found by +#matching+.
23
- module SubclassTracker
24
- class NoSuchSubclass < StandardError
25
- def initialize(subcommand)
26
- super "Unrecognized identifier: #{subcommand}"
27
- end
28
- end
29
-
30
- # Set or return the identifier for this class.
31
- def identifier(id = nil)
32
- return @identifier if id.nil?
33
- @identifier = id
34
- end
35
-
36
- def inherited(child)
37
- @subclasses ||= []
38
- @subclasses << child
39
- super
40
- end
41
-
42
- def each
43
- @subclasses ||= []
44
- @subclasses.each { |subclass| yield subclass }
45
- end
46
-
47
- def matching(identifier)
48
- find { |subclass| subclass.identifier === identifier } or raise NoSuchSubclass, identifier
49
- end
50
-
51
- include Enumerable
52
- end
53
- end
@@ -1,46 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rpub::Commands::Clean do
4
- before do
5
- Dir.chdir File.join(FIXTURES_DIRECTORY, 'clean')
6
- end
7
-
8
- after do
9
- FileUtils.touch 'preview.html'
10
- FileUtils.touch 'example.epub'
11
- end
12
-
13
- it 'should remove example.epub file' do
14
- expect {
15
- described_class.new.invoke
16
- }.to remove_file('example.epub')
17
- end
18
-
19
- it 'should remove preview.html file' do
20
- expect {
21
- described_class.new.invoke
22
- }.to remove_file('preview.html')
23
- end
24
-
25
- context 'when in dry run mode' do
26
- let(:buffer) { StringIO.new }
27
- let(:subject) { described_class.new(['-d'], buffer) }
28
-
29
- it 'should print preview.html' do
30
- subject.invoke
31
- buffer.string.should include('preview.html')
32
- end
33
-
34
- it 'should not print non-existant files' do
35
- FileUtils.rm 'preview.html'
36
- subject.invoke
37
- buffer.string.should_not include('preview.html')
38
- end
39
-
40
- it 'should not remove existing files' do
41
- expect {
42
- subject.invoke
43
- }.to_not remove_file('preview.html')
44
- end
45
- end
46
- end
@@ -1,52 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rpub::Commands::Generate do
4
- let(:buffer) { StringIO.new }
5
- before do
6
- Dir.chdir File.join(FIXTURES_DIRECTORY, 'generate')
7
- end
8
-
9
- after do
10
- File.unlink 'styles.css' if File.exist?('styles.css')
11
- File.unlink 'layout.html' if File.exist?('layout.html')
12
- File.unlink 'config.yml' if File.exist?('config.yml')
13
- end
14
-
15
- context 'given a specific option' do
16
- let(:subject) { described_class.new(['--config'], buffer) }
17
-
18
- it 'should generate one file' do
19
- expect(&subject.method(:invoke)).to create_file('config.yml')
20
- end
21
-
22
- it 'should not generate stylesheet' do
23
- expect(&subject.method(:invoke)).to_not create_file('layout.html', 'styles.css')
24
- end
25
- end
26
-
27
- context 'given a no option' do
28
- let(:subject) { described_class.new(['--no-styles'], buffer) }
29
-
30
- it 'should generate two files' do
31
- expect(&subject.method(:invoke)).to create_file('layout.html', 'config.yml')
32
- end
33
-
34
- it 'should not generate stylesheet' do
35
- expect(&subject.method(:invoke)).to_not create_file('styles.css')
36
- end
37
- end
38
-
39
- context 'given no options' do
40
- let(:subject) { described_class.new([], buffer) }
41
-
42
- it 'should generate three files' do
43
- expect(&subject.method(:invoke)).to create_file('styles.css', 'layout.html', 'config.yml')
44
- end
45
-
46
- it 'should not generate existing files' do
47
- File.open('styles.css', 'w') { |f| f.write 'foo' }
48
- expect(&subject.method(:invoke)).to_not change { File.read('styles.css') }
49
- buffer.string.should include('Not overriding styles.css')
50
- end
51
- end
52
- end
@@ -1,26 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rpub::Commands::Main do
4
- let(:buffer) { StringIO.new }
5
-
6
- it 'should default to help text' do
7
- described_class.new([], buffer).invoke
8
- buffer.string.should =~ /Display command reference/
9
- end
10
-
11
- it 'should raise error when a subcommand remains' do
12
- expect {
13
- described_class.new(['foo'], buffer).invoke
14
- }.should raise_error(Rpub::InvalidSubcommand)
15
- end
16
-
17
- it 'should print the version number' do
18
- described_class.new(['-v'], buffer).invoke
19
- buffer.string.should =~ /rpub \d+\.\d+\.\d+/
20
- end
21
-
22
- it 'should print help text' do
23
- described_class.new(['-h'], buffer).invoke
24
- buffer.string.should =~ /Display command reference/
25
- end
26
- end
@@ -1,33 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rpub::Commands::Package do
4
- before do
5
- Dir.chdir File.join(FIXTURES_DIRECTORY, 'package')
6
- end
7
-
8
- after do
9
- File.unlink('package.zip') if File.exist?('package.zip')
10
- File.unlink('untitled-book-0.0.0.epub') if File.exist?('untitled-book-0.0.0.epub')
11
- end
12
-
13
- it 'should generate an archive' do
14
- expect(&subject.method(:invoke)).to create_file('package.zip')
15
- end
16
-
17
- context 'archive file' do
18
- before { described_class.new.invoke }
19
-
20
- let(:subject) do
21
- [].tap do |files|
22
- Zip::ZipInputStream.open('package.zip') do |io|
23
- while entry = io.get_next_entry
24
- files << entry.name
25
- end
26
- end
27
- end
28
- end
29
-
30
- it { should include('README.md') }
31
- it { should include('untitled-book-0.0.0.epub') }
32
- end
33
- end
@@ -1,43 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Rpub::Commands::Preview do
4
- before do
5
- Dir.chdir File.join(FIXTURES_DIRECTORY, 'preview')
6
- end
7
-
8
- after do
9
- File.unlink 'preview.html' if File.exist?('preview.html')
10
- File.unlink 'foo.bar' if File.exist?('foo.bar')
11
- end
12
-
13
- context 'generated content' do
14
- before { Rpub::Commands::Preview.new.invoke }
15
- let(:subject) { File.read('preview.html') }
16
-
17
- it { should include('<p>foo</p>') }
18
- it { should include('<p>bar</p>') }
19
- it { should match(/foo.*bar/m) }
20
- it { should match(/<head>/) }
21
- it { should match(/<style>/) }
22
- end
23
-
24
- it 'should create new preview file' do
25
- expect {
26
- Rpub::Commands::Preview.new.invoke
27
- }.to create_file('preview.html')
28
- end
29
-
30
- it 'should do nothing when there are no files to preview' do
31
- Dir.chdir File.join(FIXTURES_DIRECTORY, 'no_files')
32
- expect {
33
- Rpub::Commands::Preview.new.invoke
34
- }.to_not create_file('preview.html')
35
- end
36
-
37
- it 'should allow overriding the filename' do
38
- expect {
39
- Rpub::Commands::Preview.new(['-o', 'foo.bar']).invoke
40
- }.to create_file('foo.bar')
41
- end
42
-
43
- end