review 0.6.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.
- data/COPYING +515 -0
- data/ChangeLog +1278 -0
- data/README.rdoc +21 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/bin/review-check +190 -0
- data/bin/review-checkdep +63 -0
- data/bin/review-compile +165 -0
- data/bin/review-epubmaker +525 -0
- data/bin/review-index +108 -0
- data/bin/review-preproc +140 -0
- data/bin/review-validate +51 -0
- data/bin/review-vol +106 -0
- data/doc/format.re +486 -0
- data/doc/format.txt +434 -0
- data/doc/format_idg.txt +194 -0
- data/doc/format_sjis.txt +313 -0
- data/doc/sample.css +91 -0
- data/doc/sample.yaml +46 -0
- data/lib/lineinput.rb +155 -0
- data/lib/review/book.rb +580 -0
- data/lib/review/builder.rb +274 -0
- data/lib/review/compat.rb +22 -0
- data/lib/review/compiler.rb +483 -0
- data/lib/review/epubbuilder.rb +692 -0
- data/lib/review/ewbbuilder.rb +382 -0
- data/lib/review/exception.rb +21 -0
- data/lib/review/htmlbuilder.rb +370 -0
- data/lib/review/htmllayout.rb +19 -0
- data/lib/review/htmlutils.rb +27 -0
- data/lib/review/idgxmlbuilder.rb +1078 -0
- data/lib/review/index.rb +224 -0
- data/lib/review/latexbuilder.rb +420 -0
- data/lib/review/latexindex.rb +35 -0
- data/lib/review/latexutils.rb +52 -0
- data/lib/review/preprocessor.rb +520 -0
- data/lib/review/textutils.rb +19 -0
- data/lib/review/tocparser.rb +333 -0
- data/lib/review/tocprinter.rb +220 -0
- data/lib/review/topbuilder.rb +572 -0
- data/lib/review/unfold.rb +138 -0
- data/lib/review/volume.rb +66 -0
- data/lib/review.rb +4 -0
- data/review.gemspec +93 -0
- data/setup.rb +1587 -0
- data/test/test_epubbuilder.rb +73 -0
- data/test/test_helper.rb +2 -0
- data/test/test_htmlbuilder.rb +42 -0
- data/test/test_latexbuilder.rb +74 -0
- metadata +122 -0
data/README.rdoc
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
= ReVIEW
|
2
|
+
|
3
|
+
ReVIEW is a easy-to-use digital publishing system for books and ebooks.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== License
|
16
|
+
|
17
|
+
LGPL. See COPYING file.
|
18
|
+
|
19
|
+
== Copyright
|
20
|
+
|
21
|
+
Copyright (c) 2006-2010 Minero Aoki, Kenshi Muto, Masayoshi Takahashi.
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/clean'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "review"
|
10
|
+
gem.summary = %Q{ReVIEW: a easy-to-use digital publishing system}
|
11
|
+
gem.description = %Q{ReVIEW is a digital publishing system for books and ebooks. It supports InDesin, EPUB and LaTeX.}
|
12
|
+
gem.email = "kmuto@debian.org"
|
13
|
+
gem.homepage = "http://github.com/kmuto/review"
|
14
|
+
gem.authors = ["kmuto", "takahashim"]
|
15
|
+
# gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
16
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
task :test => :check_dependencies
|
25
|
+
|
26
|
+
task :default => [:test]
|
27
|
+
|
28
|
+
Rake::TestTask.new("test") do |t|
|
29
|
+
t.libs << "test"
|
30
|
+
t.pattern = "test/test_*.rb"
|
31
|
+
t.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
37
|
+
|
38
|
+
rdoc.rdoc_dir = 'rdoc'
|
39
|
+
rdoc.title = "review #{version}"
|
40
|
+
rdoc.rdoc_files.include('README*')
|
41
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
42
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.6.0
|
data/bin/review-check
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
#
|
4
|
+
# Copyright (c) 1999-2007 Minero Aoki
|
5
|
+
# Copyright (c) 2010 Kenshi Muto, Minero Aoki
|
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
|
+
|
13
|
+
require 'pathname'
|
14
|
+
|
15
|
+
bindir = Pathname.new(__FILE__).realpath.dirname
|
16
|
+
$LOAD_PATH.unshift((bindir + '../lib').realpath)
|
17
|
+
|
18
|
+
require 'review/book'
|
19
|
+
require 'optparse'
|
20
|
+
require 'nkf'
|
21
|
+
|
22
|
+
def sigmain
|
23
|
+
Signal.trap(:INT) { exit 1 }
|
24
|
+
Signal.trap(:PIPE, 'IGNORE')
|
25
|
+
main
|
26
|
+
rescue Errno::EPIPE
|
27
|
+
exit 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def main
|
31
|
+
$KCODE = 'UTF-8' unless defined?(Encoding)
|
32
|
+
@param = {
|
33
|
+
"inencoding" => "UTF-8",
|
34
|
+
"outencoding" => "UTF-8"
|
35
|
+
}
|
36
|
+
|
37
|
+
modes = nil
|
38
|
+
files = ARGV unless ARGV.empty?
|
39
|
+
parser = OptionParser.new
|
40
|
+
parser.on('--inencoding=ENCODING', 'Set input encoding. (UTF-8, EUC, JIS, and SJIS)') {|enc|
|
41
|
+
@param["inencoding"] = enc
|
42
|
+
}
|
43
|
+
parser.on('--outencoding=ENCODING', 'Set output encoding. (UTF-8[default], EUC, JIS, and SJIS)') {|enc|
|
44
|
+
@param["outencoding"] = enc
|
45
|
+
}
|
46
|
+
parser.on('-a', '--all-chapters', 'Check all chapters.') {
|
47
|
+
files = ReVIEW.book.chapters.map {|ent| ent.path }
|
48
|
+
}
|
49
|
+
parser.on('-s', '--section N', 'Check section N.') {|n|
|
50
|
+
ents = ReVIEW.env.parts[Integer(n) - 1] or
|
51
|
+
raise ReVIEW::ApplicationError, "section #{n} not exist"
|
52
|
+
files = ents.map {|ent| ent.path }
|
53
|
+
}
|
54
|
+
parser.on('--text', 'Check text.') {
|
55
|
+
(modes ||= []).push :text
|
56
|
+
}
|
57
|
+
parser.on('--help', 'print this message and quit.') {
|
58
|
+
puts parser.help
|
59
|
+
exit 0
|
60
|
+
}
|
61
|
+
begin
|
62
|
+
parser.parse!
|
63
|
+
rescue OptionParser::ParseError => err
|
64
|
+
$stderr.puts err.message
|
65
|
+
$stderr.puts parser.help
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
unless files
|
69
|
+
$stderr.puts "no input"
|
70
|
+
exit 1
|
71
|
+
end
|
72
|
+
modes ||= [:text]
|
73
|
+
|
74
|
+
modes.each do |mode|
|
75
|
+
case mode
|
76
|
+
when :text
|
77
|
+
check_text files
|
78
|
+
else
|
79
|
+
raise 'must not happen'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_text(files)
|
85
|
+
re, neg = words_re(ReVIEW.book.basedir + ReVIEW.book.reject_file)
|
86
|
+
files.each do |path|
|
87
|
+
File.open(path) {|f|
|
88
|
+
each_paragraph(f) do |para, lineno|
|
89
|
+
s = para.join('')
|
90
|
+
if m = re.match(s)
|
91
|
+
next if m[0] == $ReVIEW_utils_word_ok
|
92
|
+
next if neg and neg =~ s
|
93
|
+
str, offset = find_line(para, re)
|
94
|
+
out = sprintf("%s:%d: %s\n", path, lineno + offset, str)
|
95
|
+
if @param["outencoding"] =~ /^EUC$/
|
96
|
+
print NKF.nkf("-e", out)
|
97
|
+
elsif @param["outencoding"] =~ /^SJIS$/
|
98
|
+
print NKF.nkf("-s", out)
|
99
|
+
elsif @param["outencoding"] =~ /^JIS$/
|
100
|
+
print NKF.nkf("-j", out)
|
101
|
+
else
|
102
|
+
print out
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def find_line(lines, re)
|
111
|
+
# single line?
|
112
|
+
lines.each_with_index do |line, idx|
|
113
|
+
return line.gsub(re, '<<<\&>>>'), idx if re =~ line
|
114
|
+
end
|
115
|
+
|
116
|
+
# multiple lines?
|
117
|
+
i = 0
|
118
|
+
while i < lines.size - 1
|
119
|
+
str = lines[i] + lines[i+1]
|
120
|
+
return str.gsub(re, '<<<\&>>>'), i if re =~ str
|
121
|
+
i += 1
|
122
|
+
end
|
123
|
+
|
124
|
+
raise 'must not happen'
|
125
|
+
end
|
126
|
+
|
127
|
+
def words_re(rc)
|
128
|
+
words = []
|
129
|
+
nega = []
|
130
|
+
File.foreach(rc) do |line|
|
131
|
+
next if line[0,1] == '#'
|
132
|
+
if / !/ =~ line
|
133
|
+
line, n = *line.split(/!/, 2)
|
134
|
+
nega.push n.strip
|
135
|
+
end
|
136
|
+
words.push line.strip
|
137
|
+
end
|
138
|
+
return Regexp.compile(words.join('|')),
|
139
|
+
nega.empty?() ? nil : Regexp.compile(nega.join('|'))
|
140
|
+
end
|
141
|
+
|
142
|
+
def each_paragraph(f)
|
143
|
+
$ReVIEW_utils_word_ok = nil
|
144
|
+
while line = f.gets
|
145
|
+
if @param["inencoding"] =~ /^EUC$/
|
146
|
+
line = NKF.nkf("-E -w", line)
|
147
|
+
elsif @param["inencoding"] =~ /SJIS$/
|
148
|
+
line = NKF.nkf("-S -w", line)
|
149
|
+
elsif @param["inencoding"] =~ /^JIS$/
|
150
|
+
line = NKF.nkf("-J -w", line)
|
151
|
+
else
|
152
|
+
line = NKF.nkf("-w", line)
|
153
|
+
end
|
154
|
+
case line
|
155
|
+
when /\A\#@ok\((.*)\)/
|
156
|
+
$ReVIEW_utils_word_ok = $1
|
157
|
+
when /\A\#@/
|
158
|
+
;
|
159
|
+
when %r[\A//caption\{(.*?)//\}]
|
160
|
+
yield [$1], f.filename, f.lineno
|
161
|
+
when %r<\A//\w.*\{\s*\z>
|
162
|
+
while line = f.gets
|
163
|
+
break if %r<//\}> === line
|
164
|
+
end
|
165
|
+
when /\A=/
|
166
|
+
yield [line.slice(/\A=+(?:\[.*?\])?\s+(.*)/, 1).strip], f.lineno
|
167
|
+
when /\A\s*\z/
|
168
|
+
# skip
|
169
|
+
else
|
170
|
+
buf = [line.strip]
|
171
|
+
lineno = f.lineno
|
172
|
+
while line = f.gets
|
173
|
+
break if line.strip.empty?
|
174
|
+
break if %r<\A(?:=|//[\w\}])> =~ line
|
175
|
+
next if %r<\A\#@> =~ line
|
176
|
+
buf.push line.strip
|
177
|
+
end
|
178
|
+
yield buf, lineno
|
179
|
+
$ReVIEW_utils_word_ok = nil
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def each_paragraph_line(f, &block)
|
185
|
+
each_paragraph(f) do |para, *|
|
186
|
+
para.each(&block)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
sigmain
|
data/bin/review-checkdep
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# $Id: review-checkdep 3748 2007-12-24 07:06:06Z aamine $
|
4
|
+
#
|
5
|
+
# Copyright (c) 1999-2007 Minero Aoki
|
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
|
+
|
13
|
+
require 'pathname'
|
14
|
+
|
15
|
+
bindir = Pathname.new(__FILE__).realpath.dirname
|
16
|
+
$LOAD_PATH.unshift((bindir + '../lib').realpath)
|
17
|
+
|
18
|
+
PREDEF_FILE = 'PREDEF'
|
19
|
+
|
20
|
+
def main
|
21
|
+
@provided = parse_predefined()
|
22
|
+
@unprovided = {}
|
23
|
+
ARGF.each do |line|
|
24
|
+
case line
|
25
|
+
when /\A\#@require\((.*)\)/
|
26
|
+
kw = $1
|
27
|
+
unless @provided.key?(kw)
|
28
|
+
puts "#{location()}: not provided: #{kw}"
|
29
|
+
@unprovided[kw] = location()
|
30
|
+
end
|
31
|
+
when /\A\#@provide\((.*)\)/
|
32
|
+
provide $1
|
33
|
+
else
|
34
|
+
line.scan(/@<kw>\{(.*?)[,\}]/) do
|
35
|
+
provide $1
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def provide(kw)
|
42
|
+
@provided[kw] ||= location()
|
43
|
+
if @unprovided[kw]
|
44
|
+
reqpos = @unprovided.delete(kw)
|
45
|
+
puts "#{location()}: provided now: #{kw} (#{reqpos})"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_predefined
|
50
|
+
result = {}
|
51
|
+
File.foreach(PREDEF_FILE) do |line|
|
52
|
+
result[line.strip] = '(predefined)'
|
53
|
+
end
|
54
|
+
result
|
55
|
+
rescue Errno::ENOENT
|
56
|
+
return {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def location
|
60
|
+
"#{ARGF.filename}:#{ARGF.file.lineno}"
|
61
|
+
end
|
62
|
+
|
63
|
+
main
|
data/bin/review-compile
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# $Id: review-compile 4326 2010-01-12 14:10:17Z kmuto $
|
4
|
+
#
|
5
|
+
# Copyright (c) 1999-2007 Minero Aoki
|
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
|
+
|
13
|
+
require 'pathname'
|
14
|
+
|
15
|
+
bindir = Pathname.new(__FILE__).realpath.dirname
|
16
|
+
$LOAD_PATH.unshift((bindir + '../lib').realpath)
|
17
|
+
|
18
|
+
require 'review/compiler'
|
19
|
+
require 'review/book'
|
20
|
+
require 'fileutils'
|
21
|
+
require 'optparse'
|
22
|
+
|
23
|
+
def main
|
24
|
+
Signal.trap(:INT) { exit 1 }
|
25
|
+
Signal.trap(:PIPE, "IGNORE")
|
26
|
+
_main
|
27
|
+
rescue Errno::EPIPE
|
28
|
+
exit 0
|
29
|
+
end
|
30
|
+
|
31
|
+
def _main
|
32
|
+
$KCODE = 'UTF-8' unless defined?(Encoding)
|
33
|
+
|
34
|
+
mode = :files
|
35
|
+
basedir = nil
|
36
|
+
if /\Areview2/ =~ File.basename($0)
|
37
|
+
target = File.basename($0, '.rb').sub(/review2/, '')
|
38
|
+
else
|
39
|
+
target = nil
|
40
|
+
end
|
41
|
+
check_only = false
|
42
|
+
|
43
|
+
param = {
|
44
|
+
"secnolevel" => 2, # for IDGXMLBuilder, EPUBBuilder
|
45
|
+
"tableopt" => nil, # for IDGXMLBuilder
|
46
|
+
"nolf" => nil, # for IDGXMLBuilder
|
47
|
+
"chapref" => nil, # for IDGXMLBuilder
|
48
|
+
"inencoding" => "UTF-8",
|
49
|
+
"outencoding" => "UTF-8",
|
50
|
+
"subdirmode" => nil,
|
51
|
+
"stylesheet" => nil, # for EPUBBuilder
|
52
|
+
}
|
53
|
+
|
54
|
+
parser = OptionParser.new
|
55
|
+
parser.banner = "Usage: #{File.basename($0)} [--target=FMT]"
|
56
|
+
parser.on('--inencoding=ENCODING', 'Set input encoding. (UTF-8, EUC, JIS, and SJIS)') {|enc|
|
57
|
+
param["inencoding"] = enc
|
58
|
+
}
|
59
|
+
parser.on('--outencoding=ENCODING', 'Set output encoding. (UTF-8[default], EUC, JIS, and SJIS)') {|enc|
|
60
|
+
param["outencoding"] = enc
|
61
|
+
}
|
62
|
+
parser.on('-c', '--check', 'Check manuscript') {
|
63
|
+
check_only = true
|
64
|
+
}
|
65
|
+
parser.on('--level=LVL', 'Section level to append number.') {|lvl|
|
66
|
+
param["secnolevel"] = lvl.to_i
|
67
|
+
}
|
68
|
+
parser.on('--nolfinxml', 'Do not insert LF in XML. (idgxml)') {
|
69
|
+
param["nolf"] = true
|
70
|
+
}
|
71
|
+
parser.on('--table=WIDTH', 'Default table width. (idgxml)') {|tbl|
|
72
|
+
param["tableopt"] = tbl
|
73
|
+
}
|
74
|
+
parser.on('--listinfo', 'Append listinfo tag to lists to indicate begin/end. (idgxml)') {
|
75
|
+
param["listinfo"] = true
|
76
|
+
}
|
77
|
+
parser.on('--chapref="before,middle,after"', 'Chapref decoration.') {|cdec|
|
78
|
+
param["chapref"] = cdec
|
79
|
+
}
|
80
|
+
parser.on('--subdirmode', 'Use chapter/id.ext path style to find images.') {
|
81
|
+
param["subdirmode"] = true
|
82
|
+
}
|
83
|
+
parser.on('--stylesheet=file', 'Stylesheet file for EPUB. (epub)') {|file|
|
84
|
+
param["stylesheet"] = file
|
85
|
+
}
|
86
|
+
unless target
|
87
|
+
parser.on('--target=FMT', 'Target format.') {|fmt|
|
88
|
+
target = fmt
|
89
|
+
}
|
90
|
+
end
|
91
|
+
parser.on('-a', '--all', 'Compile all chapters.') {
|
92
|
+
mode = :dir
|
93
|
+
basedir = nil
|
94
|
+
}
|
95
|
+
parser.on('--directory=DIR', 'Compile all chapters in DIR.') {|path|
|
96
|
+
mode = :dir
|
97
|
+
basedir = path
|
98
|
+
}
|
99
|
+
parser.on('--help', 'Prints this message and quit.') {
|
100
|
+
puts parser.help
|
101
|
+
exit 0
|
102
|
+
}
|
103
|
+
begin
|
104
|
+
parser.parse!
|
105
|
+
unless target
|
106
|
+
if check_only
|
107
|
+
target = 'html'
|
108
|
+
else
|
109
|
+
raise OptionParser::ParseError, "no target given"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
rescue OptionParser::ParseError => err
|
113
|
+
error err.message
|
114
|
+
$stderr.puts parser.help
|
115
|
+
exit 1
|
116
|
+
end
|
117
|
+
|
118
|
+
begin
|
119
|
+
compiler = ReVIEW::Compiler.new(load_strategy_class(target, check_only))
|
120
|
+
compiler.setParameter(param)
|
121
|
+
case mode
|
122
|
+
when :files
|
123
|
+
if ARGV.empty?
|
124
|
+
error 'no input'
|
125
|
+
exit 1
|
126
|
+
end
|
127
|
+
ReVIEW::Chapter.intern_pathes(ARGV).each do |chap|
|
128
|
+
chap.setParameter(param)
|
129
|
+
result = compiler.compile(chap)
|
130
|
+
print result unless check_only
|
131
|
+
end
|
132
|
+
when :dir
|
133
|
+
book = basedir ? ReVIEW::Book.load(basedir) : ReVIEW.book
|
134
|
+
book.setParameter(param)
|
135
|
+
book.chapters.each do |chap|
|
136
|
+
chap.setParameter(param)
|
137
|
+
str = compiler.compile(chap)
|
138
|
+
write "#{chap.name}#{compiler.strategy.extname}", str unless check_only
|
139
|
+
end
|
140
|
+
else
|
141
|
+
raise "must not happen: #{mode}"
|
142
|
+
end
|
143
|
+
rescue ReVIEW::ApplicationError => err
|
144
|
+
raise if $DEBUG
|
145
|
+
error err.message
|
146
|
+
exit 1
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def error(msg)
|
151
|
+
$stderr.puts "#{File.basename($0, '.*')}: error: #{msg}"
|
152
|
+
end
|
153
|
+
|
154
|
+
def load_strategy_class(target, strict)
|
155
|
+
require "review/#{target}builder"
|
156
|
+
ReVIEW.const_get("#{target.upcase}Builder").new(strict)
|
157
|
+
end
|
158
|
+
|
159
|
+
def write(path, str)
|
160
|
+
File.open(path, 'w') {|f|
|
161
|
+
f.puts str
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
main
|