rdtool 0.6.38 → 0.6.39
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.
- checksums.yaml +7 -0
- data/Gemfile +1 -1
- data/HISTORY +6 -0
- data/README.html +63 -9
- data/README.ja.html +67 -10
- data/README.rd +67 -4
- data/README.rd.ja +71 -5
- data/Rakefile +19 -13
- data/bin/rd2 +208 -182
- data/bin/rdswap.rb +144 -88
- data/lib/rd/filter.rb +1 -1
- data/lib/rd/rd2html-ext-opt.rb +1 -1
- data/lib/rd/rd2html-opt.rb +1 -3
- data/lib/rd/rd2html5-lib.rb +118 -0
- data/lib/rd/rd2man-lib.rb +37 -12
- data/lib/rd/rd2man-opt.rb +16 -0
- data/lib/rd/rdblockparser.ry +0 -1
- data/lib/rd/rdblockparser.tab.rb +111 -110
- data/lib/rd/rdinlineparser.tab.rb +214 -212
- data/lib/rd/rdvisitor.rb +1 -2
- data/lib/rd/version.rb +6 -6
- data/rdtool.gemspec +23 -13
- data/test/test-methodlist-item.rb +0 -1
- data/test/test-rbl-file.rb +4 -7
- data/test/test-rd2-cli.rb +91 -0
- data/test/test-rd2html5-lib.rb +67 -0
- data/test/test-rd2man-lib.rb +54 -0
- data/test/test-rdswap-cli.rb +49 -0
- data/test/test-reference-resolver.rb +1 -1
- data/utils/rd-mode.el +40 -32
- metadata +66 -72
data/bin/rd2
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
2
|
# -*- coding: ASCII-8BIT -*-
|
|
3
3
|
=begin
|
|
4
4
|
= NAME
|
|
@@ -52,232 +52,258 @@ end
|
|
|
52
52
|
include RD
|
|
53
53
|
|
|
54
54
|
SYSTEM_NAME = "RDtool -- rd2"
|
|
55
|
-
SYSTEM_VERSION = "$Version: "+RD::VERSION + "$" #"
|
|
55
|
+
SYSTEM_VERSION = "$Version: " + RD::VERSION + "$" #"
|
|
56
56
|
RD2_VERSION = Version.new_from_version_string(SYSTEM_NAME, SYSTEM_VERSION)
|
|
57
57
|
|
|
58
|
-
# global vars
|
|
59
58
|
$Visitor_Class = nil
|
|
60
59
|
$Visitor = nil
|
|
61
60
|
$RD2_Sub_OptionParser = nil
|
|
62
|
-
|
|
63
|
-
# local vars
|
|
64
|
-
include_path = []
|
|
65
|
-
with_part = []
|
|
66
|
-
output_file = nil
|
|
67
|
-
output_index = nil
|
|
68
|
-
out_code = nil
|
|
69
|
-
from_rdo = nil
|
|
70
|
-
|
|
71
|
-
# user option
|
|
61
|
+
$RD2_OptionParser = nil
|
|
72
62
|
$DEFAULT_FORMAT_LIB = "rd/rd2html-lib"
|
|
73
63
|
$RC = {}
|
|
74
64
|
$RC["filter"] = Hash.new(RD::INCLUDE_FILTER)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
65
|
+
|
|
66
|
+
class RD2Command
|
|
67
|
+
PartArgument = Struct.new(:part, :filter)
|
|
68
|
+
|
|
69
|
+
def initialize(argv: ARGV, argf: ARGF, stdout: $stdout, stderr: $stderr, program_name: $PROGRAM_NAME)
|
|
70
|
+
@argv = argv
|
|
71
|
+
@argf = argf
|
|
72
|
+
@stdout = stdout
|
|
73
|
+
@stderr = stderr
|
|
74
|
+
@program_name = program_name
|
|
75
|
+
@include_path = []
|
|
76
|
+
@with_part = []
|
|
77
|
+
@output_file = nil
|
|
78
|
+
@output_index = false
|
|
79
|
+
@out_code = nil
|
|
80
|
+
@from_rdo = false
|
|
82
81
|
end
|
|
83
|
-
rescue
|
|
84
|
-
load "rd/dot.rd2rc"
|
|
85
|
-
end
|
|
86
82
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if $Visitor_Class && !$Visitor
|
|
98
|
-
$Visitor = $Visitor_Class.new()
|
|
99
|
-
if $RD2_Sub_OptionParser
|
|
100
|
-
require $RD2_Sub_OptionParser
|
|
101
|
-
$RD2_Sub_OptionParser = nil
|
|
102
|
-
end
|
|
83
|
+
def run
|
|
84
|
+
load_user_config
|
|
85
|
+
require_implicit_format_lib
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
option_parser.parse!(@argv)
|
|
89
|
+
rescue OptionParser::ParseError => e
|
|
90
|
+
@stderr.print("Error: #{e.inspect}\n")
|
|
91
|
+
@stderr.print(option_parser.to_s)
|
|
92
|
+
return 1
|
|
103
93
|
end
|
|
104
|
-
end
|
|
105
94
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
95
|
+
load_default_format_library unless $Visitor_Class
|
|
96
|
+
ensure_visitor_loaded
|
|
97
|
+
$Visitor.input_filename = @argf.filename
|
|
98
|
+
|
|
99
|
+
tree = build_tree
|
|
100
|
+
configure_visitor
|
|
101
|
+
write_output(tree, $Visitor.visit(tree))
|
|
102
|
+
write_index(tree) if @output_index
|
|
103
|
+
0
|
|
104
|
+
rescue Racc::ParseError => e
|
|
105
|
+
@stderr.puts(e.message)
|
|
106
|
+
10
|
|
107
|
+
ensure
|
|
108
|
+
cleanup_tmp_files
|
|
110
109
|
end
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def option_parser
|
|
114
|
+
@option_parser ||= @argv.options do |q|
|
|
115
|
+
$RD2_OptionParser = q
|
|
116
|
+
q.banner = "Usage: #{File.basename(@program_name)} [options] rd-file > output\n"
|
|
117
|
+
q.on_head("global options:")
|
|
118
|
+
|
|
119
|
+
q.on("-rLIB", "--require=LIB", String, "choose format library.") do |lib|
|
|
120
|
+
load_format_library(lib)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
q.on("-oNAME", String, "indicate base name of output file") do |name|
|
|
124
|
+
@output_file = name
|
|
125
|
+
end
|
|
122
126
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
q.on("--out-code=KCODE",
|
|
128
|
+
Kconv::NAME2CONST.keys, Kconv::NAME_ALIAS,
|
|
129
|
+
"character encoding of output.(jis|euc|sjis|utf8)") do |code|
|
|
130
|
+
@out_code = code
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
q.on("--output-index", "output method index file (*.rmi)") do
|
|
134
|
+
@output_index = true
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
q.on("-IPATH", "--include-path=PATH", String,
|
|
138
|
+
"add PATH to list of include path") do |path|
|
|
139
|
+
@include_path.unshift(path)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
q.accept(PartArgument, /(\w+)(?:\s*:\s*(\w+))?/) do |_src, part, filter|
|
|
143
|
+
PartArgument.new(part, filter || part)
|
|
144
|
+
end
|
|
145
|
+
q.on("--with-part=PART", PartArgument, "include PART with Filter") do |entry|
|
|
146
|
+
@with_part << entry
|
|
147
|
+
unless @include_path.include?(RD::RDTree.tmp_dir)
|
|
148
|
+
@include_path << RD::RDTree.tmp_dir
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
q.on("--from-rdo", "load from *.rdo instead of *.rd") do
|
|
153
|
+
@from_rdo = true
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
q.on("--version", "print versions.") do
|
|
157
|
+
@stderr.puts(RD2_VERSION)
|
|
158
|
+
@stderr.puts(Tree::version)
|
|
159
|
+
@stderr.puts(Visitor::version)
|
|
160
|
+
@stderr.puts($Visitor_Class.version) if $Visitor_Class
|
|
161
|
+
raise SystemExit.new(0)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
q.on_tail("--help", "print this message") do
|
|
165
|
+
@stderr.print(q.to_s)
|
|
166
|
+
raise SystemExit.new(0)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
128
169
|
end
|
|
129
170
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
with_part.push([part, filter || part])
|
|
137
|
-
unless include_path.index(RD::RDTree.tmp_dir)
|
|
138
|
-
include_path.push(RD::RDTree.tmp_dir)
|
|
171
|
+
def load_user_config
|
|
172
|
+
user_config = File.expand_path("~/.rd2rc")
|
|
173
|
+
if File.readable?(user_config)
|
|
174
|
+
load user_config
|
|
175
|
+
else
|
|
176
|
+
load "rd/dot.rd2rc"
|
|
139
177
|
end
|
|
178
|
+
rescue LoadError, StandardError
|
|
179
|
+
load "rd/dot.rd2rc"
|
|
140
180
|
end
|
|
141
181
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
182
|
+
def require_implicit_format_lib
|
|
183
|
+
base = File.basename(@program_name, ".*").downcase
|
|
184
|
+
return unless /rd2.+/ =~ base
|
|
185
|
+
|
|
186
|
+
load_format_library("rd/#{$&}-lib.rb")
|
|
145
187
|
end
|
|
146
188
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
STDERR.puts Tree::version
|
|
151
|
-
STDERR.puts Visitor::version
|
|
152
|
-
STDERR.puts $Visitor_Class.version if $Visitor_Class
|
|
153
|
-
exit(0)
|
|
189
|
+
def load_format_library(lib)
|
|
190
|
+
require lib
|
|
191
|
+
ensure_visitor_loaded
|
|
154
192
|
end
|
|
155
193
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
STDERR.print(q.to_s)
|
|
159
|
-
exit(0)
|
|
194
|
+
def load_default_format_library
|
|
195
|
+
load_format_library($DEFAULT_FORMAT_LIB)
|
|
160
196
|
end
|
|
161
|
-
end # OptionParser.new
|
|
162
|
-
|
|
163
|
-
# require format lib implicitly
|
|
164
|
-
if /rd2.+/ =~ File.basename($0, ".*").downcase
|
|
165
|
-
visitor_lib = "rd/" + $& + "-lib.rb"
|
|
166
|
-
require visitor_lib
|
|
167
|
-
require $RD2_Sub_OptionParser if $RD2_Sub_OptionParser
|
|
168
|
-
# make visitor
|
|
169
|
-
$Visitor = $Visitor_Class.new()
|
|
170
|
-
end
|
|
171
197
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
STDERR.print("Error: " + $!.inspect + "\n")
|
|
176
|
-
STDERR.print(ARGV.options.to_s)
|
|
177
|
-
exit(1)
|
|
178
|
-
end
|
|
198
|
+
def ensure_visitor_loaded
|
|
199
|
+
return unless $Visitor_Class
|
|
200
|
+
return if $Visitor
|
|
179
201
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
end
|
|
202
|
+
$Visitor = $Visitor_Class.new
|
|
203
|
+
load_sub_option_parser
|
|
204
|
+
end
|
|
184
205
|
|
|
185
|
-
|
|
206
|
+
def load_sub_option_parser
|
|
207
|
+
return unless $RD2_Sub_OptionParser
|
|
186
208
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
rdos = []
|
|
190
|
-
ARGV.each do |path|
|
|
191
|
-
rdos.push(File.open(path))
|
|
192
|
-
dirname = File.dirname(path)
|
|
193
|
-
include_path.push(dirname, dirname + "/include")
|
|
194
|
-
end
|
|
195
|
-
tree = RDTree.new_from_rdo(*rdos)
|
|
196
|
-
tree.include_path = include_path
|
|
197
|
-
else
|
|
198
|
-
# set Include_Path
|
|
199
|
-
if ARGF.filename
|
|
200
|
-
dir = File.dirname(ARGF.filename)
|
|
201
|
-
else
|
|
202
|
-
dir = "."
|
|
209
|
+
require $RD2_Sub_OptionParser
|
|
210
|
+
$RD2_Sub_OptionParser = nil
|
|
203
211
|
end
|
|
204
|
-
include_path.push(dir)
|
|
205
|
-
include_path.push(dir + "/include")
|
|
206
212
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
213
|
+
def build_tree
|
|
214
|
+
if @from_rdo
|
|
215
|
+
build_tree_from_rdo
|
|
216
|
+
else
|
|
217
|
+
build_tree_from_rd
|
|
218
|
+
end
|
|
211
219
|
end
|
|
212
220
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
221
|
+
def build_tree_from_rdo
|
|
222
|
+
rdos = []
|
|
223
|
+
@argv.each do |path|
|
|
224
|
+
rdos << File.open(path)
|
|
225
|
+
dirname = File.dirname(path)
|
|
226
|
+
@include_path.push(dirname, File.join(dirname, "include"))
|
|
227
|
+
end
|
|
228
|
+
tree = RDTree.new_from_rdo(*rdos)
|
|
229
|
+
tree.include_path = @include_path
|
|
230
|
+
tree
|
|
231
|
+
ensure
|
|
232
|
+
rdos&.each(&:close)
|
|
218
233
|
end
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
234
|
+
|
|
235
|
+
def build_tree_from_rd
|
|
236
|
+
dir = @argf.filename ? File.dirname(@argf.filename) : "."
|
|
237
|
+
@include_path.push(dir, File.join(dir, "include"))
|
|
238
|
+
|
|
239
|
+
src = read_input_lines
|
|
240
|
+
if src.find { |line| /\S/ === line } && !src.find { |line| /^=begin\b/ === line }
|
|
241
|
+
src.unshift("=begin\n").push("=end\n")
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
tree = RDTree.new(src, @include_path, nil)
|
|
245
|
+
@with_part.each do |entry|
|
|
246
|
+
tree.filter[entry.part] = $RC["filter"][entry.filter]
|
|
247
|
+
end
|
|
222
248
|
tree.parse
|
|
223
|
-
|
|
224
|
-
STDERR.puts($!.message)
|
|
225
|
-
exit(10)
|
|
249
|
+
tree
|
|
226
250
|
end
|
|
227
|
-
end
|
|
228
251
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
end
|
|
252
|
+
def read_input_lines
|
|
253
|
+
@argf.readlines
|
|
254
|
+
end
|
|
233
255
|
|
|
234
|
-
|
|
235
|
-
|
|
256
|
+
def configure_visitor
|
|
257
|
+
@with_part.each do |entry|
|
|
258
|
+
$Visitor.include_suffix.push(entry.part)
|
|
259
|
+
end
|
|
236
260
|
|
|
237
|
-
|
|
238
|
-
if out_code
|
|
239
|
-
begin
|
|
240
|
-
$Visitor.charcode = out_code
|
|
241
|
-
$Visitor.lang = "ja"
|
|
242
|
-
rescue NameError
|
|
243
|
-
end
|
|
244
|
-
end
|
|
261
|
+
$Visitor.filename = @output_file if @output_file
|
|
245
262
|
|
|
246
|
-
|
|
247
|
-
out = $Visitor.visit(tree)
|
|
263
|
+
return unless @out_code
|
|
248
264
|
|
|
249
|
-
|
|
250
|
-
|
|
265
|
+
begin
|
|
266
|
+
$Visitor.charcode = @out_code
|
|
267
|
+
$Visitor.lang = "ja"
|
|
268
|
+
rescue NameError
|
|
269
|
+
end
|
|
270
|
+
end
|
|
251
271
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
else
|
|
259
|
-
|
|
260
|
-
end
|
|
272
|
+
def write_output(tree, out)
|
|
273
|
+
out = Kconv.kconv(out, Kconv::NAME2CONST[@out_code], Kconv::AUTO) if @out_code
|
|
274
|
+
|
|
275
|
+
if @output_file
|
|
276
|
+
suffix = if $Visitor.respond_to?(:output_suffix)
|
|
277
|
+
$Visitor.output_suffix
|
|
278
|
+
else
|
|
279
|
+
$Visitor.class::OUTPUT_SUFFIX
|
|
280
|
+
end
|
|
281
|
+
filename = @output_file + "." + suffix
|
|
282
|
+
File.open(filename, "w") { |file| file.print(out) }
|
|
283
|
+
@stderr.print("#{File.basename(@program_name)}: output to #{filename}...\n")
|
|
284
|
+
else
|
|
285
|
+
@stdout.print(out)
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def write_index(tree)
|
|
290
|
+
unless @output_file
|
|
291
|
+
raise %Q[Error: option "--output-index" must be used with option "-oNAME"]
|
|
292
|
+
end
|
|
261
293
|
|
|
262
|
-
# RMI
|
|
263
|
-
if output_index
|
|
264
|
-
if output_file
|
|
265
294
|
require "rd/rd2rmi-lib"
|
|
266
295
|
rmivisitor = RD2RMIVisitor.new
|
|
267
|
-
rmivisitor.filename = output_file
|
|
268
|
-
|
|
269
|
-
filename
|
|
270
|
-
|
|
271
|
-
file.print(rmi)
|
|
272
|
-
file.close
|
|
273
|
-
STDERR.print("#{$0}: output to #{filename}...\n")
|
|
274
|
-
else
|
|
275
|
-
raise %Q[Error: option "--output-index" must be used with option "-oNAME"]
|
|
296
|
+
rmivisitor.filename = @output_file
|
|
297
|
+
filename = @output_file + ".rmi"
|
|
298
|
+
File.open(filename, "w") { |file| file.print(rmivisitor.visit(tree)) }
|
|
299
|
+
@stderr.print("#{File.basename(@program_name)}: output to #{filename}...\n")
|
|
276
300
|
end
|
|
277
|
-
end
|
|
278
|
-
|
|
279
301
|
|
|
280
|
-
|
|
281
|
-
Dir.glob("#{RD::RDTree.tmp_dir}/rdtmp.#{$$}.*.*").each do |
|
|
282
|
-
|
|
302
|
+
def cleanup_tmp_files
|
|
303
|
+
Dir.glob("#{RD::RDTree.tmp_dir}/rdtmp.#{$$}.*.*").each do |path|
|
|
304
|
+
File.delete(path)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
283
307
|
end
|
|
308
|
+
|
|
309
|
+
exit(RD2Command.new.run)
|