review 1.0.0 → 1.1.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 (100) hide show
  1. data/.travis.yml +1 -2
  2. data/ChangeLog +65 -0
  3. data/Gemfile +5 -0
  4. data/README.rdoc +6 -1
  5. data/Rakefile +14 -28
  6. data/bin/review-check +9 -21
  7. data/bin/review-compile +45 -12
  8. data/bin/review-epubmaker +477 -220
  9. data/bin/review-epubmaker-ng +5 -14
  10. data/bin/review-index +4 -2
  11. data/bin/review-init +94 -0
  12. data/bin/review-pdfmaker +70 -287
  13. data/bin/review-preproc +5 -2
  14. data/bin/review-vol +4 -11
  15. data/debian/changelog +3 -3
  16. data/debian/copyright +5 -3
  17. data/debian/docs +1 -0
  18. data/doc/format.rdoc +57 -11
  19. data/doc/quickstart.rdoc +4 -4
  20. data/doc/sample.yaml +11 -7
  21. data/lib/epubmaker.rb +1 -1
  22. data/lib/epubmaker/epubv2.rb +26 -27
  23. data/lib/epubmaker/epubv3.rb +13 -13
  24. data/lib/epubmaker/producer.rb +1 -1
  25. data/lib/review.rb +3 -4
  26. data/lib/review/book.rb +17 -581
  27. data/lib/review/book/base.rb +247 -0
  28. data/lib/review/book/chapter.rb +81 -0
  29. data/lib/review/book/compilable.rb +163 -0
  30. data/lib/review/book/index.rb +339 -0
  31. data/lib/review/book/page_metric.rb +38 -0
  32. data/lib/review/book/parameters.rb +97 -0
  33. data/lib/review/book/part.rb +44 -0
  34. data/lib/review/book/volume.rb +65 -0
  35. data/lib/review/builder.rb +34 -40
  36. data/lib/review/compiler.rb +32 -13
  37. data/lib/review/configure.rb +38 -0
  38. data/lib/review/ewbbuilder.rb +23 -21
  39. data/lib/review/extentions.rb +3 -0
  40. data/lib/review/extentions/object.rb +9 -0
  41. data/lib/review/{compat.rb → extentions/string.rb} +11 -0
  42. data/lib/review/htmlbuilder.rb +162 -74
  43. data/lib/review/htmlutils.rb +28 -1
  44. data/lib/review/i18n.yaml +11 -0
  45. data/lib/review/idgxmlbuilder.rb +119 -35
  46. data/lib/review/inaobuilder.rb +355 -0
  47. data/lib/review/latexbuilder.rb +133 -59
  48. data/lib/review/latexutils.rb +15 -6
  49. data/lib/review/makerhelper.rb +59 -0
  50. data/lib/review/markdownbuilder.rb +129 -0
  51. data/lib/review/preprocessor.rb +20 -7
  52. data/lib/review/review.tex.erb +250 -0
  53. data/lib/review/textutils.rb +28 -3
  54. data/lib/review/tocparser.rb +20 -12
  55. data/lib/review/tocprinter.rb +7 -3
  56. data/lib/review/topbuilder.rb +44 -27
  57. data/lib/review/version.rb +3 -0
  58. data/review.gemspec +20 -117
  59. data/test/book_test_helper.rb +35 -0
  60. data/test/sample-book/README.md +5 -0
  61. data/test/sample-book/src/CHAPS +2 -0
  62. data/test/sample-book/src/PREDEF +1 -0
  63. data/test/sample-book/src/Rakefile +26 -0
  64. data/test/sample-book/src/_cover.html +3 -0
  65. data/test/sample-book/src/ch01.re +71 -0
  66. data/test/sample-book/src/ch02.re +3 -0
  67. data/test/sample-book/src/config.yml +55 -0
  68. data/test/sample-book/src/images/ch01-imgsample.jpg +0 -0
  69. data/test/sample-book/src/images/cover.jpg +0 -0
  70. data/test/sample-book/src/main.css +251 -0
  71. data/test/sample-book/src/preface.re +15 -0
  72. data/test/sample-book/src/sty/jumoline.sty +310 -0
  73. data/test/sample-book/src/sty/samplemacro.sty +21 -0
  74. data/test/sample-book/src/vendor/jumoline/README +29 -0
  75. data/test/sample-book/src/vendor/jumoline/jumoline.dtx +2988 -0
  76. data/test/sample-book/src/vendor/jumoline/jumoline.ins +6 -0
  77. data/test/test_book.rb +26 -646
  78. data/test/test_book_chapter.rb +418 -0
  79. data/test/test_book_parameter.rb +42 -0
  80. data/test/test_book_part.rb +53 -0
  81. data/test/test_builder.rb +17 -10
  82. data/test/test_compiler.rb +46 -0
  83. data/test/test_epubmaker.rb +1 -1
  84. data/test/test_epubmaker_cmd.rb +36 -0
  85. data/test/test_helper.rb +17 -0
  86. data/test/test_htmlbuilder.rb +156 -24
  87. data/test/test_htmlutils.rb +4 -0
  88. data/test/test_i18n.rb +6 -2
  89. data/test/test_idgxmlbuilder.rb +33 -11
  90. data/test/test_inaobuilder.rb +247 -0
  91. data/test/test_index.rb +31 -0
  92. data/test/test_latexbuilder.rb +115 -35
  93. data/test/test_makerhelper.rb +50 -0
  94. data/test/test_pdfmaker_cmd.rb +36 -0
  95. data/test/test_preprocessor.rb +7 -7
  96. data/test/test_topbuilder.rb +6 -7
  97. data/test/test_uuid.rb +1 -0
  98. metadata +117 -12
  99. data/lib/review/index.rb +0 -323
  100. data/lib/review/volume.rb +0 -66
