aozora2html 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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