aozora2html 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: edf21d2f7a57981dd8804564940a39eb9bd3f892
4
+ data.tar.gz: 677bcf4c4c1eb6db14f807e95ac2e46af9e3f75f
5
+ SHA512:
6
+ metadata.gz: 458e1fc1eaa839e90cb894a4d6f5d1bc23940b8b25737504b0838324957fd61f699488f988ea0e6cf7c85b78dce70b499a23270244b87b344ae7845b4c1e63ee
7
+ data.tar.gz: 4b739ed45adb2061e27e5cb4719814d84b1797b79020e20a63e7da8055cd6f2e3a903a030374ef351d4e3f992eb4c385a7c84ad9678b3b7e9a7dbb50fe117073
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *~
2
+ #*#
3
+ *.bak
4
+ pkg
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ sudo: false
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - ruby-head
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aozora2html.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,21 @@
1
+ guard :test do
2
+ watch(%r{^test/test_.+\.rb$})
3
+ watch('test/test_helper.rb') { 'test' }
4
+
5
+ # Non-rails
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
7
+
8
+ # Rails 4
9
+ # watch(%r{^app/(.+)\.rb}) { |m| "test/#{m[1]}_test.rb" }
10
+ # watch(%r{^app/controllers/application_controller\.rb}) { 'test/controllers' }
11
+ # watch(%r{^app/controllers/(.+)_controller\.rb}) { |m| "test/integration/#{m[1]}_test.rb" }
12
+ # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" }
13
+ # watch(%r{^lib/(.+)\.rb}) { |m| "test/lib/#{m[1]}_test.rb" }
14
+
15
+ # Rails < 4
16
+ # watch(%r{^app/models/(.+)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" }
17
+ # watch(%r{^app/controllers/(.+)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" }
18
+ # watch(%r{^app/views/(.+)/.+\.erb$}) { |m| "test/functional/#{m[1]}_controller_test.rb" }
19
+ # watch(%r{^app/views/.+$}) { 'test/integration' }
20
+ # watch('app/controllers/application_controller.rb') { ['test/functional', 'test/integration'] }
21
+ end
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # Aozora2Html
2
+
3
+ [![Build Status](https://travis-ci.org/aozorahack/aozora2html.svg?branch=master)](https://travis-ci.org/aozorahack/aozora2html)
4
+
5
+ 青空文庫の「組版案内」( http://kumihan.aozora.gr.jp/ )で配布されているtxt2html内にあるt2hs.rbを改造するプロジェクトです。
6
+
7
+ ## 動作環境
8
+
9
+ Ruby 2.0以上が推奨ですが、1.9でも動くはずです。
10
+
11
+ ## インストール
12
+
13
+ RubyGemsとしてインストール可能になっています。
14
+
15
+ ```
16
+ $ gem install aozora2html
17
+ ```
18
+
19
+ ソースからインストールするときは以下のようにします。
20
+
21
+ ```
22
+ $ gem install bundler
23
+ $ rake install
24
+ ```
25
+
26
+ ## 実行
27
+
28
+ コマンドは`aozora2html`です。以下のように実行します。
29
+
30
+ ```
31
+ $ aozora2html foo.txt foo.html
32
+ ```
33
+
34
+ こうすると、青空文庫記法で書かれたfoo.txtをfoo.htmlに変換します。
35
+
36
+ ## テスト
37
+
38
+ テストも追加しています。テストは以下のように実行します。
39
+
40
+ ```
41
+ $ bundle install
42
+ $ rake test
43
+ ```
44
+
45
+ ## License
46
+
47
+ CC0
48
+
49
+ To the extent possible under law, 青空文庫 has waived all copyright and related or neighboring rights to txt2xhtml. This work is published from Japan.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require "bundler/gem_tasks"
3
+ require 'rake/testtask'
4
+ require 'rake/clean'
5
+
6
+ task :default => [:test]
7
+
8
+ Rake::TestTask.new("test") do |t|
9
+ t.libs << "test"
10
+ t.test_files = Dir.glob("test/**/test_*.rb")
11
+ t.verbose = true
12
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aozora2html/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aozora2html"
8
+ spec.version = Aozora2Html::VERSION
9
+ spec.platform = Gem::Platform::RUBY
10
+ spec.license = "CC0"
11
+ spec.authors = ["aozorahack team"]
12
+ spec.email = ["takahashimm@gmail.com"]
13
+
14
+ spec.summary = %q{converter from Aozora Bunko format into xhtml. It's based of t2hs.rb from kumihan.aozora.gr.jp.}
15
+ spec.description = %q{converter from Aozora Bunko format into xhtml. It's based of t2hs.rb from kumihan.aozora.gr.jp.}
16
+ spec.homepage = "https://github.com/aozorahack/aozora2html"
17
+
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ spec.bindir = "bin"
20
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "test-unit"
27
+ spec.add_development_dependency "test-unit-rr"
28
+ # spec.add_development_dependency "test-unit-notify"
29
+ # spec.add_development_dependency "terminal-notifier"
30
+ spec.add_development_dependency "guard"
31
+ spec.add_development_dependency "guard-test"
32
+ end
data/bin/aozora2html ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'aozora2html'
4
+
5
+ # override Aozora2Html#push_chars
6
+ #
7
+ # Original Aozora2Html#push_chars does not convert "'" into '&#39;'; it's old behaivor
8
+ # of CGI.escapeHTML().
9
+ #
10
+ class Aozora2Html
11
+ def push_chars(obj)
12
+ if obj.is_a?(Array)
13
+ obj.each{|x|
14
+ push_chars(x)
15
+ }
16
+ elsif obj.is_a?(String)
17
+ if obj.length == 1
18
+ obj = obj.gsub(/[&\"<>]/, {'&' => '&amp;', '"' => '&quot;', '<' => '&lt;', '>' => '&gt;'})
19
+ end
20
+ obj.each_char{|x|
21
+ push_char(x)
22
+ }
23
+ else
24
+ push_char(obj)
25
+ end
26
+ end
27
+ end
28
+
29
+ def usage
30
+ $stderr.print "usage: aozora2html <text file> <html file>\n"
31
+ end
32
+
33
+ if ARGV.size != 2
34
+ usage
35
+ exit 1
36
+ end
37
+
38
+ if !File.exists?(ARGV[0])
39
+ $stderr.print "file not found: #{ARGV[0]}\n"
40
+ exit 1
41
+ end
42
+
43
+ Aozora2Html.new(ARGV[0],ARGV[1]).process
44
+
@@ -0,0 +1,6 @@
1
+ require "aozora2html/version"
2
+ require 't2hs.rb'
3
+
4
+ ## already defined in t2hs.rb
5
+ class Aozora2Html
6
+ end
@@ -0,0 +1,3 @@
1
+ class Aozora2Html
2
+ VERSION = "0.1.0"
3
+ end
data/lib/t2hs.rb ADDED
@@ -0,0 +1,2529 @@
1
+ # -*- coding:shift_jis -*-
2
+ # �‹󕶌Ɍ`���̃e�L�X�g�t�@�C���� html �ɐ��`���� ruby �X�N���v�g
3
+ require "cgi"
4
+
5
+ $gaiji_dir = "../../../gaiji/"
6
+
7
+ # 1.8 like to_s method to Array
8
+ class Array
9
+ def to_s
10
+ self.join
11
+ end
12
+ end
13
+
14
+ # ��Oclass
15
+ class Aozora_Exception < Exception
16
+ def initialize (message)
17
+ @message=message
18
+ end
19
+ end
20
+
21
+ class Aozora_Error < Aozora_Exception
22
+ def message (line)
23
+ "�G���[(#{line}�s��):#{@message}. \r\n�������~���܂�"
24
+ end
25
+ end
26
+
27
+ class Jstream
28
+ attr_accessor :line
29
+ def store_to_buffer
30
+ if tmp = @file.readline.chomp!("\r\n")
31
+ @buffer = tmp.each_char.to_a
32
+ else
33
+ raise Aozora_Error.new("���s�R�[�h���A�uCR+LF�v�ɂ��炽�߂Ă�������")
34
+ end
35
+ @entry = true
36
+ end
37
+ def initialize (file_io)
38
+ @line = 0
39
+ @entry = false
40
+ @file = file_io
41
+ begin
42
+ store_to_buffer
43
+ rescue Aozora_Exception => e
44
+ puts e.message(1)
45
+ if e.is_a?(Aozora_Error)
46
+ exit(2)
47
+ end
48
+ end
49
+ end
50
+ def inspect
51
+ "#<jcode-stream input " + @file.inspect + ">"
52
+ end
53
+ def read_char
54
+ found = @buffer.shift
55
+ if @entry
56
+ @line = @line + 1
57
+ @entry = false
58
+ end
59
+ if found
60
+ found
61
+ else
62
+ begin
63
+ store_to_buffer
64
+ "\r\n"
65
+ rescue EOFError
66
+ @buffer = [:eof]
67
+ "\r\n"
68
+ end
69
+ end
70
+ end
71
+ def peek_char (pos)
72
+ found = @buffer[pos]
73
+ if found
74
+ found
75
+ else
76
+ "\r\n"
77
+ end
78
+ end
79
+ def close
80
+ @file.close
81
+ end
82
+ end
83
+
84
+ # �ϊ������‹�L�@class
85
+ class Aozora_tag
86
+ # debug�p
87
+ def inspect
88
+ to_s
89
+ end
90
+
91
+ def syntax_error
92
+ raise Aozora_Error.new("���L���d�˂�ۂ̌����A�u�����͈͂��ɁA�L���͈͂���Ɂv������Ă��܂���B�����N��̎w�j���Q�l�ɁA�����������炽�߂Ă�������")
93
+ end
94
+ end
95
+
96
+ # �S�Ă̐‹�L�@��HTML element�ɕϊ������
97
+ # ���������āAblock/inline�̋�ʂ�����
98
+ # �S�Ă̖��[�‹�class�͂ǂ��炩��module��include����K�v������
99
+ module Inline_tag
100
+ def initialize (*args)
101
+ true
102
+ end
103
+ end
104
+
105
+ module Block_tag
106
+ # �K�v�Ɋ�Â�method override����
107
+ def close_tag
108
+ "</div>"
109
+ end
110
+ def initialize (parser, *args)
111
+ if parser.block_allowed_context?
112
+ nil
113
+ else
114
+ syntax_error
115
+ end
116
+ end
117
+ end
118
+
119
+ class Accent_tag < Aozora_tag
120
+ include Inline_tag
121
+ def initialize (parser, code, name)
122
+ @code = code
123
+ @name = name
124
+ super
125
+ end
126
+ def to_s
127
+ "<img src=\"#{$gaiji_dir}#{@code}.png\" alt=\"��(#{@name})\" class=\"gaiji\" />"
128
+ end
129
+ end
130
+
131
+ class Gaiji_tag < Aozora_tag
132
+ include Inline_tag
133
+ end
134
+
135
+ class Embed_Gaiji_tag < Gaiji_tag
136
+ def initialize (parser, folder, code, name)
137
+ @folder = folder
138
+ @code = code
139
+ @name = name
140
+ super
141
+ end
142
+ def to_s
143
+ "<img src=\"#{$gaiji_dir}#{@folder}/#{@code}.png\" alt=\"��(#{@name})\" class=\"gaiji\" />"
144
+ end
145
+ end
146
+
147
+ class UnEmbed_Gaiji_tag < Gaiji_tag
148
+ def initialize (parser, desc)
149
+ @desc = desc; @escaped = false
150
+ super
151
+ end
152
+ def to_s
153
+ '<span class="notes">�m' + @desc + '�n</span>'
154
+ end
155
+ def escaped?
156
+ @escaped
157
+ end
158
+ def escape!
159
+ @escaped = true
160
+ end
161
+ end
162
+
163
+ class Editor_note_tag < Aozora_tag
164
+ include Inline_tag
165
+ def initialize (parser, desc)
166
+ @desc = desc
167
+ super
168
+ end
169
+ def to_s
170
+ '<span class="notes">�m��' + @desc + '�n</span>'
171
+ end
172
+ end
173
+
174
+ class Indent_tag < Aozora_tag
175
+ include Block_tag
176
+ end
177
+
178
+ module Oneline_Indent_tag
179
+ end
180
+
181
+ module Multiline_tag
182
+ end
183
+
184
+ class Multiline_style_tag < Aozora_tag
185
+ include Block_tag, Multiline_tag
186
+ def initialize (parser, style)
187
+ @style = style
188
+ super
189
+ end
190
+ def to_s
191
+ "<div class=\"#{@style}\">"
192
+ end
193
+ end
194
+
195
+ class Font_size_tag < Aozora_tag
196
+ include Block_tag, Multiline_tag
197
+ def initialize (parser, times, daisho)
198
+ @class = daisho.to_s + times.to_s
199
+ @style = case times
200
+ when 1
201
+ ""
202
+ when 2
203
+ "x-"
204
+ else
205
+ if times >= 3
206
+ "xx-"
207
+ else
208
+ raise Aozora_Error.new("�����T�C�Y�̎w�肪�s���ł�")
209
+ end
210
+ end + case daisho
211
+ when :dai
212
+ "large"
213
+ when :sho
214
+ "small"
215
+ end
216
+ super
217
+ end
218
+ def to_s
219
+ "<div class=\"#{@class}\" style=\"font-size: #{@style};\">"
220
+ end
221
+ end
222
+
223
+ class Jizume_tag < Indent_tag
224
+ include Multiline_tag
225
+ def initialize (parser, width)
226
+ @w = width
227
+ super
228
+ end
229
+ def to_s
230
+ "<div class=\"jizume_#{@w}\" style=\"width: #{@w}em\">"
231
+ end
232
+ end
233
+
234
+ class Keigakomi_tag < Aozora_tag
235
+ include Block_tag, Multiline_tag
236
+ def initialize (parser, size = 1)
237
+ @size = size
238
+ super
239
+ end
240
+ def to_s
241
+ "<div class=\"keigakomi\" style=\"border: solid #{@size}px\">"
242
+ end
243
+ end
244
+
245
+ class Multiline_yokogumi_tag < Aozora_tag
246
+ include Block_tag, Multiline_tag
247
+ def initialize (parser)
248
+ super
249
+ end
250
+ def to_s
251
+ "<div class=\"yokogumi\">"
252
+ end
253
+ end
254
+
255
+ class Multiline_caption_tag < Aozora_tag
256
+ include Block_tag, Multiline_tag
257
+ def initialize (parser)
258
+ super
259
+ end
260
+ def to_s
261
+ "<div class=\"caption\">"
262
+ end
263
+ end
264
+
265
+ class Multiline_midashi_tag < Aozora_tag
266
+ include Block_tag, Multiline_tag
267
+ def initialize (parser,size,type)
268
+ super
269
+ @tag = if size.match("��")
270
+ @id = parser.new_midashi_id(1)
271
+ "h5"
272
+ elsif size.match("��")
273
+ @id = parser.new_midashi_id(10)
274
+ "h4"
275
+ elsif size.match("��")
276
+ @id = parser.new_midashi_id(100)
277
+ "h3"
278
+ else
279
+ raise Aozora_Error.new("����`�Ȍ��o���ł�")
280
+ end
281
+ @class = case type
282
+ when :normal
283
+ case @tag
284
+ when "h5"
285
+ "ko-midashi"
286
+ when "h4"
287
+ "naka-midashi"
288
+ when "h3"
289
+ "o-midashi"
290
+ end
291
+ when :dogyo
292
+ case @tag
293
+ when "h5"
294
+ "dogyo-ko-midashi"
295
+ when "h4"
296
+ "dogyo-naka-midashi"
297
+ when "h3"
298
+ "dogyo-o-midashi"
299
+ end
300
+ when :mado
301
+ case @tag
302
+ when "h5"
303
+ "mado-ko-midashi"
304
+ when "h4"
305
+ "mado-naka-midashi"
306
+ when "h3"
307
+ "mado-o-midashi"
308
+ end
309
+ else
310
+ raise Aozora_Error.new("����`�Ȍ��o���ł�")
311
+ end
312
+ end
313
+ def to_s
314
+ "<#{@tag} class=\"#{@class}\"><a class=\"midashi_anchor\" id=\"midashi#{@id}\">"
315
+ end
316
+ def close_tag
317
+ "</a></#{@tag}>"
318
+ end
319
+ end
320
+
321
+ class Jisage_tag < Indent_tag
322
+ def initialize (parser, width)
323
+ @width = width
324
+ super
325
+ end
326
+ def to_s
327
+ "<div class=\"jisage_#{@width}\" style=\"margin-left: #{@width}em\">"
328
+ end
329
+ end
330
+
331
+ class Oneline_Jisage_tag < Jisage_tag
332
+ include Oneline_Indent_tag
333
+ end
334
+ class Multiline_Jisage_tag < Jisage_tag
335
+ include Multiline_tag
336
+ end
337
+
338
+ class Chitsuki_tag < Indent_tag
339
+ def initialize (parser, length)
340
+ @length = length
341
+ super
342
+ end
343
+ def to_s
344
+ '<div class="chitsuki_' + @length + '" style="text-align:right; margin-right: ' + @length + 'em">'
345
+ end
346
+ end
347
+
348
+ class Oneline_Chitsuki_tag < Chitsuki_tag
349
+ include Oneline_Indent_tag
350
+ end
351
+
352
+
353
+ class Multiline_Chitsuki_tag < Chitsuki_tag
354
+ include Multiline_tag
355
+ end
356
+
357
+ # �O���Q�Ƃł����‚����͒��g���`�F�b�N����
358
+ # �q�v�f������Inline_tag�͑S�Ă����‚̃T�u�N���X
359
+ class Reference_mentioned_tag < Aozora_tag
360
+ include Inline_tag
361
+ attr_accessor :target
362
+ def block_element? (elt)
363
+ if elt.is_a?(Array)
364
+ elt.each{|x|
365
+ if block_element?(x)
366
+ return true
367
+ end
368
+ }
369
+ nil
370
+ elsif elt.is_a?(String)
371
+ elt.match(/<div/)
372
+ else
373
+ elt.is_a?(Block_tag)
374
+ end
375
+ end
376
+ def initialize (*args)
377
+ if block_element?(@target)
378
+ syntax_error
379
+ end
380
+ end
381
+ def target_string
382
+ if @target.is_a?(Reference_mentioned_tag)
383
+ @target.target_string
384
+ elsif @target.is_a?(Array)
385
+ @target.collect{|x|
386
+ if x.is_a?(Reference_mentioned_tag)
387
+ x.target_string
388
+ else
389
+ x
390
+ end}.to_s
391
+ else
392
+ @target
393
+ end
394
+ end
395
+ end
396
+
397
+ class Midashi_tag < Reference_mentioned_tag
398
+ def initialize (parser,target,size,type)
399
+ super
400
+ @target = target
401
+ @tag = if size.match("��")
402
+ @id = parser.new_midashi_id(1)
403
+ "h5"
404
+ elsif size.match("��")
405
+ @id = parser.new_midashi_id(10)
406
+ "h4"
407
+ elsif size.match("��")
408
+ @id = parser.new_midashi_id(100)
409
+ "h3"
410
+ else
411
+ raise Aozora_Error.new("����`�Ȍ��o���ł�")
412
+ end
413
+ @class = case type
414
+ when :normal
415
+ case @tag
416
+ when "h5"
417
+ "ko-midashi"
418
+ when "h4"
419
+ "naka-midashi"
420
+ when "h3"
421
+ "o-midashi"
422
+ end
423
+ when :dogyo
424
+ case @tag
425
+ when "h5"
426
+ "dogyo-ko-midashi"
427
+ when "h4"
428
+ "dogyo-naka-midashi"
429
+ when "h3"
430
+ "dogyo-o-midashi"
431
+ end
432
+ when :mado
433
+ case @tag
434
+ when "h5"
435
+ "mado-ko-midashi"
436
+ when "h4"
437
+ "mado-naka-midashi"
438
+ when "h3"
439
+ "mado-o-midashi"
440
+ end
441
+ else
442
+ raise Aozora_Error.new("����`�Ȍ��o���ł�")
443
+ end
444
+ end
445
+ def to_s
446
+ "<#{@tag} class=\"#{@class}\"><a class=\"midashi_anchor\" id=\"midashi#{@id}\">#{@target}</a></#{@tag}>"
447
+ end
448
+ end
449
+
450
+ # complex ruby markup
451
+ # if css3 is major supported, please fix ruby position with property "ruby-position"
452
+ # see also: http://www.w3.org/TR/2001/WD-css3-ruby-20010216/
453
+ class Ruby_tag < Reference_mentioned_tag
454
+ attr_accessor :ruby, :under_ruby
455
+ def initialize (parser, string, ruby, under_ruby = "")
456
+ @target = string; @ruby = ruby; @under_ruby = under_ruby
457
+ super
458
+ end
459
+
460
+ def gen_rt (string)
461
+ if string != ""
462
+ "<rt class=\"real_ruby\">#{string}</rt>"
463
+ else
464
+ "<rt class=\"dummy_ruby\"></rt>"
465
+ end
466
+ end
467
+
468
+ def to_s
469
+ "<ruby><rb>#{@target.to_s}</rb><rp>�i</rp><rt>#{@ruby.to_s}</rt><rp>�j</rp></ruby>"
470
+ end
471
+
472
+ # complex ruby is waiting for IE support and CSS3 candidate
473
+ =begin
474
+ def to_s
475
+ ans = "<ruby class=\"complex_ruby\"><rbc>" # indicator of new version of aozora ruby
476
+ if @ruby.is_a?(Array) and @ruby.length > 0
477
+ # cell is used
478
+ @rbspan = @ruby.length
479
+ end
480
+ if @under_ruby.is_a?(Array) and @under_ruby.length > 0
481
+ # cell is used, but two way cell is not supported
482
+ if @rbspan
483
+ raise Aozora_Error.new("�T�|�[�g����Ă��Ȃ����G�ȃ��r�t���ł�")
484
+ else
485
+ @rbspan = @under_ruby.length
486
+ end
487
+ end
488
+
489
+ # target
490
+ if @rbspan
491
+ @target.each{|x|
492
+ ans.concat("<rb>#{x.to_s}</rb>")
493
+ }
494
+ else
495
+ ans.concat("<rb>#{@target.to_s}</rb>")
496
+ end
497
+
498
+ ans.concat("</rbc><rtc>")
499
+
500
+ # upper ruby
501
+ if @ruby.is_a?(Array)
502
+ @ruby.each{|x|
503
+ ans.concat(gen_rt(x))
504
+ }
505
+ elsif @rbspan
506
+ if @ruby != ""
507
+ ans.concat("<rt class=\"real_ruby\" rbspan=\"#{@rbspan}\">#{@ruby}</rt>")
508
+ else
509
+ ans.concat("<rt class=\"dummy_ruby\" rbspan=\"#{@rbspan}\"></rt>")
510
+ end
511
+ else
512
+ ans.concat(gen_rt(@ruby))
513
+ end
514
+
515
+ ans.concat("</rtc>")
516
+
517
+ # under_ruby (if exists)
518
+ if @under_ruby.length > 0
519
+ ans.concat("<rtc>")
520
+ if @under_ruby.is_a?(Array)
521
+ @under_ruby.each{|x|
522
+ ans.concat(gen_rt(x))
523
+ }
524
+ elsif @rbspan
525
+ ans.concat("<rt class=\"real_ruby\" rbspan=\"#{@rbspan}\">#{@under_ruby}</rt>")
526
+ else
527
+ ans.concat(gen_rt(@under_ruby))
528
+ end
529
+ ans.concat("</rtc>")
530
+ end
531
+
532
+ # finalize
533
+ ans.concat("</ruby>")
534
+
535
+ ans
536
+ end
537
+ =end
538
+ end
539
+
540
+ class Kunten_tag < Aozora_tag
541
+ include Inline_tag
542
+ end
543
+
544
+ class Kaeriten_tag < Kunten_tag
545
+ def initialize (parser, string)
546
+ @string = string
547
+ super
548
+ end
549
+ def to_s
550
+ "<sub class=\"kaeriten\">#{@string.to_s}</sub>"
551
+ end
552
+ end
553
+
554
+ class Okurigana_tag < Kunten_tag
555
+ def initialize (parser, string)
556
+ @string = string
557
+ super
558
+ end
559
+ def to_s
560
+ "<sup class=\"okurigana\">#{@string.to_s}</sup>"
561
+ end
562
+ end
563
+
564
+ class Inline_keigakomi_tag < Reference_mentioned_tag
565
+ def initialize (parser, target)
566
+ @target = target
567
+ super
568
+ end
569
+ def to_s
570
+ "<span class=\"keigakomi\">#{@target.to_s}</span>"
571
+ end
572
+ end
573
+
574
+ class Inline_yokogumi_tag < Reference_mentioned_tag
575
+ def initialize (parser, target)
576
+ @target = target
577
+ super
578
+ end
579
+ def to_s
580
+ "<span class=\"yokogumi\">#{@target.to_s}</span>"
581
+ end
582
+ end
583
+
584
+ class Inline_caption_tag < Reference_mentioned_tag
585
+ def initialize (parser, target)
586
+ @target = target
587
+ super
588
+ end
589
+ def to_s
590
+ "<span class=\"caption\">#{@target.to_s}</span>"
591
+ end
592
+ end
593
+
594
+ class Inline_font_size_tag < Reference_mentioned_tag
595
+ def initialize (parser, target, times, daisho)
596
+ @target = target
597
+ @class = daisho.to_s + times.to_s
598
+ @style = case times
599
+ when 1
600
+ ""
601
+ when 2
602
+ "x-"
603
+ else
604
+ if times >= 3
605
+ "xx-"
606
+ else
607
+ raise Aozora_Error.new("�����T�C�Y�̎w�肪�s���ł�")
608
+ end
609
+ end + case daisho
610
+ when :dai
611
+ "large"
612
+ when :sho
613
+ "small"
614
+ end
615
+ super
616
+ end
617
+ def to_s
618
+ "<span class=\"#{@class}\" style=\"font-size: #{@style};\">" + @target.to_s + "</span>"
619
+ end
620
+ end
621
+
622
+ class Decorate_tag < Reference_mentioned_tag
623
+ def initialize (parser, target, html_class, html_tag)
624
+ @target = target; @close = "</#{html_tag}>"
625
+ @open = "<#{html_tag} class=\"#{html_class}\">"
626
+ super
627
+ end
628
+ def to_s
629
+ @open+@target.to_s+@close
630
+ end
631
+ end
632
+
633
+ class Dakuten_katakana_tag < Aozora_tag
634
+ include Inline_tag
635
+ def initialize (parser, n, katakana)
636
+ @n = n; @katakana = katakana
637
+ super
638
+ end
639
+ def to_s
640
+ "<img src=\"#{$gaiji_dir}/1-07/1-07-8#{@n}.png\" alt=\"��(���_�t���Љ����u#{@katakana}�v�A1-07-8#{@n})\" class=\"gaiji\" />"
641
+ end
642
+ end
643
+
644
+ class Dir_tag < Reference_mentioned_tag
645
+ def initialize (parser, target)
646
+ @target = target
647
+ super
648
+ end
649
+ def to_s
650
+ "<span dir=\"ltr\">#{@target.to_s}</span>"
651
+ end
652
+ end
653
+
654
+ class Img_tag < Aozora_tag
655
+ include Inline_tag
656
+ def initialize (parser, filename, css_class, alt, width, height)
657
+ @filename = filename; @css_class = css_class; @alt = alt; @width = width; @height = height
658
+ super
659
+ end
660
+ def to_s
661
+ "<img class=\"#{@css_class}\" width=\"#{@width}\" height=\"#{@height}\" src=\"#{@filename}\" alt=\"#{@alt}\" />"
662
+ end
663
+ end
664
+
665
+ # tag��`�I���
666
+
667
+ # �ϊ���{��
668
+ class Aozora2Html
669
+ # �S�p�o�b�N�X���b�V�����o���Ȃ����璼�ł�
670
+ @@ku = ["18e5"].pack("h*")
671
+ @@noji = ["18f5"].pack("h*")
672
+ @@dakuten = ["18d8"].pack("h*")
673
+ # @@kunoji = ["18e518f5"].pack("h*")
674
+ # utf8 ["fecbf8fecbcb"].pack("h*")
675
+ # @@dakutenkunoji = ["18e518d818f5"].pack("h*")
676
+ # utf8 ["fecbf82e083bfecbcb"].pack("h*")
677
+ @@accent_table = {
678
+ "!"=>{
679
+ "@"=>["1-09/1-09-03","�t���Q��"]
680
+ },
681
+ "?"=>{
682
+ "@"=>["1-09/1-09-22","�t�^�╄"]
683
+ },
684
+ "A"=>{
685
+ "`"=>["1-09/1-09-23","�O���[�u�A�N�Z���g�t��A"],
686
+ "'"=>["1-09/1-09-24","�A�L���[�g�A�N�Z���g�t��A"],
687
+ "^"=>["1-09/1-09-25","�T�[�J���t���b�N�X�A�N�Z���g�t��"],
688
+ "~"=>["1-09/1-09-26","�`���h�t��A"],
689
+ ":"=>["1-09/1-09-27","�_�C�G���V�X�t��A"],
690
+ "&"=>["1-09/1-09-28","�ナ���O�t��A"],
691
+ "_"=>["1-09/1-09-85","�}�N�����t��A"],
692
+ "E"=>{"&"=>["1-09/1-09-29","���K�`��AE"]}
693
+ },
694
+ "C"=>{
695
+ ","=>["1-09/1-09-30","�Z�f�B���t��C"]
696
+ },
697
+ "E"=>{
698
+ "`"=>["1-09/1-09-31","�O���[�u�A�N�Z���g�t��E"],
699
+ "'"=>["1-09/1-09-32","�A�L���[�g�A�N�Z���g�t��E"],
700
+ "^"=>["1-09/1-09-33","�T�[�J���t���b�N�X�A�N�Z���g�t��E"],
701
+ ":"=>["1-09/1-09-34","�_�C�G���V�X�t��E"],
702
+ "_"=>["1-09/1-09-88","�}�N�����t��E"]
703
+ },
704
+ "I"=>{
705
+ "`"=>["1-09/1-09-35","�O���[�u�A�N�Z���g�t��I"],
706
+ "'"=>["1-09/1-09-36","�A�L���[�g�A�N�Z���g�t��I"],
707
+ "^"=>["1-09/1-09-37","�T�[�J���t���b�N�X�A�N�Z���g�t��I"],
708
+ ":"=>["1-09/1-09-38","�_�C�G���V�X�t��I"],
709
+ "_"=>["1-09/1-09-86","�}�N�����t��I"]
710
+ },
711
+ "N"=>{
712
+ "~"=>["1-09/1-09-40","�`���h�t��N"]
713
+ },
714
+ "O"=>{
715
+ "`"=>["1-09/1-09-41","�O���[�u�A�N�Z���g�t��O"],
716
+ "'"=>["1-09/1-09-42","�A�L���[�g�A�N�Z���g�t��O"],
717
+ "^"=>["1-09/1-09-43","�T�[�J���t���b�N�X�A�N�Z���g�t��O"],
718
+ "~"=>["1-09/1-09-44","�`���h�t��O"],
719
+ ":"=>["1-09/1-09-45","�_�C�G���V�X�t��O"],
720
+ "/"=>["1-09/1-09-46","�X�g���[�N�t��O"],
721
+ "_"=>["1-09/1-09-89","�}�N�����t��O"],
722
+ "E"=>{"&"=>["1-11/1-11-11","���K�`��OE�啶��"]}
723
+ },
724
+ "U"=>{
725
+ "`"=>["1-09/1-09-47","�O���[�u�A�N�Z���g�t��U"],
726
+ "'"=>["1-09/1-09-48","�A�L���[�g�A�N�Z���g�t��U"],
727
+ "^"=>["1-09/1-09-49","�T�[�J���t���b�N�X�A�N�Z���g�t��U"],
728
+ ":"=>["1-09/1-09-50","�_�C�G���V�X�t��U"],
729
+ "_"=>["1-09/1-09-87","�}�N�����t��U"]
730
+ },
731
+ "Y"=>{
732
+ "'"=>["1-09/1-09-51","�A�L���[�g�A�N�Z���g�t��Y"]
733
+ },
734
+ "s"=>{
735
+ "&"=>["1-09/1-09-53","�h�C�c��G�X�c�F�b�g"]
736
+ },
737
+ "a"=>{
738
+ "`"=>["1-09/1-09-54","�O���[�u�A�N�Z���g�t��A������"],
739
+ "'"=>["1-09/1-09-55","�A�L���[�g�A�N�Z���g�t��A������"],
740
+ "^"=>["1-09/1-09-56","�T�[�J���t���b�N�X�A�N�Z���g�t��A������"],
741
+ "~"=>["1-09/1-09-57","�`���h�t��A������"],
742
+ ":"=>["1-09/1-09-58","�_�C�G���V�X�t��A������"],
743
+ "&"=>["1-09/1-09-59","�ナ���O�t��A������"],
744
+ "_"=>["1-09/1-09-90","�}�N�����t��A������"],
745
+ "e"=>{"&"=>["1-09/1-09-60","���K�`��AE������"]}
746
+ },
747
+ "c"=>{
748
+ ","=>["1-09/1-09-61","�Z�f�B���t��C������"]
749
+ },
750
+ "e"=>{
751
+ "`"=>["1-09/1-09-62","�O���[�u�A�N�Z���g�t��E������"],
752
+ "'"=>["1-09/1-09-63","�A�L���[�g�A�N�Z���g�t��E������"],
753
+ "^"=>["1-09/1-09-64","�T�[�J���t���b�N�X�A�N�Z���g�t��E������"],
754
+ ":"=>["1-09/1-09-65","�_�C�G���V�X�t��E������"],
755
+ "_"=>["1-09/1-09-93","�}�N�����t��E������"]
756
+ },
757
+ "i"=>{
758
+ "`"=>["1-09/1-09-66","�O���[�u�A�N�Z���g�t��I������"],
759
+ "'"=>["1-09/1-09-67","�A�L���[�g�A�N�Z���g�t��I������"],
760
+ "^"=>["1-09/1-09-68","�T�[�J���t���b�N�X�A�N�Z���g�t��I������"],
761
+ ":"=>["1-09/1-09-69","�_�C�G���V�X�t��I������"],
762
+ "_"=>["1-09/1-09-91","�}�N�����t��I������"]
763
+ },
764
+ "n"=>{
765
+ "~"=>["1-09/1-09-71","�`���h�t��N������"]
766
+ },
767
+ "o"=>{
768
+ "`"=>["1-09/1-09-72","�O���[�u�A�N�Z���g�t��O������"],
769
+ "'"=>["1-09/1-09-73","�A�L���[�g�A�N�Z���g�t��O������"],
770
+ "^"=>["1-09/1-09-74","�T�[�J���t���b�N�X�A�N�Z���g�t��O������"],
771
+ "~"=>["1-09/1-09-75","�`���h�t��O������"],
772
+ ":"=>["1-09/1-09-76","�_�C�G���V�X�t��O������"],
773
+ "_"=>["1-09/1-09-94","�}�N�����t��O������"],
774
+ "/"=>["1-09/1-09-77","�X�g���[�N�t��O������"],
775
+ "e"=>{"&"=>["1-11/1-11-10","���K�`��OE������"]}
776
+ },
777
+ "u"=>{
778
+ "`"=>["1-09/1-09-78","�O���[�u�A�N�Z���g�t��U������"],
779
+ "'"=>["1-09/1-09-79","�A�L���[�g�A�N�Z���g�t��U������"],
780
+ "^"=>["1-09/1-09-80","�T�[�J���t���b�N�X�A�N�Z���g�t��U������"],
781
+ "_"=>["1-09/1-09-92","�}�N�����t��U������"],
782
+ ":"=>["1-09/1-09-81","�_�C�G���V�X�t��U������"]
783
+ },
784
+ "y"=>{
785
+ "'"=>["1-09/1-09-82","�A�L���[�g�A�N�Z���g�t��Y������"],
786
+ ":"=>["1-09/1-09-84","�_�C�G���V�X�t��Y������"]
787
+ }
788
+ }
789
+ # [class, tag]
790
+ @@command_table = {
791
+ "�T�_" => ["sesame_dot","em"],
792
+ "���S�}�T�_" => ["white_sesame_dot","em"],
793
+ "�ۖT�_" => ["black_circle","em"],
794
+ "���ۖT�_" => ["white_circle","em"],
795
+ "���O�p�T�_" => ["black_up-pointing_triangle","em"],
796
+ "���O�p�T�_" => ["white_up-pointing_triangle","em"],
797
+ "��d�ۖT�_" => ["bullseye","em"],
798
+ "�ւ̖ږT�_" => ["fisheye","em"],
799
+ "�΂–T�_" => ["saltire", "em"],
800
+ "�T��"=> ["underline_solid","em"],
801
+ "��d�T��"=> ["underline_double","em"],
802
+ "����"=> ["underline_dotted","em"],
803
+ "�j��"=> ["underline_dashed","em"],
804
+ "�g��"=> ["underline_wave","em"],
805
+ "����"=> ["futoji","span"],
806
+ "�Α�"=> ["shatai","span"],
807
+ "���t��������"=>["subscript","sub"],
808
+ "��t��������"=>["superscript","sup"],
809
+ "�s�E������"=>["superscript","sup"],
810
+ "�s��������"=>["subscript","sub"]
811
+ }
812
+ def initialize (input, output)
813
+ @stream = Jstream.new(File.open(input,"r:Shift_JIS"))
814
+ @buffer = []; @ruby_buf = [""]; @ruby_char_type = nil
815
+ @out = File.open(output,"w"); @section = :head; @header = []; @style_stack = []
816
+ @chuuki_table = {}; @images = []; @indent_stack = []; @tag_stack = []
817
+ @midashi_id = 0; @terprip = true
818
+ @endchar = :eof
819
+ end
820
+
821
+ def scount
822
+ @stream.line
823
+ end
824
+
825
+ def block_allowed_context?
826
+ # inline_tag���J���Ă��Ȃ����`�F�b�N����Ώ\��
827
+ not(@style_stack.last)
828
+ end
829
+
830
+ def read_char
831
+ @stream.read_char
832
+ end
833
+
834
+ def read_to (endchar)
835
+ buf=""
836
+ loop{
837
+ char=@stream.read_char
838
+ if char==endchar
839
+ break
840
+ else
841
+ if char.kind_of?(Symbol)
842
+ print endchar
843
+ end
844
+ buf.concat(char)
845
+ end}
846
+ buf
847
+ end
848
+
849
+ def read_accent
850
+ Aozora_accent_parser.new(@stream,"�l",@chuuki_table,@images).process
851
+ end
852
+
853
+ def read_to_nest (endchar)
854
+ Aozora_tag_parser.new(@stream,endchar,@chuuki_table,@images).process
855
+ end
856
+
857
+ def read_line
858
+ tmp=read_to("\r\n")
859
+ @buffer=[]
860
+ tmp
861
+ end
862
+
863
+ def process ()
864
+ catch(:terminate){
865
+ loop{
866
+ begin
867
+ parse
868
+ rescue Aozora_Exception => e
869
+ puts e.message(scount)
870
+ if e.is_a?(Aozora_Error)
871
+ exit(2)
872
+ end
873
+ end
874
+ }
875
+ }
876
+ tail_output # final call
877
+ finalize
878
+ close
879
+ end
880
+
881
+ def char_type (char)
882
+ if char.is_a?(Accent_tag)
883
+ :hankaku
884
+ elsif char.is_a?(Gaiji_tag)
885
+ :kanji
886
+ elsif char.is_a?(Kunten_tag) # just remove this line
887
+ :else
888
+ elsif char.is_a?(Dakuten_katakana_tag)
889
+ :katakana
890
+ elsif char.is_a?(Aozora_tag)
891
+ :else
892
+ elsif char.match(/[��-��T�U]/)
893
+ :hiragana
894
+ elsif char.match(/[�@-���[�R�S��]/)
895
+ :katakana
896
+ elsif char.match(/[�O-�X�`-�y��-����-����-�ք@-�`�p-���|���f�C�D]/)
897
+ :zenkaku
898
+ elsif char.match(/[A-Za-z0-9#\-\&'\,]/)
899
+ :hankaku
900
+ elsif char.match(/[��-꤁X���W�Y�Z��]/)
901
+ :kanji
902
+ elsif char.match(/[\.\;\"\?\!\)]/)
903
+ :hankaku_terminate
904
+ else
905
+ :else
906
+ end
907
+ end
908
+
909
+ def finalize ()
910
+ hyoki
911
+ dynamic_contents
912
+ @out.print("</body>\r\n</html>\r\n")
913
+ end
914
+
915
+ def dynamic_contents
916
+ @out.print("<div id=\"card\">\r\n<hr />\r\n<br />\r\n")
917
+ @out.print("<a href=\"JavaScript:goLibCard();\" id=\"goAZLibCard\">���}���J�[�h</a>")
918
+ @out.print("<script type=\"text/javascript\" src=\"../../contents.js\"></script>\r\n")
919
+ @out.print("<script type=\"text/javascript\" src=\"../../golibcard.js\"></script>\r\n")
920
+ @out.print("</div>")
921
+ end
922
+
923
+ def close ()
924
+ @stream.close
925
+ @out.close
926
+ end
927
+
928
+ def convert_indent_type (type)
929
+ case type
930
+ when :jisage
931
+ "������"
932
+ when :chitsuki
933
+ "�n�t��"
934
+ when :keigakomi
935
+ "�r�͂�"
936
+ when :caption
937
+ "�L���v�V����"
938
+ when :jizume
939
+ "���l��"
940
+ when :futoji
941
+ "����"
942
+ when :shatai
943
+ "�Α�"
944
+ when :sho
945
+ "�����ȕ���"
946
+ when :dai
947
+ "�傫�ȕ���"
948
+ else
949
+ type
950
+ end
951
+ end
952
+
953
+ def check_close_match (type)
954
+ ind = if @indent_stack.last.is_a?(String)
955
+ @noprint = true
956
+ :jisage
957
+ else
958
+ @indent_stack.last
959
+ end
960
+ if ind == type
961
+ nil
962
+ else
963
+ convert_indent_type(type)
964
+ end
965
+ end
966
+
967
+ def implicit_close (type)
968
+ if @indent_stack.last
969
+ if n = check_close_match(type)
970
+ # ok, nested multiline tags, go ahead
971
+ else
972
+ # not nested, please close
973
+ @indent_stack.pop
974
+ if tag = @tag_stack.pop
975
+ push_chars(tag)
976
+ end
977
+ end
978
+ end
979
+ end
980
+
981
+ def ensure_close
982
+ if n = @indent_stack.last
983
+ raise Aozora_Error.new("#{convert_indent_type(n)}���ɖ{�����I�����܂���")
984
+ end
985
+ end
986
+
987
+ def explicit_close (type)
988
+ if n = check_close_match(type)
989
+ raise Aozora_Error.new("#{n}��‚��悤�Ƃ��܂������A#{n}���ł͂���܂���")
990
+ end
991
+ if tag = @tag_stack.pop
992
+ push_chars(tag)
993
+ end
994
+ end
995
+
996
+ # main loop
997
+ def parse
998
+ case @section
999
+ when :head
1000
+ parse_header
1001
+ when :head_end
1002
+ judge_chuuki
1003
+ when :chuuki, :chuuki_in
1004
+ parse_chuuki
1005
+ when :body
1006
+ parse_body
1007
+ when :tail
1008
+ parse_tail
1009
+ else
1010
+ Aozora_Error.new("encount undefined condition")
1011
+ end
1012
+ end
1013
+
1014
+ def judge_chuuki
1015
+ # ���L�����邩�ǂ����`�F�b�N
1016
+ i=0
1017
+ loop{
1018
+ case @stream.peek_char(i)
1019
+ when "-"
1020
+ i=i+1
1021
+ when "\r\n"
1022
+ @section = :chuuki
1023
+ return
1024
+ else
1025
+ @section = :body
1026
+ @out.print("<br />\r\n")
1027
+ return
1028
+ end
1029
+ }
1030
+ end
1031
+
1032
+ # header�͈�s���“ǂ�
1033
+ def parse_header
1034
+ string = read_line
1035
+ # refine from Tomita 09/06/14
1036
+ if (string == "") # ��s������΁A�����Ńw�b�_�[�I���Ƃ݂Ȃ�
1037
+ @section = :head_end
1038
+ process_header
1039
+ else
1040
+ string.gsub!(/�b/,"")
1041
+ string.gsub!(/�s.*?�t/,"")
1042
+ @header.push(string)
1043
+ end
1044
+ end
1045
+
1046
+ def html_title_push (string, hash, attr)
1047
+ found = hash[attr]
1048
+ if found
1049
+ if found != ""
1050
+ string + " " + found
1051
+ else
1052
+ found
1053
+ end
1054
+ else
1055
+ string
1056
+ end
1057
+ end
1058
+
1059
+ def out_header_info (hash, attr, true_name = nil)
1060
+ found = hash[attr]
1061
+ if found
1062
+ @out.print("<h2 class=\"#{true_name or attr}\">#{found}</h2>\r\n")
1063
+ end
1064
+ end
1065
+
1066
+ def header_element_type (string)
1067
+ original = true
1068
+ string.each_char{|x|
1069
+ code = x.unpack("H*")[0]
1070
+ if ("00" <= code and code <= "7f") or # 1byte
1071
+ ("8140" <= code and code <= "8258") or # 1-1, 3-25
1072
+ ("839f" <= code and code <= "8491") # 6-1, 7-81
1073
+ # continue
1074
+ else
1075
+ original = false
1076
+ break
1077
+ end
1078
+ }
1079
+ if original
1080
+ :original
1081
+ elsif string.match(/[�Z��|��|�ҏW|�ҏW�Z��|�Z���ҏW]$/)
1082
+ :editor
1083
+ elsif string.match(/�Җ�$/)
1084
+ :henyaku
1085
+ elsif string.match(/��$/)
1086
+ :translator
1087
+ end
1088
+ end
1089
+
1090
+ def process_person (string,header_info)
1091
+ type = header_element_type(string)
1092
+ case type
1093
+ when :editor
1094
+ header_info[:editor] = string
1095
+ when :translator
1096
+ header_info[:translator] = string
1097
+ when :henyaku
1098
+ header_info[:henyaku] = string
1099
+ else
1100
+ type = :author
1101
+ header_info[:author] = string
1102
+ end
1103
+ type
1104
+ end
1105
+
1106
+ def process_header()
1107
+ header_info = {:title=>@header[0]}
1108
+ case @header.length
1109
+ when 2
1110
+ process_person(@header[1],header_info)
1111
+ when 3
1112
+ if header_element_type(@header[1]) == :original
1113
+ header_info[:original_title] = @header[1]
1114
+ process_person(@header[2],header_info)
1115
+ elsif process_person(@header[2],header_info) == :author
1116
+ header_info[:subtitle] = @header[1]
1117
+ else
1118
+ header_info[:author] = @header[1]
1119
+ end
1120
+ when 4
1121
+ if header_element_type(@header[1]) == :original
1122
+ header_info[:original_title] = @header[1]
1123
+ else
1124
+ header_info[:subtitle] = @header[1]
1125
+ end
1126
+ if process_person(@header[3],header_info) == :author
1127
+ header_info[:subtitle] = @header[2]
1128
+ else
1129
+ header_info[:author] = @header[2]
1130
+ end
1131
+ when 5
1132
+ header_info[:original_title] = @header[1]
1133
+ header_info[:subtitle] = @header[2]
1134
+ header_info[:author] = @header[3]
1135
+ if process_person(@header[4],header_info) == :author
1136
+ raise Aozora_Error.new("parser encounted author twice")
1137
+ end
1138
+ when 6
1139
+ header_info[:original_title] = @header[1]
1140
+ header_info[:subtitle] = @header[2]
1141
+ header_info[:original_subtitle] = @header[3]
1142
+ header_info[:author] = @header[4]
1143
+ if process_person(@header[5],header_info) == :author
1144
+ raise Aozora_Error.new("parser encounted author twice")
1145
+ end
1146
+ end
1147
+
1148
+ # <title> �s���\�z
1149
+ html_title = "<title>#{header_info[:author]}"
1150
+ html_title = html_title_push(html_title, header_info, :translator)
1151
+ html_title = html_title_push(html_title, header_info, :editor)
1152
+ html_title = html_title_push(html_title, header_info, :henyaku)
1153
+ html_title = html_title_push(html_title, header_info, :title)
1154
+ html_title = html_title_push(html_title, header_info, :original_title)
1155
+ html_title = html_title_push(html_title, header_info, :subtitle)
1156
+ html_title = html_title_push(html_title, header_info, :original_subtitle)
1157
+ html_title += "</title>"
1158
+
1159
+ # �o��
1160
+ @out.print("<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\r\n \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"ja\" >\r\n<head>\r\n <meta http-equiv=\"Content-Type\" content=\"text/html;charset=Shift_JIS\" />\r\n <meta http-equiv=\"content-style-type\" content=\"text/css\" />\r\n <link rel=\"stylesheet\" type=\"text/css\" href=\"../../aozora.css\" />\r\n\t#{html_title}\r\n <script type=\"text/javascript\" src=\"../../jquery-1.4.2.min.js\"></script>\r\n <link rel=\"Schema.DC\" href=\"http://purl.org/dc/elements/1.1/\" />\r\n <meta name=\"DC.Title\" content=\"#{header_info[:title]}\" />\r\n <meta name=\"DC.Creator\" content=\"#{header_info[:author]}\" />\r\n <meta name=\"DC.Publisher\" content=\"�‹󕶌�\" />\r\n</head>\r\n<body>\r\n<div class=\"metadata\">\r\n")
1161
+ @out.print("<h1 class=\"title\">#{header_info[:title]}</h1>\r\n")
1162
+ out_header_info(header_info, :original_title)
1163
+ out_header_info(header_info, :subtitle)
1164
+ out_header_info(header_info, :original_subtitle)
1165
+ out_header_info(header_info, :author)
1166
+ out_header_info(header_info, :editor)
1167
+ out_header_info(header_info, :translator)
1168
+ out_header_info(header_info, :henyaku, "editor-translator")
1169
+ @out.print("<br />\r\n<br />\r\n</div>\r\n<div id=\"contents\" style=\"display:none\"></div><div class=\"main_text\">")
1170
+ end
1171
+
1172
+ def parse_chuuki
1173
+ string = read_line
1174
+ if (string.match(/^\-+$/))
1175
+ case @section
1176
+ when :chuuki
1177
+ @section = :chuuki_in
1178
+ when :chuuki_in
1179
+ @section = :body
1180
+ end
1181
+ end
1182
+ end
1183
+
1184
+ def illegal_char_check (char)
1185
+ if char.is_a?(String)
1186
+ code = char.unpack("H*")[0]
1187
+ if code == "21" or
1188
+ code == "23" or
1189
+ ("a1" <= code and code <= "a5") or
1190
+ ("28" <= code and code<= "29") or
1191
+ code == "5b" or
1192
+ code == "5d" or
1193
+ code == "3d" or
1194
+ code == "3f" or
1195
+ code == "2b" or
1196
+ ("7b" <= code and code <= "7d")
1197
+ puts "�x��(#{scount}�s��):1�o�C�g�́u#{char}�v���g���Ă��܂�"
1198
+ end
1199
+
1200
+ if code == "81f2"
1201
+ puts "�x��(#{scount}�s��):���L�L���̌�p�̉”\��������A�u#{char}�v���g���Ă��܂�"
1202
+ end
1203
+
1204
+ if ("81ad" <= code and code <= "81b7") or
1205
+ ("81c0" <= code and code <= "81c7") or
1206
+ ("81cf" <= code and code <= "81d9") or
1207
+ ("81e9" <= code and code <= "81ef") or
1208
+ ("81f8" <= code and code <= "81fb") or
1209
+ ("8240" <= code and code <= "824e") or
1210
+ ("8259" <= code and code <= "825f") or
1211
+ ("827a" <= code and code <= "8280") or
1212
+ ("829b" <= code and code <= "829e") or
1213
+ ("82f2" <= code and code <= "82fc") or
1214
+ ("8397" <= code and code <= "839e") or
1215
+ ("83b7" <= code and code <= "83be") or
1216
+ ("83d7" <= code and code <= "83fc") or
1217
+ ("8461" <= code and code <= "846f") or
1218
+ ("8492" <= code and code <= "849e") or
1219
+ ("84bf" <= code and code <= "84fc") or
1220
+ ("8540" <= code and code <= "85fc") or
1221
+ ("8640" <= code and code <= "86fc") or
1222
+ ("8740" <= code and code <= "87fc") or
1223
+ ("8840" <= code and code <= "889e") or
1224
+ ("9873" <= code and code <= "989e") or
1225
+ ("eaa5" <= code and code <= "eafc") or
1226
+ ("eb40" <= code and code <= "ebfc") or
1227
+ ("ec40" <= code and code <= "ecfc") or
1228
+ ("ed40" <= code and code <= "edfc") or
1229
+ ("ee40" <= code and code <= "eefc") or
1230
+ ("ef40" <= code and code <= "effc")
1231
+ puts "�x��(#{scount}�s��):JIS�O���u#{char}�v���g���Ă��܂�"
1232
+ end
1233
+ end
1234
+ end
1235
+
1236
+ # �{�̉�͕�
1237
+ # 1�������“ǂݍ��݁Adispatch����@buffer,@ruby_buf�ւ��܂�
1238
+ # ���s�R�[�h�ɓ��������痭�ߍ��񂾂��̂�general_output����
1239
+
1240
+ def parse_body
1241
+ char = read_char
1242
+ check = true
1243
+ case char
1244
+ when "�k"
1245
+ check = false
1246
+ char = read_accent
1247
+ when "��"
1248
+ if @buffer.length == 0
1249
+ ending_check
1250
+ end
1251
+ when "��"
1252
+ char = dispatch_gaiji
1253
+ when "�m"
1254
+ char = dispatch_aozora_command
1255
+ when @@ku
1256
+ assign_kunoji
1257
+ when "�s"
1258
+ char = apply_ruby
1259
+ end
1260
+ if char == "\r\n"
1261
+ general_output
1262
+ elsif char == "�b"
1263
+ ruby_buf_dump
1264
+ @ruby_buf_protected = true
1265
+ elsif char == @endchar
1266
+ # suddenly finished the file
1267
+ puts "�x��(#{scount}�s��):�\�����ʃt�@�C���I�["
1268
+ throw :terminate
1269
+ elsif char != nil
1270
+ if check
1271
+ illegal_char_check(char)
1272
+ end
1273
+ push_chars(char)
1274
+ end
1275
+ end
1276
+
1277
+ def ending_check
1278
+ if @stream.peek_char(0) == "�{" and @stream.peek_char(1) == "�F"
1279
+ @section = :tail
1280
+ ensure_close
1281
+ @out.print "</div>\r\n<div class=\"bibliographical_information\">\r\n<hr />\r\n<br />\r\n"
1282
+ end
1283
+ end
1284
+
1285
+ # buffer management
1286
+ def ruby_buf_dump
1287
+ if @ruby_buf_protected
1288
+ @ruby_buf.unshift("�b")
1289
+ @ruby_buf_protected = nil
1290
+ end
1291
+ top = @ruby_buf[0]
1292
+ if top.is_a?(String) and @buffer.last.is_a?(String)
1293
+ @buffer.last.concat(top)
1294
+ @buffer = @buffer + @ruby_buf[1,@ruby_buf.length]
1295
+ else
1296
+ @buffer = @buffer + @ruby_buf
1297
+ end
1298
+ @ruby_buf = [""]
1299
+ end
1300
+
1301
+ def push_chars (obj)
1302
+ if obj.is_a?(Array)
1303
+ obj.each{|x|
1304
+ push_chars(x)
1305
+ }
1306
+ elsif obj.is_a?(String)
1307
+ if obj.length == 1
1308
+ obj = CGI.escapeHTML(obj)
1309
+ end
1310
+ obj.each_char{|x|
1311
+ push_char(x)
1312
+ }
1313
+ else
1314
+ push_char(obj)
1315
+ end
1316
+ end
1317
+
1318
+ def push_char (char)
1319
+ ctype = char_type(char)
1320
+ if ctype == :hankaku_terminate and @ruby_buf_type == :hankaku
1321
+ if @ruby_buf.last.is_a?(String)
1322
+ @ruby_buf.last.concat(char)
1323
+ else
1324
+ @ruby_buf.push(char)
1325
+ end
1326
+ @ruby_buf_type = :else
1327
+ elsif @ruby_buf_protected or (ctype != :else and ctype == @ruby_buf_type)
1328
+ if char.is_a?(String) and @ruby_buf.last.is_a?(String)
1329
+ @ruby_buf.last.concat(char)
1330
+ else
1331
+ @ruby_buf.push(char)
1332
+ @ruby_buf.push("")
1333
+ end
1334
+ else
1335
+ ruby_buf_dump
1336
+ @ruby_buf_type = ctype
1337
+ @ruby_buf = [char]
1338
+ end
1339
+ end
1340
+
1341
+ def buf_is_blank? (buf)
1342
+ buf.each{|token|
1343
+ if token.is_a?(String) and not(token=="")
1344
+ return false
1345
+ elsif token.is_a?(Oneline_Indent_tag)
1346
+ return :inline
1347
+ end
1348
+ }
1349
+ true
1350
+ end
1351
+
1352
+ def terpri? (buf)
1353
+ flag = true
1354
+ buf.each{|x|
1355
+ if x.is_a?(Multiline_tag)
1356
+ flag = false
1357
+ elsif (x.is_a?(String) and x == "")
1358
+ nil
1359
+ else
1360
+ return true
1361
+ end
1362
+ }
1363
+ flag
1364
+ end
1365
+
1366
+ def general_output
1367
+ if @style_stack.last
1368
+ raise Aozora_Error.new("#{@style_stack.last[0]}���ɉ��s����܂����B���s���܂����v�f�ɂ̓u���b�N�\�L��p���Ă�������")
1369
+ end
1370
+ # buffer�ɃC���f���g�^�O����������������s���Ȃ��I
1371
+ if @noprint
1372
+ @noprint = false
1373
+ return
1374
+ end
1375
+ ruby_buf_dump
1376
+ buf = @buffer
1377
+ @ruby_buf = [""]; @ruby_buf_mode = nil; @buffer = []
1378
+ tail = []
1379
+
1380
+ indent_type = buf_is_blank?(buf)
1381
+ terprip = (terpri?(buf) and @terprip)
1382
+ @terprip = true
1383
+
1384
+ if @indent_stack.last.is_a?(String) and not(indent_type)
1385
+ @out.print @indent_stack.last
1386
+ end
1387
+
1388
+ buf.each{|s|
1389
+ if s.is_a?(Oneline_Indent_tag)
1390
+ tail.unshift(s.close_tag)
1391
+ elsif s.is_a?(UnEmbed_Gaiji_tag) and not(s.escaped?)
1392
+ # �����Ă��������𕜊�������
1393
+ @out.print "��"
1394
+ elsif s.is_a?(Multiline_Chitsuki_tag)
1395
+ elsif s.is_a?(String) and s.match("</em")
1396
+ end
1397
+ @out.print s.to_s
1398
+ }
1399
+ if @indent_stack.last.is_a?(String)
1400
+ # �Ԃ牺��indent
1401
+ # tail always active
1402
+ if tail.last
1403
+ tail.each{|s|
1404
+ @out.print s.to_s
1405
+ }
1406
+ end
1407
+ if indent_type == :inline
1408
+ @out.print "\r\n"
1409
+ elsif indent_type and terprip
1410
+ @out.print "<br />\r\n"
1411
+ else
1412
+ @out.print "</div>\r\n"
1413
+ end
1414
+ elsif tail.last
1415
+ tail.each{|s|
1416
+ @out.print s.to_s
1417
+ }
1418
+ @out.print "\r\n"
1419
+ elsif terprip
1420
+ @out.print "<br />\r\n"
1421
+ else
1422
+ @out.print "\r\n"
1423
+ end
1424
+ end
1425
+
1426
+ # �O���Q�Ƃ̔��� Ruby,style�d�˂������X�̂��߁A�v�f�̔z��ŕԂ�
1427
+ def search_front_reference (string)
1428
+ if string.length == 0
1429
+ return false
1430
+ end
1431
+ searching_buf = if @ruby_buf.length != 0
1432
+ @ruby_buf
1433
+ else
1434
+ @buffer
1435
+ end
1436
+ last_string = searching_buf.last
1437
+ if last_string.is_a?(String)
1438
+ if last_string == ""
1439
+ searching_buf.pop
1440
+ search_front_reference(string.sub(Regexp.new(Regexp.quote(last_string)+"$"),""))
1441
+ elsif match = last_string.match(Regexp.new(Regexp.quote(string)+"$"))
1442
+ # ���S��v
1443
+ # start = match.begin(0)
1444
+ # tail = match.end(0)
1445
+ # last_string[start,tail-start] = ""
1446
+ searching_buf.pop
1447
+ searching_buf.push(last_string.sub(Regexp.new(Regexp.quote(string)+"$"),""))
1448
+ [string]
1449
+ elsif string.match(Regexp.new(Regexp.quote(last_string)+"$"))
1450
+ # ������v
1451
+ tmp = searching_buf.pop
1452
+ found = search_front_reference(string.sub(Regexp.new(Regexp.quote(last_string)+"$"),""))
1453
+ if found
1454
+ found+[tmp]
1455
+ else
1456
+ searching_buf.push(tmp)
1457
+ false
1458
+ end
1459
+ end
1460
+ elsif last_string.is_a?(Reference_mentioned_tag)
1461
+ inner = last_string.target_string
1462
+ if inner == string
1463
+ # ���S��v
1464
+ searching_buf.pop
1465
+ [last_string]
1466
+ elsif string.match(Regexp.new(Regexp.quote(inner)+"$"))
1467
+ # ������v
1468
+ tmp = searching_buf.pop
1469
+ found = search_front_reference(string.sub(Regexp.new(Regexp.quote(inner)+"$"),""))
1470
+ if found
1471
+ found+[tmp]
1472
+ else
1473
+ searching_buf.push(tmp)
1474
+ false
1475
+ end
1476
+ end
1477
+ else
1478
+ false
1479
+ end
1480
+ end
1481
+
1482
+ # ���������O���Q�Ƃ����ɖ߂�
1483
+ def recovery_front_reference (reference)
1484
+ reference.each{|elt|
1485
+ # if @ruby_buf_protected
1486
+ if @ruby_buf.length > 0
1487
+ if @ruby_buf.last.is_a?(String)
1488
+ if elt.is_a?(String)
1489
+ @ruby_buf.last.concat(elt)
1490
+ else
1491
+ @ruby_buf.push(elt)
1492
+ end
1493
+ else
1494
+ @ruby_buf.push(elt)
1495
+ end
1496
+ else
1497
+ if @buffer.last.is_a?(String)
1498
+ if elt.is_a?(String)
1499
+ @buffer.last.concat(elt)
1500
+ else
1501
+ @buffer.push(elt)
1502
+ end
1503
+ else
1504
+ @ruby_buf.push(elt)
1505
+ end
1506
+ end
1507
+ }
1508
+ end
1509
+
1510
+ def convert_japanese_number (command)
1511
+ tmp = command.tr("�O-�X", "0-9")
1512
+ tmp.tr!("���O�l�ܘZ������Z","1234567890")
1513
+ tmp.gsub!(/(\d)�\(\d)/){"#{$1}#{$2}"}
1514
+ tmp.gsub!(/(\d)�\/){"#{$1}0"}
1515
+ tmp.gsub!(/�\(\d)/){"1#{$1}"}
1516
+ tmp.gsub!(/�\/,"10")
1517
+ tmp
1518
+ end
1519
+
1520
+ def kuten2png (substring)
1521
+ desc = substring.gsub(/�u���v[��|��]/,"")
1522
+ match = desc.match(/[12]\-\d{1,2}\-\d{1,2}/)
1523
+ if (match and not(desc.match(/��0213�O��/)) and not(desc.match(/��.*��/)))
1524
+ @chuuki_table[:newjis] = true
1525
+ codes = match[0].split("-")
1526
+ folder = sprintf("%1d-%02d",*codes)
1527
+ code = sprintf("%1d-%02d-%02d",*codes)
1528
+ Embed_Gaiji_tag.new(self, folder,code,desc.gsub!("��",""))
1529
+ else
1530
+ substring
1531
+ end
1532
+ end
1533
+
1534
+ def escape_gaiji (command)
1535
+ whole, kanji, line = command.match(/(?:��)(.*)(?:�A)(.*)/).to_a
1536
+ tmp = @images.assoc(kanji)
1537
+ if tmp
1538
+ tmp.push(line)
1539
+ else
1540
+ @images.push([kanji,line])
1541
+ end
1542
+ UnEmbed_Gaiji_tag.new(self, command)
1543
+ end
1544
+
1545
+ def dispatch_gaiji
1546
+ hook = @stream.peek_char(0)
1547
+ if hook == "�m"
1548
+ read_char
1549
+ # embed?
1550
+ command,raw = read_to_nest("�n")
1551
+ try_emb = kuten2png(command)
1552
+ if try_emb == command
1553
+ # Unemb
1554
+ escape_gaiji(command)
1555
+ else
1556
+ try_emb
1557
+ end
1558
+ else
1559
+ "��"
1560
+ end
1561
+ end
1562
+
1563
+ def dispatch_aozora_command
1564
+ if @stream.peek_char(0) != "��"
1565
+ "�m"
1566
+ else
1567
+ read_char
1568
+ command,raw = read_to_nest("�n")
1569
+ # �K�p�����͂���ő��v���H�@�딚�|����딚
1570
+ if command.match(/�܂�Ԃ���/)
1571
+ apply_burasage(command)
1572
+
1573
+ elsif command.match(/^��������/)
1574
+ exec_block_start_command(command.sub(/^��������/,""))
1575
+ elsif command.match(/^������/)
1576
+ exec_block_end_command(command.sub(/^������/,""))
1577
+
1578
+ elsif command.match(/���蒍/)
1579
+ apply_warichu(command)
1580
+ elsif command.match(/������/)
1581
+ apply_jisage(command)
1582
+ elsif command.match(/fig(\d)+_(\d)+\.png/)
1583
+ exec_img_command(command,raw)
1584
+ # avoid to try complex ruby -- escape to notes
1585
+ elsif command.match(/(��|��)�Ɂu(.*)�v��(���r|���L|�T�L)/)
1586
+ apply_rest_notes(command)
1587
+ elsif command.match(/�I���$/)
1588
+ exec_inline_end_command(command)
1589
+ nil
1590
+ elsif command.match(/^�u.+�v/)
1591
+ exec_frontref_command(command)
1592
+ elsif command.match(/1-7-8[2345]/)
1593
+ apply_dakuten_katakana(command)
1594
+ elsif command.match(/^([���O�l�ܘZ������\���㒆���b�������V�n�l]+)$/)
1595
+ Kaeriten_tag.new(self, command)
1596
+ elsif command.match(/^�i(.+)�j$/)
1597
+ Okurigana_tag.new(self, command.gsub!(/[�i�j]/,""))
1598
+ elsif command.match(/(�n�t��|���グ)(�I���)*$/)
1599
+ apply_chitsuki(command)
1600
+ elsif exec_inline_start_command(command)
1601
+ nil
1602
+ else
1603
+ apply_rest_notes(command)
1604
+ end
1605
+ end
1606
+ end
1607
+
1608
+ def apply_burasage (command)
1609
+ tag = nil
1610
+ if implicit_close(:jisage)
1611
+ @terprip = false
1612
+ general_output
1613
+ end
1614
+ @noprint = true # always no print
1615
+ command = convert_japanese_number(command)
1616
+ if command.match(/�V�t��/)
1617
+ width = command.match(/�܂�Ԃ���(\d*)������/)[1]
1618
+ tag = '<div class="burasage" style="margin-left: ' + width + 'em; text-indent: -' + width + 'em;">'
1619
+ else
1620
+ match = command.match(/(\d*)�������A�܂�Ԃ���(\d*)������/)
1621
+ left, indent = match.to_a[1,2]
1622
+ left = left.to_i - indent.to_i
1623
+ tag = "<div class=\"burasage\" style=\"margin-left: #{indent}em; text-indent: #{left}em;\">"
1624
+ end
1625
+ @indent_stack.push(tag)
1626
+ @tag_stack.push("") # dummy
1627
+ nil
1628
+ end
1629
+
1630
+ def jisage_width (command)
1631
+ convert_japanese_number(command).match(/(\d*)(?:������)/)[1]
1632
+ end
1633
+
1634
+ def apply_jisage (command)
1635
+ if command.match(/�܂�/) or command.match(/�I���/)
1636
+ # �������I���
1637
+ explicit_close(:jisage)
1638
+ @indent_stack.pop
1639
+ nil
1640
+ else
1641
+ if command.match(/���̍s/)
1642
+ # 1�s����
1643
+ @buffer.unshift(Oneline_Jisage_tag.new(self, jisage_width(command)))
1644
+ nil
1645
+ else
1646
+ if @buffer.length == 0 and @stream.peek_char(0) == "\r\n"
1647
+ # command�̂�
1648
+ @terprip = false
1649
+ implicit_close(:jisage)
1650
+ # adhook hack
1651
+ @noprint = false
1652
+ @indent_stack.push(:jisage)
1653
+ Multiline_Jisage_tag.new(self, jisage_width(command))
1654
+ else
1655
+ @buffer.unshift(Oneline_Jisage_tag.new(self, jisage_width(command)))
1656
+ nil
1657
+ end
1658
+ end
1659
+ end
1660
+ end
1661
+
1662
+ def apply_warichu (command)
1663
+ if command.match(/�I���/)
1664
+ check = @stream.peek_char(0)
1665
+ if check == "�j"
1666
+ push_chars('</span>')
1667
+ else
1668
+ push_chars('�j')
1669
+ push_chars('</span>')
1670
+ end
1671
+ else
1672
+ check = @ruby_buf.last
1673
+ if check.is_a?(String) and check.match(/�i$/)
1674
+ push_chars('<span class="warichu">')
1675
+ else
1676
+ push_chars('<span class="warichu">')
1677
+ push_chars('�i')
1678
+ end
1679
+ end
1680
+ nil
1681
+ end
1682
+
1683
+ def chitsuki_length (command)
1684
+ command = convert_japanese_number(command)
1685
+ if match = command.match(/([0-9]+)��/)
1686
+ match[1]
1687
+ else
1688
+ "0"
1689
+ end
1690
+ end
1691
+
1692
+ def apply_chitsuki (string, multiline = false)
1693
+ if string.match(/�����Œn�t���I���/) or
1694
+ string.match(/�����Ŏ��グ�I���/)
1695
+ explicit_close(:chitsuki)
1696
+ @indent_stack.pop
1697
+ nil
1698
+ else
1699
+ l = chitsuki_length(string)
1700
+ if multiline
1701
+ # �����s�w��
1702
+ implicit_close(:chitsuki)
1703
+ @indent_stack.push(:chitsuki)
1704
+ Multiline_Chitsuki_tag.new(self, l)
1705
+ else
1706
+ # 1�s�̂�
1707
+ Oneline_Chitsuki_tag.new(self, l)
1708
+ end
1709
+ end
1710
+ end
1711
+
1712
+ def new_midashi_id(inc)
1713
+ @midashi_id += inc
1714
+ end
1715
+
1716
+ def apply_midashi(command)
1717
+ @indent_stack.push(:midashi)
1718
+ midashi_type = :normal
1719
+ if command.match(/���s/)
1720
+ midashi_type = :dogyo
1721
+ elsif command.match (/��/)
1722
+ midashi_type = :mado
1723
+ else
1724
+ @terprip = false
1725
+ end
1726
+ Multiline_midashi_tag.new(self,command,midashi_type)
1727
+ end
1728
+
1729
+ def apply_yokogumi(command)
1730
+ @indent_stack.push(:yokogumi)
1731
+ Multiline_yokogumi_tag.new(self)
1732
+ end
1733
+
1734
+ def apply_keigakomi(command)
1735
+ @indent_stack.push(:keigakomi)
1736
+ Keigakomi_tag.new(self)
1737
+ end
1738
+
1739
+ def apply_caption(command)
1740
+ @indent_stack.push(:caption)
1741
+ Multiline_caption_tag.new(self)
1742
+ end
1743
+
1744
+ def apply_jizume(command)
1745
+ w = convert_japanese_number(command).match(/(\d*)(?:���l��)/)[1]
1746
+ @indent_stack.push(:jizume)
1747
+ Jizume_tag.new(self, w)
1748
+ end
1749
+
1750
+ def push_block_tag (tag,closing)
1751
+ push_chars(tag)
1752
+ closing.concat(tag.close_tag)
1753
+ end
1754
+
1755
+ def exec_inline_start_command (command)
1756
+ case command
1757
+ when "���L�t��"
1758
+ @style_stack.push([command,'</ruby>'])
1759
+ push_char('<ruby><rb>')
1760
+ when "�c����"
1761
+ @style_stack.push([command,'</span>'])
1762
+ push_char('<span dir="ltr">')
1763
+ when "�r�͂�"
1764
+ @style_stack.push([command,'</span>'])
1765
+ push_chars('<span class="keigakomi">')
1766
+ when "���g��"
1767
+ @style_stack.push([command,'</span>'])
1768
+ push_chars('<span class="yokogumi">')
1769
+ when "�L���v�V����"
1770
+ @style_stack.push([command,'</span>'])
1771
+ push_chars('<span class="caption">')
1772
+ when "�匩�o��"
1773
+ @style_stack.push([command,'</a></h3>'])
1774
+ @terprip = false
1775
+ push_chars("<h3 class=\"o-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(100)}\">")
1776
+ when "�����o��"
1777
+ @style_stack.push([command,'</a></h4>'])
1778
+ @terprip = false
1779
+ push_chars("<h4 class=\"naka-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(10)}\">")
1780
+ when "�����o��"
1781
+ @style_stack.push([command,'</a></h5>'])
1782
+ @terprip = false
1783
+ push_chars("<h5 class=\"ko-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(1)}\">")
1784
+ when "���s�匩�o��"
1785
+ @style_stack.push([command,'</a></h3>'])
1786
+ push_chars("<h3 class=\"dogyo-o-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(100)}\">")
1787
+ when "���s�����o��"
1788
+ @style_stack.push([command,'</a></h4>'])
1789
+ push_chars("<h4 class=\"dogyo-naka-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(10)}\">")
1790
+ when "���s�����o��"
1791
+ @style_stack.push([command,'</a></h5>'])
1792
+ push_chars("<h5 class=\"dogyo-ko-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(1)}\">")
1793
+ when "���匩�o��"
1794
+ @style_stack.push([command,'</a></h3>'])
1795
+ push_chars("<h3 class=\"mado-o-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(100)}\">")
1796
+ when "�������o��"
1797
+ @style_stack.push([command,'</a></h4>'])
1798
+ push_chars("<h4 class=\"mado-naka-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(10)}\">")
1799
+ when "�������o��"
1800
+ @style_stack.push([command,'</a></h5>'])
1801
+ push_chars("<h5 class=\"mado-ko-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(1)}\">")
1802
+ else
1803
+ if command.match(/(.*)�i�K(..)�ȕ���/)
1804
+ @style_stack.push([command,'</span>'])
1805
+ whole, nest, style = command.match(/(.*)�i�K(..)�ȕ���/).to_a
1806
+ times = convert_japanese_number(nest).to_i
1807
+ daisho = if style.match("��")
1808
+ :sho
1809
+ else
1810
+ :dai
1811
+ end
1812
+ html_class = daisho.to_s + times.to_s
1813
+ size = case times
1814
+ when 1
1815
+ ""
1816
+ when 2
1817
+ "x-"
1818
+ else
1819
+ if times >= 3
1820
+ "xx-"
1821
+ else
1822
+ raise Aozora_Error.new("�����T�C�Y�̎w�肪�s���ł�")
1823
+ end
1824
+ end + case daisho
1825
+ when :dai
1826
+ "large"
1827
+ when :sho
1828
+ "small"
1829
+ end
1830
+ push_chars("<span class=\"#{html_class}\" style=\"font-size: #{size};\">")
1831
+ else
1832
+ ## Decoration ##
1833
+ key = command
1834
+ filter = lambda{|x| x}
1835
+ if command.match(/(�E|��|��|��)��(.*)/)
1836
+ whole, dir, com = command.match(/(�E|��|��|��)��(.*)/).to_a
1837
+ # renew command
1838
+ key = com
1839
+ if command.match(/�_/)
1840
+ case dir
1841
+ when "��", "��"
1842
+ filter = lambda{|x| x + "_after"}
1843
+ end
1844
+ elsif command.match(/��/)
1845
+ case dir
1846
+ when "��", "��"
1847
+ filter = lambda{|x| x.sub("under","over")}
1848
+ end
1849
+ end
1850
+ end
1851
+
1852
+ found = @@command_table[key]
1853
+ # found = [class, tag]
1854
+ if found
1855
+ @style_stack.push([command,"</#{found[1]}>"])
1856
+ if found[1] == "em" # or found[1] == "strong"
1857
+ @chuuki_table[:em] = true
1858
+ end
1859
+ push_chars("<#{found[1]} class=\"#{filter.call(found[0])}\">")
1860
+ else
1861
+ nil
1862
+ end
1863
+ end
1864
+ end
1865
+ end
1866
+
1867
+ def exec_inline_end_command (command)
1868
+ encount = command.sub("�I���","")
1869
+ if encount == "�{��"
1870
+ # force to finish main_text
1871
+ @section = :tail
1872
+ ensure_close
1873
+ @noprint = true
1874
+ @out.print "</div>\r\n<div class=\"after_text\">\r\n<hr />\r\n"
1875
+ elsif encount.match("���L�t��") and @style_stack.last[0] == "���L�t��"
1876
+ # special inline ruby
1877
+ @style_stack.pop
1878
+ whole, ruby = encount.match("�u(.*)�v�̒��L�t��").to_a
1879
+ push_char("</rb><rp>�i</rp><rt>#{ruby}</rt><rp>�j</rp></ruby>")
1880
+ elsif @style_stack.last[0].match(encount)
1881
+ push_chars(@style_stack.pop[1])
1882
+ else
1883
+ raise Aozora_Error.new("#{encount}���I�����悤�Ƃ��܂������A#{@style_stack.last[0]}���ł�")
1884
+ end
1885
+ end
1886
+
1887
+ def exec_block_start_command (command)
1888
+ match = ""
1889
+ if command.match(/������/)
1890
+ push_block_tag(apply_jisage(command),match)
1891
+ elsif command.match(/(�n�t��|���グ)$/)
1892
+ push_block_tag(apply_chitsuki(command,true),match)
1893
+ end
1894
+
1895
+ if command.match(/���o��/)
1896
+ push_block_tag(apply_midashi(command),match)
1897
+ end
1898
+
1899
+ if command.match(/���l��/)
1900
+ if match != ""
1901
+ @indent_stack.pop
1902
+ end
1903
+ push_block_tag(apply_jizume(command),match)
1904
+ end
1905
+
1906
+ if command.match(/���g��/)
1907
+ if match != ""
1908
+ @indent_stack.pop
1909
+ end
1910
+ push_block_tag(apply_yokogumi(command),match)
1911
+ end
1912
+
1913
+ if command.match(/�r�͂�/)
1914
+ if match != ""
1915
+ @indent_stack.pop
1916
+ end
1917
+ push_block_tag(apply_keigakomi(command),match)
1918
+ end
1919
+
1920
+ if command.match(/�L���v�V����/)
1921
+ if match != ""
1922
+ @indent_stack.pop
1923
+ end
1924
+ push_block_tag(apply_caption(command),match)
1925
+ end
1926
+
1927
+ if command.match(/����/)
1928
+ if match != ""
1929
+ @indent_stack.pop
1930
+ end
1931
+ push_block_tag(Multiline_style_tag.new(self, "futoji"),match)
1932
+ @indent_stack.push(:futoji)
1933
+ end
1934
+ if command.match(/�Α�/)
1935
+ if match != ""
1936
+ @indent_stack.pop
1937
+ end
1938
+ push_block_tag(Multiline_style_tag.new(self, "shatai"),match)
1939
+ @indent_stack.push(:shatai)
1940
+ end
1941
+
1942
+ if command.match(/(.*)�i�K(..)�ȕ���/)
1943
+ whole, nest, style = command.match(/(.*)�i�K(..)�ȕ���/).to_a
1944
+ if match != ""
1945
+ @indent_stack.pop
1946
+ end
1947
+ daisho = if style == "����"
1948
+ :sho
1949
+ else
1950
+ :dai
1951
+ end
1952
+ push_block_tag(Font_size_tag.new(self,
1953
+ convert_japanese_number(nest).to_i,
1954
+ daisho),match)
1955
+ @indent_stack.push(daisho)
1956
+ end
1957
+
1958
+ if match == ""
1959
+ apply_rest_notes("��������" + command)
1960
+ else
1961
+ @tag_stack.push(match)
1962
+ nil
1963
+ end
1964
+ end
1965
+
1966
+ def exec_block_end_command (command)
1967
+ match = false
1968
+ if mode = if command.match(/������/)
1969
+ :jisage
1970
+ elsif command.match(/(�n�t��|���グ)�I���$/)
1971
+ :chitsuki
1972
+ elsif command.match(/���o��/)
1973
+ :midashi
1974
+ elsif command.match(/���l��/)
1975
+ :jizume
1976
+ elsif command.match(/���g��/)
1977
+ :yokogumi
1978
+ elsif command.match(/�r�͂�/)
1979
+ :keigakomi
1980
+ elsif command.match(/�L���v�V����/)
1981
+ :caption
1982
+ elsif command.match(/����/)
1983
+ :futoji
1984
+ elsif command.match(/�Α�/)
1985
+ :shatai
1986
+ elsif command.match(/�傫�ȕ���/)
1987
+ :dai
1988
+ elsif command.match(/�����ȕ���/)
1989
+ :sho
1990
+ end
1991
+ explicit_close(mode)
1992
+ match = @indent_stack.pop
1993
+ end
1994
+
1995
+ if match
1996
+ if not(match.is_a?(String))
1997
+ @terprip = false
1998
+ end
1999
+ nil
2000
+ else
2001
+ apply_rest_notes("������" + command)
2002
+ end
2003
+ end
2004
+
2005
+ def exec_img_command (command,raw)
2006
+ match = raw.match(/(.*)�i(fig.+\.png)(�A��([0-9]+)�~�c([0-9]+))*�j����/)
2007
+ if match
2008
+ whole, alt, src, wh, width, height = match.to_a
2009
+ css_class = if alt.match(/�ʐ^/)
2010
+ "photo"
2011
+ else
2012
+ "illustration"
2013
+ end
2014
+ Img_tag.new(self, src, css_class, alt, width, height)
2015
+ else
2016
+ apply_rest_notes(command)
2017
+ end
2018
+ end
2019
+
2020
+ def exec_frontref_command (command)
2021
+ whole, reference, spec1, spec2 = command.match(/�u([^�u�v]*(?:�u.+�v)*[^�u�v]*)�v[��|��|��](�u.+�v��)*(.+)/).to_a
2022
+ spec = if spec1
2023
+ spec1 + spec2
2024
+ else
2025
+ spec2
2026
+ end
2027
+ if reference and found = search_front_reference(reference)
2028
+ tmp = exec_style(found, spec)
2029
+ if tmp
2030
+ return tmp
2031
+ else
2032
+ recovery_front_reference(found)
2033
+ end
2034
+ end
2035
+ # comment out?
2036
+ apply_rest_notes(command)
2037
+ end
2038
+
2039
+ def multiply (bouki, times)
2040
+ s = ""
2041
+ (times-1).times{
2042
+ s += bouki
2043
+ s += "<!>"
2044
+ }
2045
+ s + bouki
2046
+ end
2047
+
2048
+ def include_ruby? (array)
2049
+ array.index{|elt|
2050
+ if elt.is_a?(Ruby_tag)
2051
+ true
2052
+ elsif elt.is_a?(Reference_mentioned_tag)
2053
+ if elt.target.is_a?(Array)
2054
+ include_ruby?(elt.target)
2055
+ else
2056
+ elt.target.is_a?(Ruby_tag)
2057
+ end
2058
+ end
2059
+ }
2060
+ end
2061
+
2062
+ # complex ruby wrap up utilities -- don't erase! we will use soon ...
2063
+ def rearrange_ruby_tag (targets, upper_ruby, under_ruby = "")
2064
+ target,upper,under = rearrange_ruby(targets, upper_ruby, under_ruby)
2065
+ Ruby_tag.new(self, target,upper,under)
2066
+ end
2067
+
2068
+ # ruby�^�O�̍Ċ��蓖��
2069
+ def rearrange_ruby (targets, upper_ruby, under_ruby = "")
2070
+ if include_ruby?(targets)
2071
+ new_targets = []
2072
+ new_upper = if upper_ruby != ""
2073
+ upper_ruby
2074
+ else
2075
+ []
2076
+ end
2077
+ new_under = if under_ruby != ""
2078
+ under_ruby
2079
+ else
2080
+ []
2081
+ end
2082
+ if new_upper.length > 1 and new_under.length > 1
2083
+ raise Aozora_Error.new("1�‚̒P���3�‚̃��r�͂‚����܂���")
2084
+ end
2085
+
2086
+ targets.each{|x|
2087
+ if x.is_a?(Ruby_tag)
2088
+ if x.target.is_a?(Array)
2089
+ # inner Ruby_tag is already complex ... give up
2090
+ raise Aozora_Error.new("�����ӏ���2�‚̃��r�͂‚����܂���")
2091
+ else
2092
+ if x.ruby != ""
2093
+ if new_upper.is_a?(Array)
2094
+ new_upper.push(x.ruby)
2095
+ else
2096
+ raise Aozora_Error.new("�����ӏ���2�‚̃��r�͂‚����܂���")
2097
+ end
2098
+ else
2099
+ if new_under.is_a?(Array)
2100
+ new_under.push(x.under_ruby)
2101
+ else
2102
+ raise Aozora_Error.new("�����ӏ���2�‚̃��r�͂‚����܂���")
2103
+ end
2104
+ end
2105
+ new_targets.push(x.target)
2106
+ end
2107
+ elsif x.is_a?(Reference_mentioned_tag)
2108
+ if x.target.is_a?(Array)
2109
+ # recursive
2110
+ tar,up,un = rearrange_ruby(x.target,"","")
2111
+ # rotation!!
2112
+ tar.each{|y|
2113
+ tmp = x.dup
2114
+ tmp.target = y
2115
+ new_targets.push(tmp)}
2116
+ if new_under.is_a?(Array)
2117
+ new_under.concat(un)
2118
+ elsif un.to_s.length > 0
2119
+ raise Aozora_Error.new("�����ӏ���2�‚̃��r�͂‚����܂���")
2120
+ end
2121
+ if new_upper.is_a?(Array)
2122
+ new_upper.concat(up)
2123
+ elsif up.to_s.length > 0
2124
+ raise Aozora_Error.new("�����ӏ���2�‚̃��r�͂‚����܂���")
2125
+ end
2126
+ else
2127
+ new_targets.push(x)
2128
+ if new_under.is_a?(Array)
2129
+ new_under.push("")
2130
+ end
2131
+ if new_upper.is_a?(Array)
2132
+ new_upper.push("")
2133
+ end
2134
+ end
2135
+ else
2136
+ new_targets.push(x)
2137
+ if new_under.is_a?(Array)
2138
+ new_under.push("")
2139
+ end
2140
+ if new_upper.is_a?(Array)
2141
+ new_upper.push("")
2142
+ end
2143
+ end
2144
+ }
2145
+ [new_targets, new_upper, new_under]
2146
+ else
2147
+ [targets, upper_ruby, under_ruby]
2148
+ end
2149
+ end
2150
+
2151
+ def exec_style (targets, command)
2152
+ try_kuten = kuten2png(command)
2153
+ if try_kuten != command
2154
+ try_kuten
2155
+ elsif command.match(/�c����/)
2156
+ Dir_tag.new(self, targets)
2157
+ elsif command.match(/���g��/)
2158
+ Inline_yokogumi_tag.new(self, targets)
2159
+ elsif command.match(/�r�͂�/)
2160
+ Inline_keigakomi_tag.new(self, targets)
2161
+ elsif command.match(/�L���v�V����/)
2162
+ Inline_caption_tag.new(self, targets)
2163
+ elsif command.match(/�Ԃ�_/)
2164
+ Kaeriten_tag.new(self, targets)
2165
+ elsif command.match(/�P�_���艼��/)
2166
+ Okurigana_tag.new(self, targets)
2167
+ elsif command.match(/���o��/)
2168
+ midashi_type = :normal
2169
+ if command.match(/���s/)
2170
+ midashi_type = :dogyo
2171
+ elsif command.match (/��/)
2172
+ midashi_type = :mado
2173
+ else
2174
+ @terprip = false
2175
+ end
2176
+ Midashi_tag.new(self, targets, command, midashi_type)
2177
+ elsif command.match(/(.*)�i�K(..)�ȕ���/)
2178
+ whole, nest, style = command.match(/(.*)�i�K(..)�ȕ���/).to_a
2179
+ Inline_font_size_tag.new(self,targets,
2180
+ convert_japanese_number(nest).to_i,
2181
+ if style.match("��")
2182
+ :sho
2183
+ else
2184
+ :dai
2185
+ end)
2186
+ elsif command.match(/(��|��)�Ɂu([^�v]*)�v��(���r|���L)/)
2187
+ whole, dir, under = command.match(/(��|��)�Ɂu([^�v]*)�v��(���r|���L)/).to_a
2188
+ if targets.length == 1 and targets[0].is_a?(Ruby_tag)
2189
+ tag = targets[0]
2190
+ if tag.under_ruby == ""
2191
+ tag.under_ruby = under
2192
+ tag
2193
+ else
2194
+ raise Aozora_Error.new("1�‚̒P���3�‚̃��r�͂‚����܂���")
2195
+ end
2196
+ else
2197
+ rearrange_ruby_tag(targets,"",under)
2198
+ end
2199
+ elsif command.match(/�u(.+?)�v�̒��L/)
2200
+ rearrange_ruby_tag(targets,/�u(.+?)�v�̒��L/.match(command).to_a[1])
2201
+ elsif command.match(/�u(.)�v�̖T�L/)
2202
+ rearrange_ruby_tag(targets,multiply( /�u(.)�v�̖T�L/.match(command).to_a[1], target.length))
2203
+ else
2204
+ ## direction fix! ##
2205
+ filter = lambda{|x| x}
2206
+ if command.match(/(�E|��|��|��)��(.*)/)
2207
+ whole, dir, com = command.match(/(�E|��|��|��)��(.*)/).to_a
2208
+ # renew command
2209
+ command = com
2210
+ if command.match(/�_/)
2211
+ case dir
2212
+ when "��", "��"
2213
+ filter = lambda{|x| x + "_after"}
2214
+ end
2215
+ elsif command.match(/��/)
2216
+ case dir
2217
+ when "��", "��"
2218
+ filter = lambda{|x| x.sub("under","over")}
2219
+ end
2220
+ end
2221
+ end
2222
+
2223
+ found = @@command_table[command]
2224
+ # found = [class, tag]
2225
+ if found
2226
+ if found[1] == "em" # or found[1] == "strong"
2227
+ @chuuki_table[:em] = true
2228
+ end
2229
+ Decorate_tag.new(self, targets, filter.call(found[0]), found[1])
2230
+ else
2231
+ nil
2232
+ end
2233
+ end
2234
+ end
2235
+
2236
+ def apply_dakuten_katakana (command)
2237
+ n = command.match(/1-7-8([2345])/).to_a[1]
2238
+ frontref =
2239
+ case n
2240
+ when "2"
2241
+ "���J"
2242
+ when "3"
2243
+ "���J"
2244
+ when "4"
2245
+ "���J"
2246
+ when "5"
2247
+ "���J"
2248
+ end
2249
+ if found = search_front_reference(frontref)
2250
+ Dakuten_katakana_tag.new(self, n,found.join)
2251
+ else
2252
+ apply_rest_notes(command)
2253
+ end
2254
+ end
2255
+
2256
+ def assign_kunoji
2257
+ second = @stream.peek_char(0)
2258
+ case second
2259
+ when @@noji
2260
+ @chuuki_table[:kunoji] = true
2261
+ when @@dakuten
2262
+ if @stream.peek_char(1) == @@noji
2263
+ @chuuki_table[:dakutenkunoji] = true
2264
+ end
2265
+ end
2266
+ end
2267
+
2268
+ def apply_rest_notes (command)
2269
+ @chuuki_table[:chuki] = true
2270
+ Editor_note_tag.new(self, command)
2271
+ end
2272
+
2273
+ # �b�������Ƃ��͕�����𖳎�����ruby_buf�����Ȃ��Ⴂ���Ȃ�
2274
+ def apply_ruby
2275
+ @ruby_buf_protected = nil
2276
+ ruby,raw = read_to_nest("�t")
2277
+ if ruby.length == 0
2278
+ # escaped ruby character
2279
+ return "�s�t"
2280
+ end
2281
+ ans = ""
2282
+ notes = []
2283
+ @ruby_buf.each{|token|
2284
+ if token.is_a?(UnEmbed_Gaiji_tag)
2285
+ ans.concat("��")
2286
+ token.escape!
2287
+ notes.push(token)
2288
+ else
2289
+ ans.concat(token.to_s)
2290
+ end}
2291
+ @buffer.push(Ruby_tag.new(self, ans, ruby))
2292
+ @buffer = @buffer + notes
2293
+ @ruby_buf = [""]
2294
+ nil
2295
+ end
2296
+
2297
+ def parse_tail
2298
+ char = read_char
2299
+ check = true
2300
+ case char
2301
+ when "�k"
2302
+ check = false
2303
+ char = read_accent
2304
+ when @endchar
2305
+ throw :terminate
2306
+ when "��"
2307
+ char = dispatch_gaiji
2308
+ when "�m"
2309
+ char = dispatch_aozora_command
2310
+ when @@ku
2311
+ assign_kunoji
2312
+ when "�s"
2313
+ char = apply_ruby
2314
+ end
2315
+ if char == "\r\n"
2316
+ tail_output
2317
+ elsif char == "�b"
2318
+ ruby_buf_dump
2319
+ @ruby_buf_protected = true
2320
+ elsif char != nil
2321
+ if check
2322
+ illegal_char_check(char)
2323
+ end
2324
+ push_chars(char)
2325
+ end
2326
+ end
2327
+
2328
+ def tail_output
2329
+ ruby_buf_dump
2330
+ string = @buffer.join
2331
+ @ruby_buf = [""]; @ruby_buf_mode = nil; @buffer = []
2332
+ string.gsub!("info@aozora.gr.jp",'<a href="mailto: info@aozora.gr.jp">info@aozora.gr.jp</a>')
2333
+ string.gsub!("�‹󕶌Ɂihttp://www.aozora.gr.jp/�j"){"<a href=\"http://www.aozora.gr.jp/\">#{$&}</a>"}
2334
+ if string.match(/(<br \/>$|<\/p>$|<\/h\d>$|<div.*>$|<\/div>$|^<[^>]*>$)/)
2335
+ @out.print string, "\r\n"
2336
+ else
2337
+ @out.print string, "<br />\r\n"
2338
+ end
2339
+ end
2340
+
2341
+ def hyoki ()
2342
+ # <br /> times fix
2343
+ @out.print "<br />\r\n</div>\r\n<div class=\"notation_notes\">\r\n<hr />\r\n<br />\r\n���\�L�ɂ‚���<br />\r\n<ul>\r\n"
2344
+ @out.print "\t<li>���̃t�@�C���� W3C ���� XHTML1.1 �ɂ������`���ō쐬����Ă��܂��B</li>\r\n"
2345
+ if @chuuki_table[:chuki]
2346
+ @out.print "\t<li>�m���c�n�́A���͎҂ɂ�钍��\���L���ł��B</li>\r\n"
2347
+ end
2348
+ if @chuuki_table[:kunoji]
2349
+ if @chuuki_table[:dakutenkunoji]
2350
+ @out.print "\t<li>�u���̎��_�v�́u#{@@ku}#{@@noji}�v�ŁA�u���_�t�����̎��_�v�́u#{@@ku}#{@@dakuten}#{@@noji}�v�ŕ\���܂����B</li>\r\n"
2351
+ else
2352
+ @out.print "\t<li>�u���̎��_�v�́u#{@@ku}#{@@noji}�v�ŕ\���܂����B</li>\r\n"
2353
+ end
2354
+ elsif @chuuki_table[:dakutenkunoji]
2355
+ @out.print "\t<li>�u���_�t�����̎��_�v�́u#{@@ku}#{@@dakuten}#{@@noji}�v�ŕ\���܂����B</li>\r\n"
2356
+ end
2357
+ if @chuuki_table[:newjis]
2358
+ @out.print "\t<li>�u���̎��_�v���̂���JIS X 0213�ɂ��镶���́A�摜�����Ė��ߍ��݂܂����B</li>\r\n"
2359
+ end
2360
+ if @chuuki_table[:accent]
2361
+ @out.print "\t<li>�A�N�Z���g�����t�����e�������́A�摜�����Ė��ߍ��݂܂����B</li>\r\n"
2362
+ end
2363
+ # if @chuuki_table[:em]
2364
+ # @out.print "\t<li>�T�_�⌗�_�A�T���̕t���������́A�����\���ɂ��܂����B</li>\r\n"
2365
+ # end
2366
+ if @images[0]
2367
+ @out.print "\t<li>���̍�i�ɂ́AJIS X 0213�ɂȂ��A�ȉ��̕������p�����Ă��܂��B�i�����́A��{���̏o���u�y�[�W-�s�v���B�j�����̕����͖{�����ł́u���m���c�n�v�̌`�Ŏ����܂����B</li>\r\n</ul>\r\n<br />\r\n\t\t<table class=\"gaiji_list\">\r\n"
2368
+ @images.each{|cell|
2369
+ k,*v = cell
2370
+ @out.print " <tr>
2371
+ <td>
2372
+ #{k}
2373
+ </td>
2374
+ <td>&nbsp;&nbsp;</td>
2375
+ <td>
2376
+ #{v.join("�A")} </td>
2377
+ <!--
2378
+ <td>
2379
+ �@�@<img src=\"../../../gaiji/others/xxxx.png\" alt=\"#{k}\" width=32 height=32 />
2380
+ </td>
2381
+ -->
2382
+ </tr>
2383
+ "
2384
+ }
2385
+ @out.print "\t\t</table>\r\n"
2386
+ else
2387
+ @out.print "</ul>\r\n" # <ul>����<li>�ȊO�̃G�������g������͕̂s���Ȃ̂ŏC��
2388
+ end
2389
+ @out.print "</div>\r\n"
2390
+ end
2391
+ end
2392
+
2393
+ # �‹�L�@�̓���q�ɑΉ��i�H�j
2394
+ class Aozora_tag_parser < Aozora2Html
2395
+ def initialize (input, endchar, chuuki, image)
2396
+ if not(input.is_a?(Jstream))
2397
+ raise ArgumentError, "tag_parser must supply Jstream as input"
2398
+ end
2399
+ @stream = input;
2400
+ @buffer = []; @ruby_buf = [""]; @ruby_char_type = nil
2401
+ @chuuki_table = chuuki; @images = image; # global�Ȋ‹����L�^����A�C�e���͋��L����K�v����
2402
+ @endchar = endchar # ���s���z����ׂ����ۂ��c
2403
+ @section = :tail # ���������ƋL�@���̓C���f���g�����Ȃ��̂œ���
2404
+ @raw = "" # �O���ϊ��O�̐��e�L�X�g���c���������Ƃ�����炵��
2405
+ end
2406
+
2407
+ def read_char # method override!
2408
+ c = @stream.read_char
2409
+ @raw.concat(c)
2410
+ c
2411
+ end
2412
+
2413
+ def read_to_nest(endchar)
2414
+ ans = super(endchar)
2415
+ @raw.concat(ans[1])
2416
+ ans
2417
+ end
2418
+
2419
+ def general_output # �o�͂�[String,String]�Ԃ��ŁI
2420
+ ruby_buf_dump
2421
+ ans=""
2422
+ @buffer.each{|s|
2423
+ if s.is_a?(UnEmbed_Gaiji_tag) and not(s.escaped?)
2424
+ # �����Ă��������𕜊�������
2425
+ ans.concat("��")
2426
+ end
2427
+ ans.concat(s.to_s)
2428
+ }
2429
+ [ans,@raw]
2430
+ end
2431
+
2432
+ def process ()
2433
+ catch(:terminate){
2434
+ loop{
2435
+ parse
2436
+ }
2437
+ }
2438
+ general_output
2439
+ end
2440
+ end
2441
+
2442
+ # accent���ꕶ���𐶂������߂̍ċA�Ăяo��
2443
+ class Aozora_accent_parser < Aozora2Html
2444
+ def initialize (input, endchar, chuuki, image)
2445
+ if not(input.is_a?(Jstream))
2446
+ raise ArgumentError, "tag_parser must supply Jstream as input"
2447
+ end
2448
+ @stream = input
2449
+ @buffer = []; @ruby_buf = [""]; @ruby_char_type = nil
2450
+ @chuuki_table = chuuki; @images = image; # global�Ȋ‹����L�^����A�C�e���͋��L����K�v����
2451
+ @endchar = endchar # ���s�͉z�����Ȃ� <br />���o�͂��Ă����Ȃ�
2452
+ @closed = nil # ���s�ł̋����P�ރ`�F�b�N�t���O
2453
+ @encount_accent = nil
2454
+ end
2455
+
2456
+ def general_output # �o�͔͂z��ŕԂ�
2457
+ ruby_buf_dump
2458
+ if not(@encount_accent)
2459
+ @buffer.unshift("�k")
2460
+ end
2461
+ if @closed and not(@encount_accent)
2462
+ @buffer.push("�l")
2463
+ elsif not(@closed)
2464
+ @buffer.push("<br />\r\n")
2465
+ end
2466
+ @buffer
2467
+ end
2468
+
2469
+ def parse
2470
+ first = read_char
2471
+ if found = @@accent_table[first]
2472
+ if found2 = found[@stream.peek_char(0)]
2473
+ if found2.is_a?(Hash)
2474
+ if found3 = found2[@stream.peek_char(1)]
2475
+ first = Accent_tag.new(self, *found3)
2476
+ @encount_accent = true
2477
+ @chuuki_table[:accent] = true
2478
+ read_char
2479
+ read_char
2480
+ end
2481
+ elsif found2
2482
+ first = Accent_tag.new(self, *found2)
2483
+ @encount_accent = true
2484
+ read_char
2485
+ @chuuki_table[:accent] = true
2486
+ end
2487
+ end
2488
+ end
2489
+ case first
2490
+ when "��"
2491
+ first = dispatch_gaiji
2492
+ when "�m"
2493
+ first = dispatch_aozora_command
2494
+ when @@ku
2495
+ assign_kunoji
2496
+ when "�s"
2497
+ first = apply_ruby
2498
+ end
2499
+ if first == "\r\n"
2500
+ if @encount_accent
2501
+ puts "�x��(#{scount}�s��):�A�N�Z���g�����̋T�b���ʂ̎n�߂ƏI��肪�A�s���ő����Ă��܂���"
2502
+ end
2503
+ throw :terminate
2504
+ elsif first == "�l"
2505
+ @closed = true
2506
+ throw :terminate
2507
+ elsif first == "�b"
2508
+ ruby_buf_dump
2509
+ @ruby_buf_protected = true
2510
+ elsif first != "" and first != nil
2511
+ illegal_char_check(first)
2512
+ push_chars(first)
2513
+ end
2514
+ end
2515
+
2516
+ def process ()
2517
+ catch(:terminate){
2518
+ loop{
2519
+ parse
2520
+ }
2521
+ }
2522
+ general_output
2523
+ end
2524
+ end
2525
+
2526
+ if $0 == __FILE__
2527
+ # todo: �����`�F�b�N�Ƃ�
2528
+ Aozora2Html.new($*[0],$*[1]).process
2529
+ end