@@ -0,0 +1,247 @@
1
+ #
2
+ # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
+ #
4
+ # Copyright (c) 2002-2008 Minero Aoki
5
+ # 2009 Minero Aoki, Kenshi Muto
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of the GNU LGPL, see the file "COPYING".
11
+ #
12
+ module ReVIEW
13
+ module Book
14
+ class Base
15
+
16
+ attr_accessor :param
17
+
18
+ def self.load_default
19
+ %w( . .. ../.. ).each do |basedir|
20
+ if File.file?("#{basedir}/CHAPS")
21
+ book = load(basedir)
22
+ if File.file?("#{basedir}/config.rb")
23
+ book.instance_variable_set("@parameters", Parameters.load("#{basedir}/config.rb"))
24
+ end
25
+ return book
26
+ end
27
+ end
28
+ new('.')
29
+ end
30
+
31
+ def self.load(dir)
32
+ update_rubyenv dir
33
+ new(dir)
34
+ end
35
+
36
+ @basedir_seen = {}
37
+
38
+ def self.update_rubyenv(dir)
39
+ return if @basedir_seen.key?(dir)
40
+ if File.directory?("#{dir}/lib/review")
41
+ $LOAD_PATH.unshift "#{dir}/lib"
42
+ end
43
+ if File.file?("#{dir}/review-ext.rb")
44
+ Kernel.load File.expand_path("#{dir}/review-ext.rb")
45
+ end
46
+ @basedir_seen[dir] = true
47
+ end
48
+
49
+ def initialize(basedir, parameters = Parameters.default)
50
+ @basedir = basedir
51
+ @parameters = parameters
52
+ @parts = nil
53
+ @chapter_index = nil
54
+ end
55
+
56
+ extend Forwardable
57
+ def_delegators '@parameters',
58
+ :chapter_file,
59
+ :part_file,
60
+ :bib_file,
61
+ :reject_file,
62
+ :predef_file,
63
+ :postdef_file,
64
+ :ext,
65
+ :image_dir,
66
+ :image_types,
67
+ :page_metric
68
+
69
+ def parts
70
+ @parts ||= read_parts()
71
+ end
72
+
73
+ def parts_in_file
74
+ parts.find_all{|part|
75
+ part if part.present? and part.file?
76
+ }
77
+ end
78
+
79
+ def part(n)
80
+ parts.detect {|part| part.number == n }
81
+ end
82
+
83
+ def each_part(&block)
84
+ parts.each(&block)
85
+ end
86
+
87
+ def chapters
88
+ parts().map {|p| p.chapters }.flatten
89
+ end
90
+
91
+ def each_chapter(&block)
92
+ chapters.each(&block)
93
+ end
94
+
95
+ def chapter_index
96
+ @chapter_index ||= ChapterIndex.new(chapters())
97
+ @chapter_index
98
+ end
99
+
100
+ def chapter(id)
101
+ chapter_index()[id]
102
+ end
103
+
104
+ def volume
105
+ Volume.sum(chapters.map {|chap| chap.volume })
106
+ end
107
+
108
+ def read_CHAPS
109
+ read_FILE("chapter_file")
110
+ end
111
+
112
+ def read_PREDEF
113
+ read_FILE("predef_file")
114
+ end
115
+
116
+ def read_POSTDEF
117
+ read_FILE("postdef_file")
118
+ end
119
+
120
+ def read_PART
121
+ @read_PART ||= File.read("#{@basedir}/#{part_file}")
122
+ end
123
+
124
+ def part_exist?
125
+ File.exist?("#{@basedir}/#{part_file}")
126
+ end
127
+
128
+ def read_bib
129
+ File.read("#{@basedir}/#{bib_file}")
130
+ end
131
+
132
+ def bib_exist?
133
+ File.exist?("#{@basedir}/#{bib_file}")
134
+ end
135
+
136
+ def prefaces
137
+ if File.file?("#{@basedir}/#{predef_file}")
138
+ begin
139
+ return mkpart_from_namelistfile("#{@basedir}/#{predef_file}")
140
+ rescue FileNotFound => err
141
+ raise FileNotFound, "preface #{err.message}"
142
+ end
143
+ else
144
+ mkpart_from_namelist(%w(preface))
145
+ end
146
+ end
147
+
148
+ def postscripts
149
+ if File.file?("#{@basedir}/#{postdef_file}")
150
+ begin
151
+ return mkpart_from_namelistfile("#{@basedir}/#{postdef_file}")
152
+ rescue FileNotFound => err
153
+ raise FileNotFound, "postscript #{err.message}"
154
+ end
155
+ else
156
+ mkpart_from_namelist(%w(appendix postscript))
157
+ end
158
+ end
159
+
160
+ def basedir
161
+ @basedir
162
+ end
163
+
164
+ private
165
+
166
+ def read_parts
167
+ list = parse_chapters
168
+ if pre = prefaces
169
+ list.unshift pre
170
+ end
171
+ if post = postscripts
172
+ list.push post
173
+ end
174
+ list
175
+ end
176
+
177
+ def parse_chapters
178
+ part = 0
179
+ num = 0
180
+ chap = read_CHAPS()\
181
+ .strip.lines.map {|line| line.strip }.join("\n").split(/\n{2,}/)\
182
+ .map {|part_chunk|
183
+ chaps = part_chunk.split.map {|chapid|
184
+ Chapter.new(self, (num += 1), chapid, "#{@basedir}/#{chapid}")
185
+ }
186
+ if part_exist? && read_PART.split("\n").size >= part
187
+ Part.new(self, (part += 1), chaps, read_PART.split("\n")[part-1])
188
+ else
189
+ Part.new(self, (part += 1), chaps)
190
+ end
191
+ }
192
+ return chap
193
+ end
194
+
195
+ def mkpart_from_namelistfile(path)
196
+ chaps = []
197
+ File.read(path).split.each_with_index do |name, idx|
198
+ name.sub!(/\A\xEF\xBB\xBF/u, '') # remove BOM
199
+ if path =~ /PREDEF/
200
+ chaps << mkchap(name)
201
+ else
202
+ chaps << mkchap(name, idx + 1)
203
+ end
204
+ end
205
+ mkpart(chaps)
206
+ end
207
+
208
+ def mkpart_from_namelist(names)
209
+ mkpart(names.map {|n| mkchap_ifexist(n) }.compact)
210
+ end
211
+
212
+ def mkpart(chaps)
213
+ chaps.empty? ? nil : Part.new(self, nil, chaps)
214
+ end
215
+
216
+ def mkchap(name, number = nil)
217
+ name += ext if File.extname(name) == ""
218
+ path = "#{@basedir}/#{name}"
219
+ raise FileNotFound, "file not exist: #{path}" unless File.file?(path)
220
+ Chapter.new(self, number, name, path)
221
+ end
222
+
223
+ def mkchap_ifexist(id)
224
+ name = "#{id}#{ext()}"
225
+ path = "#{@basedir}/#{name}"
226
+ File.file?(path) ? Chapter.new(self, nil, name, path) : nil
227
+ end
228
+
229
+ def read_FILE(filename)
230
+ res = ""
231
+ File.open("#{@basedir}/#{eval(filename)}") do |f|
232
+ while line = f.gets
233
+ line.sub!(/\A\xEF\xBB\xBF/u, '') # remove BOM
234
+ if /\A#/ =~ line
235
+ next
236
+ end
237
+ line.gsub!(/#.*$/, "")
238
+ res << line
239
+ end
240
+ end
241
+ res
242
+ rescue Errno::ENOENT
243
+ Dir.glob("#{@basedir}/*#{ext()}").sort.join("\n")
244
+ end
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,81 @@
1
+ #
2
+ # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
+ #
4
+ # Copyright (c) 2002-2008 Minero Aoki
5
+ # 2009 Minero Aoki, Kenshi Muto
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of the GNU LGPL, see the file "COPYING".
11
+ #
12
+ require 'review/book/compilable'
13
+ module ReVIEW
14
+ module Book
15
+ class Chapter
16
+ include Compilable
17
+
18
+ def Chapter.intern_pathes(pathes)
19
+ books = {}
20
+ pathes.map {|path|
21
+ basedir = File.dirname(path)
22
+ book = (books[File.expand_path(basedir)] ||= Book.load(basedir))
23
+ begin
24
+ book.chapter(File.basename(path, '.*'))
25
+ rescue KeyError => err
26
+ raise FileNotFound, "no such file: #{path}"
27
+ end
28
+ }
29
+ end
30
+
31
+ def Chapter.for_stdin
32
+ new(nil, nil, '-', nil, $stdin)
33
+ end
34
+
35
+ def Chapter.for_path(number, path)
36
+ new(nil, number, File.basename(path), path)
37
+ end
38
+
39
+ attr_reader :number
40
+
41
+ def initialize(book, number, name, path, io = nil)
42
+ @book = book
43
+ @number = number
44
+ @name = name
45
+ @path = path
46
+ @io = io
47
+ @title = nil
48
+ @content = nil
49
+ @list_index = nil
50
+ @table_index = nil
51
+ @footnote_index = nil
52
+ @image_index = nil
53
+ @icon_index = nil
54
+ @numberless_image_index = nil
55
+ @indepimage_index = nil
56
+ @headline_index = nil
57
+ end
58
+
59
+ def inspect
60
+ "\#<#{self.class} #{@number} #{@path}>"
61
+ end
62
+
63
+ def on_CHAPS?
64
+ on_FILE?(@book.read_CHAPS())
65
+ end
66
+
67
+ def on_PREDEF?
68
+ on_FILE?(@book.read_PREDEF())
69
+ end
70
+
71
+ def on_POSTDEF?
72
+ on_FILE?(@book.read_POSTDEF())
73
+ end
74
+
75
+ private
76
+ def on_FILE?(contents)
77
+ contents.lines.map(&:strip).include?(id() + @book.ext())
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,163 @@
1
+ #
2
+ # $Id: book.rb 4315 2009-09-02 04:15:24Z kmuto $
3
+ #
4
+ # Copyright (c) 2002-2008 Minero Aoki
5
+ # 2009 Minero Aoki, Kenshi Muto
6
+ #
7
+ # This program is free software.
8
+ # You can distribute or modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of the GNU LGPL, see the file "COPYING".
11
+ #
12
+ require 'review/textutils'
13
+ module ReVIEW
14
+ module Book
15
+ module Compilable
16
+ include TextUtils
17
+ attr_reader :book
18
+ attr_reader :path
19
+
20
+ def env
21
+ @book
22
+ end
23
+
24
+ def dirname
25
+ return nil unless @path
26
+ File.dirname(@path)
27
+ end
28
+
29
+ def basename
30
+ return nil unless @path
31
+ File.basename(@path)
32
+ end
33
+
34
+ def name
35
+ File.basename(@name, '.*')
36
+ end
37
+
38
+ alias id name
39
+
40
+ def title
41
+ @title = ""
42
+ open {|f|
43
+ f.each_line {|l|
44
+ l = convert_inencoding(l, ReVIEW.book.param["inencoding"])
45
+ if l =~ /\A=+/
46
+ @title = l.sub(/\A=+/, '').strip
47
+ break
48
+ end
49
+ }
50
+ }
51
+ @title
52
+ end
53
+
54
+ def size
55
+ File.size(path())
56
+ end
57
+
58
+ def volume
59
+ @volume ||= Volume.count_file(path())
60
+ end
61
+
62
+ def open(&block)
63
+ return (block_given?() ? yield(@io) : @io) if @io
64
+ File.open(path(), &block)
65
+ end
66
+
67
+ attr_writer :content
68
+
69
+ def content
70
+ @content = convert_inencoding(File.read(path()),
71
+ ReVIEW.book.param["inencoding"])
72
+ rescue
73
+ @content
74
+ end
75
+
76
+ def lines
77
+ # FIXME: we cannot duplicate Enumerator on ruby 1.9 HEAD
78
+ (@lines ||= content().lines.to_a).dup
79
+ end
80
+
81
+ def list(id)
82
+ list_index()[id]
83
+ end
84
+
85
+ def list_index
86
+ @list_index ||= ListIndex.parse(lines())
87
+ @list_index
88
+ end
89
+
90
+ def table(id)
91
+ table_index()[id]
92
+ end
93
+
94
+ def table_index
95
+ @table_index ||= TableIndex.parse(lines())
96
+ @table_index
97
+ end
98
+
99
+ def footnote(id)
100
+ footnote_index()[id]
101
+ end
102
+
103
+ def footnote_index
104
+ @footnote_index ||= FootnoteIndex.parse(lines())
105
+ @footnote_index
106
+ end
107
+
108
+ def image(id)
109
+ return image_index()[id] if image_index().has_key?(id)
110
+ return icon_index()[id] if icon_index().has_key?(id)
111
+ return numberless_image_index()[id] if numberless_image_index().has_key?(id)
112
+ indepimage_index()[id]
113
+ end
114
+
115
+ def numberless_image_index
116
+ @numberless_image_index ||=
117
+ NumberlessImageIndex.parse(lines(), id(),
118
+ "#{book.basedir}#{@book.image_dir}",
119
+ @book.image_types)
120
+ end
121
+
122
+ def image_index
123
+ @image_index ||= ImageIndex.parse(lines(), id(),
124
+ "#{book.basedir}#{@book.image_dir}",
125
+ @book.image_types)
126
+ @image_index
127
+ end
128
+
129
+ def icon_index
130
+ @icon_index ||= IconIndex.parse(lines(), id(),
131
+ "#{book.basedir}#{@book.image_dir}",
132
+ @book.image_types)
133
+ @icon_index
134
+ end
135
+
136
+ def indepimage_index
137
+ @indepimage_index ||=
138
+ IndepImageIndex.parse(lines(), id(),
139
+ "#{book.basedir}#{@book.image_dir}",
140
+ @book.image_types)
141
+ end
142
+
143
+ def bibpaper(id)
144
+ bibpaper_index()[id]
145
+ end
146
+
147
+ def bibpaper_index
148
+ raise FileNotFound, "no such bib file: #{@book.bib_file}" unless @book.bib_exist?
149
+ @bibpaper_index ||= BibpaperIndex.parse(@book.read_bib.lines.to_a)
150
+ @bibpaper_index
151
+ end
152
+
153
+ def headline(caption)
154
+ headline_index()[caption]
155
+ end
156
+
157
+ def headline_index
158
+ @headline_index ||= HeadlineIndex.parse(lines(), self)
159
+ end
160
+ end
161
+ end
162
+ end
163
+