epuber 0.3.5

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 (206) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +46 -0
  5. data/bin/epuber +10 -0
  6. data/epuber.gemspec +51 -0
  7. data/lib/epuber.rb +14 -0
  8. data/lib/epuber/book.rb +267 -0
  9. data/lib/epuber/book/contributor.rb +90 -0
  10. data/lib/epuber/book/file_request.rb +68 -0
  11. data/lib/epuber/book/target.rb +284 -0
  12. data/lib/epuber/book/toc_item.rb +130 -0
  13. data/lib/epuber/checker.rb +19 -0
  14. data/lib/epuber/checker/text_checker.rb +129 -0
  15. data/lib/epuber/checker_transformer_base.rb +71 -0
  16. data/lib/epuber/command.rb +65 -0
  17. data/lib/epuber/command/compile.rb +142 -0
  18. data/lib/epuber/command/init.rb +145 -0
  19. data/lib/epuber/command/server.rb +59 -0
  20. data/lib/epuber/compiler.rb +255 -0
  21. data/lib/epuber/compiler/compilation_context.rb +86 -0
  22. data/lib/epuber/compiler/file_finders/abstract.rb +270 -0
  23. data/lib/epuber/compiler/file_finders/imaginary.rb +167 -0
  24. data/lib/epuber/compiler/file_finders/normal.rb +22 -0
  25. data/lib/epuber/compiler/file_resolver.rb +316 -0
  26. data/lib/epuber/compiler/file_types/abstract_file.rb +119 -0
  27. data/lib/epuber/compiler/file_types/bade_file.rb +39 -0
  28. data/lib/epuber/compiler/file_types/container_xml_file.rb +26 -0
  29. data/lib/epuber/compiler/file_types/generated_file.rb +29 -0
  30. data/lib/epuber/compiler/file_types/ibooks_display_options_file.rb +31 -0
  31. data/lib/epuber/compiler/file_types/image_file.rb +42 -0
  32. data/lib/epuber/compiler/file_types/mime_type_file.rb +20 -0
  33. data/lib/epuber/compiler/file_types/nav_file.rb +42 -0
  34. data/lib/epuber/compiler/file_types/opf_file.rb +27 -0
  35. data/lib/epuber/compiler/file_types/source_file.rb +52 -0
  36. data/lib/epuber/compiler/file_types/static_file.rb +18 -0
  37. data/lib/epuber/compiler/file_types/stylus_file.rb +20 -0
  38. data/lib/epuber/compiler/file_types/xhtml_file.rb +102 -0
  39. data/lib/epuber/compiler/generator.rb +67 -0
  40. data/lib/epuber/compiler/meta_inf_generator.rb +41 -0
  41. data/lib/epuber/compiler/nav_generator.rb +201 -0
  42. data/lib/epuber/compiler/opf_generator.rb +284 -0
  43. data/lib/epuber/compiler/xhtml_processor.rb +254 -0
  44. data/lib/epuber/config.rb +133 -0
  45. data/lib/epuber/dsl/attribute.rb +248 -0
  46. data/lib/epuber/dsl/attribute_support.rb +130 -0
  47. data/lib/epuber/dsl/object.rb +145 -0
  48. data/lib/epuber/dsl/tree_object.rb +101 -0
  49. data/lib/epuber/helper.rb +19 -0
  50. data/lib/epuber/lockfile.rb +55 -0
  51. data/lib/epuber/plugin.rb +108 -0
  52. data/lib/epuber/ruby_extensions/match_data.rb +40 -0
  53. data/lib/epuber/ruby_extensions/thread.rb +13 -0
  54. data/lib/epuber/server.rb +614 -0
  55. data/lib/epuber/server/auto_refresh/auto_refresh.coffee +97 -0
  56. data/lib/epuber/server/auto_refresh/connector.coffee +125 -0
  57. data/lib/epuber/server/auto_refresh/protocol.coffee +41 -0
  58. data/lib/epuber/server/auto_refresh/reloader.coffee +261 -0
  59. data/lib/epuber/server/base.styl +3 -0
  60. data/lib/epuber/server/basic.styl +211 -0
  61. data/lib/epuber/server/book_content.styl +39 -0
  62. data/lib/epuber/server/default_cover.png +0 -0
  63. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Bold.ttf +0 -0
  64. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-BoldItalic.ttf +0 -0
  65. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Italic.ttf +0 -0
  66. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Regular.ttf +0 -0
  67. data/lib/epuber/server/handlers.rb +67 -0
  68. data/lib/epuber/server/keyboard_control.coffee +6 -0
  69. data/lib/epuber/server/pages/book.bade +75 -0
  70. data/lib/epuber/server/pages/common.bade +59 -0
  71. data/lib/epuber/server/pages/files.bade +17 -0
  72. data/lib/epuber/server/pages/toc.bade +29 -0
  73. data/lib/epuber/server/support.coffee +10 -0
  74. data/lib/epuber/templates/template.bookspec +143 -0
  75. data/lib/epuber/third_party/bower.rb +22 -0
  76. data/lib/epuber/third_party/bower/bower.json +10 -0
  77. data/lib/epuber/third_party/bower/bower_components/cookies-js/bower.json +10 -0
  78. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.d.ts +33 -0
  79. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.js +173 -0
  80. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.min.js +6 -0
  81. data/lib/epuber/third_party/bower/bower_components/jquery/MIT-LICENSE.txt +21 -0
  82. data/lib/epuber/third_party/bower/bower_components/jquery/bower.json +28 -0
  83. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.js +9210 -0
  84. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.min.js +5 -0
  85. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.min.map +1 -0
  86. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax.js +786 -0
  87. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/jsonp.js +89 -0
  88. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/load.js +75 -0
  89. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  90. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/parseXML.js +28 -0
  91. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/script.js +64 -0
  92. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  93. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  94. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/xhr.js +136 -0
  95. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes.js +11 -0
  96. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/attr.js +141 -0
  97. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/classes.js +158 -0
  98. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/prop.js +94 -0
  99. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/support.js +35 -0
  100. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/val.js +161 -0
  101. data/lib/epuber/third_party/bower/bower_components/jquery/src/callbacks.js +205 -0
  102. data/lib/epuber/third_party/bower/bower_components/jquery/src/core.js +502 -0
  103. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/access.js +60 -0
  104. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/init.js +123 -0
  105. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/parseHTML.js +39 -0
  106. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/ready.js +97 -0
  107. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
  108. data/lib/epuber/third_party/bower/bower_components/jquery/src/css.js +450 -0
  109. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/addGetHookIf.js +22 -0
  110. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/curCSS.js +57 -0
  111. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/defaultDisplay.js +70 -0
  112. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  113. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/support.js +96 -0
  114. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/swap.js +28 -0
  115. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  116. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/getStyles.js +12 -0
  117. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/isHidden.js +13 -0
  118. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/rmargin.js +3 -0
  119. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  120. data/lib/epuber/third_party/bower/bower_components/jquery/src/data.js +178 -0
  121. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/Data.js +181 -0
  122. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/accepts.js +20 -0
  123. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/data_priv.js +5 -0
  124. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/data_user.js +5 -0
  125. data/lib/epuber/third_party/bower/bower_components/jquery/src/deferred.js +149 -0
  126. data/lib/epuber/third_party/bower/bower_components/jquery/src/deprecated.js +13 -0
  127. data/lib/epuber/third_party/bower/bower_components/jquery/src/dimensions.js +50 -0
  128. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects.js +648 -0
  129. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects/Tween.js +114 -0
  130. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  131. data/lib/epuber/third_party/bower/bower_components/jquery/src/event.js +868 -0
  132. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/ajax.js +13 -0
  133. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/alias.js +39 -0
  134. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/support.js +9 -0
  135. data/lib/epuber/third_party/bower/bower_components/jquery/src/exports/amd.js +24 -0
  136. data/lib/epuber/third_party/bower/bower_components/jquery/src/exports/global.js +32 -0
  137. data/lib/epuber/third_party/bower/bower_components/jquery/src/intro.js +44 -0
  138. data/lib/epuber/third_party/bower/bower_components/jquery/src/jquery.js +37 -0
  139. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation.js +580 -0
  140. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
  141. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/support.js +32 -0
  142. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  143. data/lib/epuber/third_party/bower/bower_components/jquery/src/offset.js +207 -0
  144. data/lib/epuber/third_party/bower/bower_components/jquery/src/outro.js +1 -0
  145. data/lib/epuber/third_party/bower/bower_components/jquery/src/queue.js +142 -0
  146. data/lib/epuber/third_party/bower/bower_components/jquery/src/queue/delay.js +22 -0
  147. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector-native.js +172 -0
  148. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector-sizzle.js +14 -0
  149. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector.js +1 -0
  150. data/lib/epuber/third_party/bower/bower_components/jquery/src/serialize.js +111 -0
  151. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.js +2067 -0
  152. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  153. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  154. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing.js +199 -0
  155. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/findFilter.js +100 -0
  156. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  157. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/arr.js +3 -0
  158. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/class2type.js +4 -0
  159. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/concat.js +5 -0
  160. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/hasOwn.js +5 -0
  161. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/indexOf.js +5 -0
  162. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/pnum.js +3 -0
  163. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/push.js +5 -0
  164. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/rnotwhite.js +3 -0
  165. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/slice.js +5 -0
  166. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/strundefined.js +3 -0
  167. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/support.js +4 -0
  168. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/toString.js +5 -0
  169. data/lib/epuber/third_party/bower/bower_components/jquery/src/wrap.js +79 -0
  170. data/lib/epuber/third_party/bower/bower_components/keymaster/MIT-LICENSE +20 -0
  171. data/lib/epuber/third_party/bower/bower_components/keymaster/Makefile +4 -0
  172. data/lib/epuber/third_party/bower/bower_components/keymaster/README.markdown +212 -0
  173. data/lib/epuber/third_party/bower/bower_components/keymaster/bower.json +27 -0
  174. data/lib/epuber/third_party/bower/bower_components/keymaster/keymaster.js +296 -0
  175. data/lib/epuber/third_party/bower/bower_components/keymaster/package.json +11 -0
  176. data/lib/epuber/third_party/bower/bower_components/keymaster/test.html +93 -0
  177. data/lib/epuber/third_party/bower/bower_components/spin.js/LICENSE.txt +21 -0
  178. data/lib/epuber/third_party/bower/bower_components/spin.js/README.md +21 -0
  179. data/lib/epuber/third_party/bower/bower_components/spin.js/bower.json +18 -0
  180. data/lib/epuber/third_party/bower/bower_components/spin.js/jquery.spin.js +80 -0
  181. data/lib/epuber/third_party/bower/bower_components/spin.js/spin.js +337 -0
  182. data/lib/epuber/third_party/bower/bower_components/uri.js/LICENSE.txt +21 -0
  183. data/lib/epuber/third_party/bower/bower_components/uri.js/README.md +534 -0
  184. data/lib/epuber/third_party/bower/bower_components/uri.js/bower.json +16 -0
  185. data/lib/epuber/third_party/bower/bower_components/uri.js/contributing.md +19 -0
  186. data/lib/epuber/third_party/bower/bower_components/uri.js/src/IPv6.js +188 -0
  187. data/lib/epuber/third_party/bower/bower_components/uri.js/src/SecondLevelDomains.js +241 -0
  188. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.fragmentQuery.js +104 -0
  189. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.fragmentURI.js +97 -0
  190. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.js +2115 -0
  191. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.min.js +86 -0
  192. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URITemplate.js +499 -0
  193. data/lib/epuber/third_party/bower/bower_components/uri.js/src/jquery.URI.js +235 -0
  194. data/lib/epuber/third_party/bower/bower_components/uri.js/src/jquery.URI.min.js +7 -0
  195. data/lib/epuber/third_party/bower/bower_components/uri.js/src/punycode.js +508 -0
  196. data/lib/epuber/transformer.rb +19 -0
  197. data/lib/epuber/transformer/text_transformer.rb +60 -0
  198. data/lib/epuber/user_interface.rb +186 -0
  199. data/lib/epuber/vendor/globals_context.rb +26 -0
  200. data/lib/epuber/vendor/hash_binding.rb +26 -0
  201. data/lib/epuber/vendor/nokogiri_extensions.rb +30 -0
  202. data/lib/epuber/vendor/ruby_templater.rb +71 -0
  203. data/lib/epuber/vendor/size.rb +20 -0
  204. data/lib/epuber/vendor/version.rb +83 -0
  205. data/lib/epuber/version.rb +4 -0
  206. metadata +556 -0
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'checker_transformer_base'
4
+
5
+
6
+ module Epuber
7
+ class Checker < CheckerTransformerBase
8
+ require_relative 'checker/text_checker'
9
+
10
+ # @return [Hash<Symbol, Class>]
11
+ #
12
+ def self.map_source_type__class
13
+ {
14
+ :result_text_xhtml_string => TextChecker,
15
+ :source_text_file => TextChecker,
16
+ }.merge(super)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,129 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_support/core_ext/string/access'
4
+
5
+ require_relative '../ruby_extensions/match_data'
6
+ require_relative '../checker'
7
+
8
+
9
+ module Epuber
10
+ class Checker
11
+ class TextChecker < Checker
12
+ class MatchProblem
13
+ # @param message [String]
14
+ # @param file_path [String]
15
+ # @param match [MatchData]
16
+ #
17
+ def initialize(match, message, file_path)
18
+ @match = match
19
+ @message = message
20
+ @file_path = file_path
21
+ end
22
+
23
+ # Formats caret symbol with space indent
24
+ #
25
+ # @param [Fixnum] indent
26
+ #
27
+ # @return [String]
28
+ #
29
+ def caret_symbol(indent)
30
+ ' ' * indent + '^'
31
+ end
32
+
33
+ # Formats caret symbols for indent and length
34
+ #
35
+ # @param [Fixnum] length
36
+ # @param [Fixnum] indent
37
+ #
38
+ # @return [String]
39
+ #
40
+ def caret_symbols(indent, length)
41
+ start_sign = caret_symbol(indent)
42
+ end_sign = if length > 1
43
+ caret_symbol(length-2)
44
+ else
45
+ ''
46
+ end
47
+
48
+ "#{start_sign}#{end_sign}"
49
+ end
50
+
51
+ def formatted_match_line
52
+ match_line = @match.matched_string
53
+ pre_line = @match.pre_match_lines.last || ''
54
+
55
+ pre = match_pre_line = pre_line
56
+ if remove_tabs(match_pre_line).length > 100
57
+ pre = "#{match_pre_line.first(20)}...#{match_pre_line.last(30)}"
58
+ end
59
+
60
+ pre = remove_tabs(pre)
61
+
62
+ post_line = @match.post_match_lines.first || ''
63
+
64
+ post = if post_line.length > 50
65
+ "#{post_line.first(50)}..."
66
+ else
67
+ post_line
68
+ end
69
+
70
+ [pre, match_line, post]
71
+ end
72
+
73
+ def remove_tabs(text)
74
+ text.gsub("\t", ' ' * 4)
75
+ end
76
+
77
+ def to_s
78
+ pre_original = @match.pre_match_lines.last || ''
79
+ pre, match_text, post = formatted_match_line
80
+
81
+ pointers = caret_symbols(pre.length, match_text.length)
82
+
83
+ %{#{@file_path}:#{@match.line_number} column: #{pre_original.length} --- #{@message}
84
+ #{pre + match_text.ansi.red + post}
85
+ #{pointers}}
86
+ end
87
+ end
88
+
89
+ # @return [String]
90
+ #
91
+ attr_accessor :text
92
+
93
+ # @return [String]
94
+ #
95
+ attr_accessor :file_path
96
+
97
+
98
+
99
+ # @param file_path [String]
100
+ # @param text [String]
101
+ # @param [CompilationContext] compilation_context
102
+ #
103
+ # @return nil
104
+ #
105
+ def call(file_path, text, compilation_context)
106
+ @file_path = file_path
107
+ @text = text
108
+
109
+ @block.call(self, text, compilation_context)
110
+
111
+ @text = nil
112
+ @file_path = nil
113
+ end
114
+
115
+ # @param regexp [Regexp]
116
+ # @param [String] message message to display, when the regexp found something
117
+ #
118
+ def should_not_contain(regexp, message)
119
+ # find all matches
120
+ # taken from http://stackoverflow.com/questions/6804557/how-do-i-get-the-match-data-for-all-occurrences-of-a-ruby-regular-expression-in
121
+ matches = text.to_enum(:scan, regexp).map { Regexp.last_match }
122
+ matches.each do |match|
123
+ # @type match [MatchData]
124
+ UI.print_processing_problem MatchProblem.new(match, message, Config.instance.pretty_path_from_project(file_path))
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,71 @@
1
+
2
+ module Epuber
3
+ class CheckerTransformerBase
4
+
5
+ # Type of source value for this checker, valid values are:
6
+ # :result_text_xhtml_string just before writing result xhtml to build folder
7
+ #
8
+ # @return [Symbol]
9
+ #
10
+ attr_reader :source_type
11
+
12
+ # List of options/flags passed in from plugin instance
13
+ #
14
+ # @return [Array<Symbol>]
15
+ #
16
+ attr_reader :options
17
+
18
+ # @return [Proc]
19
+ #
20
+ attr_reader :block
21
+
22
+
23
+ # @param [Symbol] type type of checker, see #type
24
+ # @param [Array<Symbol>] options list of other arguments, usually flags
25
+ #
26
+ def initialize(type, *options, &block)
27
+ @source_type = type
28
+ @block = block
29
+
30
+ valid_options_inst = valid_options
31
+ options.each do |opt|
32
+ raise "Unknown option #{opt.inspect}" unless valid_options_inst.include?(opt)
33
+ end
34
+ @options = options
35
+ end
36
+
37
+ # @return [Array<Symbol>]
38
+ #
39
+ def valid_options
40
+ [:run_only_before_release]
41
+ end
42
+
43
+
44
+
45
+ def call(*args)
46
+ raise NotImplementedError, 'You should override this method'
47
+ end
48
+
49
+
50
+
51
+ # ------------------------------------------------------------------ #
52
+ # @group Registration
53
+
54
+ # @return [Hash<Symbol, Class>]
55
+ #
56
+ def self.map_source_type__class
57
+ {}
58
+ end
59
+
60
+
61
+ # @param type [Symbol]
62
+ #
63
+ # @return [Class]
64
+ #
65
+ def self.class_for_source_type(type)
66
+ checker_class = self.map_source_type__class[type]
67
+ raise "#{self} class not found for type: #{type.inspect}" if checker_class.nil?
68
+ checker_class
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ require 'claide'
4
+
5
+ module Epuber
6
+ class PlainInformative < StandardError
7
+ include CLAide::InformativeError
8
+
9
+ def message
10
+ "[!] #{super}".ansi.red
11
+ end
12
+ end
13
+
14
+ class Command < CLAide::Command
15
+ require_relative 'command/compile'
16
+ require_relative 'command/init'
17
+ require_relative 'command/server'
18
+
19
+ self.abstract_command = true
20
+ self.command = 'epuber'
21
+ self.version = VERSION
22
+ self.description = 'Epuber, easy creating and maintaining e-book.'
23
+ self.plugin_prefixes = plugin_prefixes + %w(epuber)
24
+
25
+ def self.run(argv = [])
26
+ begin
27
+ UI.current_command = self
28
+ super
29
+ UI.current_command = nil
30
+
31
+ rescue => e
32
+ UI.error!(e)
33
+
34
+ UI.current_command = nil
35
+ end
36
+ end
37
+
38
+ def validate!
39
+ super
40
+ UI.current_command = self
41
+ end
42
+
43
+ def run
44
+ UI.current_command = self
45
+ end
46
+
47
+ protected
48
+
49
+ # @return [Epuber::Book::Book]
50
+ #
51
+ def book
52
+ Config.instance.bookspec
53
+ end
54
+
55
+ # @return [void]
56
+ #
57
+ # @raise PlainInformative if no .bookspec file don't exists or there are too many
58
+ #
59
+ def verify_one_bookspec_exists!
60
+ bookspec_files = Config.instance.find_all_bookspecs
61
+ raise PlainInformative, "No `.bookspec' found in the project directory." if bookspec_files.empty?
62
+ raise PlainInformative, "Multiple `.bookspec' found in current directory" if bookspec_files.count > 1
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,142 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'os'
5
+
6
+ require_relative '../command'
7
+
8
+
9
+ module Epuber
10
+ class Command
11
+ class Compile < Command
12
+ self.summary = 'Compile targets into multiple EPUB files.'
13
+ self.arguments = [
14
+ CLAide::Argument.new('TARGETS', false, true),
15
+ ]
16
+
17
+ def self.options
18
+ [
19
+ ['--check', 'Performs additional validation on sources + checks result epub with epubcheck.'],
20
+ ['--write', 'Performs additional transformations which writes to source files.'],
21
+ ['--release', 'Create release version of the book, no caching, everything creates from scratch.'],
22
+ ].concat(super)
23
+ end
24
+
25
+ # @param argv [CLAide::ARGV]
26
+ #
27
+ def initialize(argv)
28
+ @targets_names = argv.arguments!
29
+ @should_check = argv.flag?('check', false)
30
+ @should_write = argv.flag?('write', false)
31
+ @release_version = argv.flag?('release', false)
32
+
33
+ super(argv)
34
+ end
35
+
36
+ def validate!
37
+ super
38
+ verify_one_bookspec_exists!
39
+ verify_all_targets_exists!
40
+ end
41
+
42
+ def run
43
+ super
44
+
45
+ puts "compiling book `#{Config.instance.pretty_path_from_project(book.file_path)}`"
46
+
47
+ if @release_version
48
+ # Remove all previous versions of compiled files
49
+ targets.each do |target|
50
+ build_path = Epuber::Config.instance.release_build_path(target)
51
+
52
+ if ::File.directory?(build_path)
53
+ FileUtils.remove_dir(build_path, true)
54
+ end
55
+ end
56
+
57
+ # Build all targets to always clean directory
58
+ targets.each do |target|
59
+ compiler = Epuber::Compiler.new(book, target)
60
+ compiler.compile(Epuber::Config.instance.release_build_path(target), check: true, write: @should_write, release: true, verbose: verbose?)
61
+
62
+ archive_name = compiler.epub_name
63
+
64
+ if ::File.exists?(archive_name)
65
+ FileUtils.remove_file(archive_name)
66
+ end
67
+
68
+ archive_path = compiler.archive(archive_name)
69
+
70
+ system(%(epubcheck "#{archive_path}"))
71
+
72
+ convert_epub_to_mobi(archive_path, ::File.basename(archive_path, '.epub') + '.mobi') if target.create_mobi
73
+ end
74
+ else
75
+ targets.each do |target|
76
+ compiler = Epuber::Compiler.new(book, target)
77
+ compiler.compile(Epuber::Config.instance.build_path(target), check: @should_check, write: @should_write, verbose: verbose?)
78
+ archive_path = compiler.archive(configuration_suffix: 'debug')
79
+
80
+ system(%(epubcheck "#{archive_path}")) if @should_check
81
+
82
+ convert_epub_to_mobi(archive_path, ::File.basename(archive_path, '.epub') + '.mobi') if target.create_mobi
83
+ end
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ # @return [Array<Epuber::Book::Target>]
90
+ #
91
+ def targets
92
+ @targets ||= (
93
+ targets = @targets_names
94
+
95
+ # when the list of targets is nil pick all available targets
96
+ if targets.empty?
97
+ book.targets
98
+ else
99
+ targets.map { |target_name| book.target_named(target_name) }
100
+ end
101
+ )
102
+ end
103
+
104
+ def verify_all_targets_exists!
105
+ index = targets.index(&:nil?)
106
+ help! "Not found target `#{@targets_names[index]}' in bookspec `#{book.file_path}'" unless index.nil?
107
+ end
108
+
109
+ def validate_dir(path)
110
+ if ::File.directory?(path)
111
+ path
112
+ end
113
+ end
114
+
115
+ def find_calibre_app
116
+ locations = `mdfind "kMDItemCFBundleIdentifier == net.kovidgoyal.calibre"`.split("\n")
117
+ UI.error!("Can't find location of calibre.app to convert EPUB to MOBI.") if locations.empty?
118
+
119
+ selected = locations.first
120
+ UI.warn("Using calibre.app at location #{selected}") if locations.count > 1
121
+
122
+ selected
123
+ end
124
+
125
+ def find_calibre_convert_file
126
+ if OS.osx?
127
+ ::File.join(find_calibre_app, 'Contents/MacOS/ebook-convert')
128
+ elsif OS.linux?
129
+ script_path = '/usr/bin/ebook-convert'
130
+ UI.error!("Can't find ebook-convert in folder /usr/bin to convert EPUB to MOBI.") unless ::File.executable?(script_path)
131
+ script_path
132
+ else
133
+ UI.error!('Unsupported OS to convert EPUB to MOBI.')
134
+ end
135
+ end
136
+
137
+ def convert_epub_to_mobi(epub_path, mobi_path)
138
+ system(find_calibre_convert_file, epub_path, mobi_path)
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,145 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+
5
+ require_relative '../command'
6
+ require_relative '../vendor/ruby_templater'
7
+
8
+
9
+ module Epuber
10
+ class Command
11
+ class Init < Command
12
+ self.summary = 'Initialize current folder to use it as Epuber project'
13
+ self.arguments = [
14
+ CLAide::Argument.new('PROJECT_NAME', false, true),
15
+ ]
16
+
17
+ # @param argv [CLAide::ARGV]
18
+ #
19
+ def initialize(argv)
20
+ @book_name = argv.arguments!.first
21
+
22
+ super(argv)
23
+ end
24
+
25
+ def validate!
26
+ help! 'You must specify identifier-like name of the book as first argument' if @book_name.nil?
27
+
28
+ existing = Dir.glob('*.bookspec')
29
+ help! "Can't reinit this folder, #{existing.first} already exists." unless existing.empty?
30
+ end
31
+
32
+ def run
33
+ super
34
+
35
+ write_gitignore
36
+ write_bookspec(@book_name)
37
+ write_sublime_project(@book_name)
38
+
39
+ FileUtils.mkdir_p('images')
40
+ FileUtils.mkdir_p('fonts')
41
+ FileUtils.mkdir_p('styles')
42
+ write_default_style(@book_name)
43
+
44
+ FileUtils.mkdir_p('text')
45
+
46
+ print_good_bye(@book_name)
47
+ end
48
+
49
+
50
+ private
51
+
52
+ def print_good_bye(book_id)
53
+ puts <<-END.ansi.green
54
+ Project initialized, please review #{book_id}.bookspec file, remove comments.
55
+ END
56
+ end
57
+
58
+ # Creates <book-id>.bookspec file from template
59
+ #
60
+ # @param book_id [String]
61
+ #
62
+ # @return [void]
63
+ #
64
+ def write_bookspec(book_id)
65
+ template_path = File.expand_path(File.join('..', 'templates', 'template.bookspec'), File.dirname(__FILE__))
66
+ rendered = Epuber::RubyTemplater.from_file(template_path)
67
+ .with_locals(book_id: book_id)
68
+ .render
69
+
70
+ write("#{book_id}.bookspec", rendered)
71
+ end
72
+
73
+ # Creates <book-id>.sublime-project
74
+ #
75
+ # @param book_id [String]
76
+ #
77
+ # @return [void]
78
+ #
79
+ def write_sublime_project(book_id)
80
+ text = '{
81
+ "folders": [
82
+ {
83
+ "follow_symlinks": true,
84
+ "path": ".",
85
+ "folder_exclude_patterns": [".epuber"],
86
+ "file_exclude_patterns": ["*.epub"]
87
+ }
88
+ ]
89
+ }'
90
+
91
+ write("#{book_id}.sublime-project", text)
92
+ end
93
+
94
+ # Creates .gitignore file
95
+ #
96
+ # @return [void]
97
+ #
98
+ def write_gitignore
99
+ write('.gitignore', <<-END
100
+ # This is generated with `epuber init`
101
+ *.epub
102
+ *.mobi
103
+ !.epuber/
104
+ .epuber/build
105
+ .epuber/release_build
106
+
107
+ END
108
+ )
109
+ end
110
+
111
+ def write_default_style(book_id)
112
+ write("styles/#{book_id}.styl", <<-END
113
+ // This is generated with `epuber init` script.
114
+ END
115
+ )
116
+ end
117
+
118
+ # @param string [String] text to file
119
+ # @param file_path [String] path to file
120
+ #
121
+ # @return [void]
122
+ #
123
+ def write(file_path, string)
124
+ File.write(file_path, string)
125
+ end
126
+
127
+ # @param text [String]
128
+ #
129
+ # @return [String] returned text without new line
130
+ #
131
+ def ask(text)
132
+ print text
133
+ result = $stdin.gets.chomp
134
+
135
+ while result.empty?
136
+ puts 'Value cannot be empty, please fill it!'.ansi.red
137
+ print text
138
+ result = $stdin.gets.chomp
139
+ end
140
+
141
+ result
142
+ end
143
+ end
144
+ end
145
+ end