aozora2html 0.9.0 → 0.9.1
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 +5 -5
- data/.github/workflows/ruby.yml +25 -0
- data/.rubocop.yml +227 -0
- data/CHANGELOG.md +33 -0
- data/LICENSE +116 -0
- data/README.md +6 -1
- data/aozora2html.gemspec +6 -8
- data/bin/aozora2html +1 -0
- data/lib/aozora2html/accent_parser.rb +2 -2
- data/lib/aozora2html/error.rb +3 -3
- data/lib/aozora2html/header.rb +2 -2
- data/lib/aozora2html/i18n.rb +12 -1
- data/lib/aozora2html/ruby_buffer.rb +2 -2
- data/lib/aozora2html/tag_parser.rb +1 -1
- data/lib/aozora2html/utils.rb +11 -0
- data/lib/aozora2html/version.rb +1 -1
- data/lib/extensions.rb +4 -0
- data/lib/t2hs.rb +536 -459
- data/test/test_aozora2html.rb +164 -7
- data/test/test_font_size_tag.rb +7 -0
- data/test/test_ruby_parse.rb +14 -0
- metadata +12 -39
- data/appveyor.yml +0 -23
data/bin/aozora2html
CHANGED
@@ -20,7 +20,7 @@ class Aozora2Html
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def general_output # 出力は配列で返す
|
23
|
-
@ruby_buf.
|
23
|
+
@ruby_buf.dump_into(@buffer)
|
24
24
|
if !@encount_accent
|
25
25
|
@buffer.unshift("〔".encode("shift_jis"))
|
26
26
|
end
|
@@ -71,7 +71,7 @@ class Aozora2Html
|
|
71
71
|
@closed = true
|
72
72
|
throw :terminate
|
73
73
|
elsif first == RUBY_PREFIX
|
74
|
-
@ruby_buf.
|
74
|
+
@ruby_buf.dump_into(@buffer)
|
75
75
|
@ruby_buf.protected = true
|
76
76
|
elsif first != "" and first != nil
|
77
77
|
illegal_char_check(first, line_number)
|
data/lib/aozora2html/error.rb
CHANGED
@@ -4,11 +4,11 @@ require "aozora2html/i18n"
|
|
4
4
|
class Aozora2Html
|
5
5
|
class Error < StandardError
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@message =
|
7
|
+
def initialize(msg)
|
8
|
+
@message = msg
|
9
9
|
end
|
10
10
|
|
11
|
-
def message(line)
|
11
|
+
def message(line = 0)
|
12
12
|
I18n.t(:error_stop, line, @message)
|
13
13
|
end
|
14
14
|
end
|
data/lib/aozora2html/header.rb
CHANGED
@@ -20,8 +20,8 @@ class Aozora2Html
|
|
20
20
|
|
21
21
|
def header_element_type(string)
|
22
22
|
original = true
|
23
|
-
string.each_char do |
|
24
|
-
code =
|
23
|
+
string.each_char do |ch|
|
24
|
+
code = ch.unpack("H*")[0]
|
25
25
|
if ("00" <= code and code <= "7f") or # 1byte
|
26
26
|
("8140" <= code and code <= "8258") or # 1-1, 3-25
|
27
27
|
("839f" <= code and code <= "8491") # 6-1, 7-81
|
data/lib/aozora2html/i18n.rb
CHANGED
@@ -7,7 +7,18 @@ class Aozora2Html
|
|
7
7
|
:use_crlf => "改行コードを、「CR+LF」にあらためてください",
|
8
8
|
:error_stop => "エラー(%d行目):%s. \r\n処理を停止します",
|
9
9
|
:invalid_font_size => "文字サイズの指定が不正です",
|
10
|
-
:unsupported_ruby => "サポートされていない複雑なルビ付けです"
|
10
|
+
:unsupported_ruby => "サポートされていない複雑なルビ付けです",
|
11
|
+
:warn_onebyte => "警告(%d行目):1バイトの「%s」が使われています",
|
12
|
+
:warn_chuki => "警告(%d行目):注記記号の誤用の可能性がある、「%s」が使われています",
|
13
|
+
:warn_jis_gaiji => "警告(%d行目):JIS外字「%s」が使われています",
|
14
|
+
:dont_crlf_in_style => "%s中に改行されました。改行をまたぐ要素にはブロック表記を用いてください",
|
15
|
+
:terminate_in_style => "%s中に本文が終了しました",
|
16
|
+
:invalid_closing => "%sを閉じようとしましたが、%s中ではありません",
|
17
|
+
:invalid_nesting => "%sを終了しようとしましたが、%s中です",
|
18
|
+
:dont_use_double_ruby => "同じ箇所に2つのルビはつけられません",
|
19
|
+
:dont_allow_triple_ruby => "1つの単語に3つのルビはつけられません",
|
20
|
+
:warn_unexpected_terminator => "警告(%d行目):予期せぬファイル終端",
|
21
|
+
:warn_undefined_command => "警告(%d行目):「%s」は未対応のコマンドのため無視します",
|
11
22
|
}
|
12
23
|
|
13
24
|
def self.t(msg, *args)
|
data/lib/aozora2html/utils.rb
CHANGED
@@ -77,6 +77,17 @@ class Aozora2Html
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
module_function :create_midashi_class
|
80
|
+
|
81
|
+
def convert_japanese_number(command)
|
82
|
+
tmp = command.tr("0-9".encode("shift_jis"), "0-9")
|
83
|
+
tmp.tr!("一二三四五六七八九〇".encode("shift_jis"),"1234567890")
|
84
|
+
tmp.gsub!(/(\d)#{"十".encode("shift_jis")}(\d)/){"#{$1}#{$2}"}
|
85
|
+
tmp.gsub!(/(\d)#{"十".encode("shift_jis")}/){"#{$1}0"}
|
86
|
+
tmp.gsub!(/#{"十".encode("shift_jis")}(\d)/){"1#{$1}"}
|
87
|
+
tmp.gsub!(/#{"十".encode("shift_jis")}/,"10")
|
88
|
+
tmp
|
89
|
+
end
|
90
|
+
module_function :convert_japanese_number
|
80
91
|
end
|
81
92
|
end
|
82
93
|
|
data/lib/aozora2html/version.rb
CHANGED
data/lib/extensions.rb
CHANGED
data/lib/t2hs.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
# -*- coding:
|
2
|
-
#
|
3
|
-
require "cgi"
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
# 青空文庫形式のテキストファイルを html に整形する ruby スクリプト
|
4
3
|
require "extensions"
|
5
4
|
require "aozora2html/error"
|
6
5
|
require "jstream"
|
@@ -11,30 +10,104 @@ require "aozora2html/style_stack"
|
|
11
10
|
require "aozora2html/header"
|
12
11
|
require "aozora2html/ruby_buffer"
|
13
12
|
require "aozora2html/yaml_loader"
|
14
|
-
require "aozora2html/zip"
|
15
13
|
require "aozora2html/utils"
|
16
14
|
|
17
15
|
$gaiji_dir = "../../../gaiji/"
|
18
16
|
|
19
17
|
$css_files = Array["../../aozora.css"]
|
20
18
|
|
21
|
-
#
|
19
|
+
# 変換器本体
|
22
20
|
class Aozora2Html
|
23
21
|
|
24
|
-
#
|
22
|
+
# 全角バックスラッシュが出せないから直打ち
|
25
23
|
KU = ["18e5"].pack("h*").force_encoding("shift_jis")
|
26
24
|
NOJI = ["18f5"].pack("h*").force_encoding("shift_jis")
|
27
25
|
DAKUTEN = ["18d8"].pack("h*").force_encoding("shift_jis")
|
28
|
-
GAIJI_MARK = "
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
26
|
+
GAIJI_MARK = "※".to_sjis
|
27
|
+
IGETA_MARK = "#".to_sjis
|
28
|
+
RUBY_BEGIN_MARK = "《".to_sjis
|
29
|
+
RUBY_END_MARK = "》".to_sjis
|
30
|
+
PAREN_BEGIN_MARK = "(".to_sjis
|
31
|
+
PAREN_END_MARK = ")".to_sjis
|
32
|
+
SIZE_SMALL = "小".to_sjis
|
33
|
+
SIZE_MIDDLE = "中".to_sjis
|
34
|
+
SIZE_LARGE = "大".to_sjis
|
35
|
+
TEIHON_MARK = "底本:".to_sjis
|
36
|
+
COMMAND_BEGIN = "[".to_sjis
|
37
|
+
COMMAND_END = "]".to_sjis
|
38
|
+
ACCENT_BEGIN = "〔".to_sjis
|
39
|
+
ACCENT_END = "〕".to_sjis
|
40
|
+
AOZORABUNKO = "青空文庫".to_sjis
|
41
|
+
#PAT_EDITOR = /[校訂|編|編集|編集校訂|校訂編集]$/
|
42
|
+
PAT_EDITOR = "(校訂|編|編集)$".to_sjis
|
43
|
+
PAT_HENYAKU = "編訳$".to_sjis
|
44
|
+
PAT_TRANSLATOR = "訳$".to_sjis
|
45
|
+
RUBY_PREFIX = "|".to_sjis
|
46
|
+
PAT_RUBY = /#{"《.*?》".to_sjis}/
|
47
|
+
PAT_DIRECTION = "(右|左|上|下)に(.*)".to_sjis
|
48
|
+
PAT_REF = "^「.+」".to_sjis
|
49
|
+
CHUUKI_COMMAND = "注記付き".to_sjis
|
50
|
+
TCY_COMMAND = "縦中横".to_sjis
|
51
|
+
KEIGAKOMI_COMMAND = "罫囲み".to_sjis
|
52
|
+
YOKOGUMI_COMMAND = "横組み".to_sjis
|
53
|
+
CAPTION_COMMAND = "キャプション".to_sjis
|
54
|
+
WARIGAKI_COMMAND = "割書".to_sjis
|
55
|
+
KAERITEN_COMMAND = "返り点".to_sjis
|
56
|
+
KUNTEN_OKURIGANA_COMMAND = "訓点送り仮名".to_sjis
|
57
|
+
MIDASHI_COMMAND = "見出し".to_sjis
|
58
|
+
OMIDASHI_COMMAND = "大見出し".to_sjis
|
59
|
+
NAKAMIDASHI_COMMAND = "中見出し".to_sjis
|
60
|
+
KOMIDASHI_COMMAND = "小見出し".to_sjis
|
61
|
+
DOGYO_OMIDASHI_COMMAND = "同行大見出し".to_sjis
|
62
|
+
DOGYO_NAKAMIDASHI_COMMAND = "同行中見出し".to_sjis
|
63
|
+
DOGYO_KOMIDASHI_COMMAND = "同行小見出し".to_sjis
|
64
|
+
MADO_OMIDASHI_COMMAND = "窓大見出し".to_sjis
|
65
|
+
MADO_NAKAMIDASHI_COMMAND = "窓中見出し".to_sjis
|
66
|
+
MADO_KOMIDASHI_COMMAND = "窓小見出し".to_sjis
|
67
|
+
LEFT_MARK = "左".to_sjis
|
68
|
+
UNDER_MARK = "下".to_sjis
|
69
|
+
OVER_MARK = "上".to_sjis
|
70
|
+
MAIN_MARK = "本文".to_sjis
|
71
|
+
END_MARK = "終わり".to_sjis
|
72
|
+
TEN_MARK = "点".to_sjis
|
73
|
+
SEN_MARK = "線".to_sjis
|
74
|
+
OPEN_MARK = "ここから".to_sjis
|
75
|
+
CLOSE_MARK = "ここで".to_sjis
|
76
|
+
MADE_MARK = "まで".to_sjis
|
77
|
+
DOGYO_MARK = "同行".to_sjis
|
78
|
+
MADO_MARK = "窓".to_sjis
|
79
|
+
JIAGE_COMMAND = "字上げ".to_sjis
|
80
|
+
JISAGE_COMMAND = "字下げ".to_sjis
|
81
|
+
PHOTO_COMMAND = "写真".to_sjis
|
82
|
+
ORIKAESHI_COMMAND = "折り返して".to_sjis
|
83
|
+
ONELINE_COMMAND = "この行".to_sjis
|
84
|
+
NON_0213_GAIJI = "非0213外字".to_sjis
|
85
|
+
WARICHU_COMMAND = "割り注".to_sjis
|
86
|
+
TENTSUKI_COMMAND = "天付き".to_sjis
|
87
|
+
PAT_REST_NOTES = "(左|下)に「(.*)」の(ルビ|注記|傍記)".to_sjis
|
88
|
+
PAT_KUTEN = /#{"「※」[は|の]".to_sjis}/
|
89
|
+
PAT_KUTEN_DUAL = "※.*※".to_sjis
|
90
|
+
PAT_GAIJI = "(?:#)(.*)(?:、)(.*)".to_sjis
|
91
|
+
PAT_KAERITEN = "^([一二三四五六七八九十レ上中下甲乙丙丁天地人]+)$".to_sjis
|
92
|
+
PAT_OKURIGANA = "^((.+))$".to_sjis
|
93
|
+
PAT_REMOVE_OKURIGANA = /#{"[()]".to_sjis}/
|
94
|
+
PAT_CHITSUKI = /#{"(地付き|字上げ)(終わり)*$".to_sjis}/
|
95
|
+
PAT_ORIKAESHI_JISAGE = "折り返して(\\d*)字下げ".to_sjis
|
96
|
+
PAT_ORIKAESHI_JISAGE2 = "(\\d*)字下げ、折り返して(\\d*)字下げ".to_sjis
|
97
|
+
PAT_JI_LEN = "([0-9]+)字".to_sjis
|
98
|
+
PAT_INLINE_RUBY = "「(.*)」の注記付き".to_sjis
|
99
|
+
PAT_IMAGE = "(.*)((fig.+\\.png)(、横([0-9]+)×縦([0-9]+))*)入る".to_sjis
|
100
|
+
PAT_FRONTREF = "「([^「」]*(?:「.+」)*[^「」]*)」[にはの](「.+」の)*(.+)".to_sjis
|
101
|
+
PAT_RUBY_DIR = "(左|下)に「([^」]*)」の(ルビ|注記)".to_sjis
|
102
|
+
PAT_CHUUKI = /#{"「(.+?)」の注記".to_sjis}/
|
103
|
+
PAT_BOUKI = /#{"「(.)」の傍記".to_sjis}/
|
104
|
+
PAT_CHARSIZE = /#{"(.*)段階(..)な文字".to_sjis}/
|
105
|
+
|
106
|
+
DYNAMIC_CONTENTS = ("<div id=\"card\">\r\n<hr />\r\n<br />\r\n" +
|
107
|
+
"<a href=\"JavaScript:goLibCard();\" id=\"goAZLibCard\">●図書カード</a>" +
|
108
|
+
"<script type=\"text/javascript\" src=\"../../contents.js\"></script>\r\n" +
|
109
|
+
"<script type=\"text/javascript\" src=\"../../golibcard.js\"></script>\r\n" +
|
110
|
+
"</div>").to_sjis
|
38
111
|
|
39
112
|
# KUNOJI = ["18e518f5"].pack("h*")
|
40
113
|
# utf8 ["fecbf8fecbcb"].pack("h*")
|
@@ -49,24 +122,24 @@ class Aozora2Html
|
|
49
122
|
JIS2UCS = loader.load("../yml/jis2ucs.yml")
|
50
123
|
|
51
124
|
INDENT_TYPE = {
|
52
|
-
:jisage => "
|
53
|
-
:chitsuki => "
|
54
|
-
:midashi => "
|
55
|
-
:jizume => "
|
56
|
-
:yokogumi => "
|
57
|
-
:keigakomi => "
|
58
|
-
:caption => "
|
59
|
-
:futoji => "
|
60
|
-
:shatai => "
|
61
|
-
:dai => "
|
62
|
-
:sho => "
|
125
|
+
:jisage => "字下げ".to_sjis,
|
126
|
+
:chitsuki => "地付き".to_sjis,
|
127
|
+
:midashi => "見出し".to_sjis,
|
128
|
+
:jizume => "字詰め".to_sjis,
|
129
|
+
:yokogumi => "横組み".to_sjis,
|
130
|
+
:keigakomi => "罫囲み".to_sjis,
|
131
|
+
:caption => "キャプション".to_sjis,
|
132
|
+
:futoji => "太字".to_sjis,
|
133
|
+
:shatai => "斜体".to_sjis,
|
134
|
+
:dai => "大きな文字".to_sjis,
|
135
|
+
:sho => "小さな文字".to_sjis,
|
63
136
|
}
|
64
137
|
|
65
138
|
DAKUTEN_KATAKANA_TABLE = {
|
66
|
-
"2" => "
|
67
|
-
"3" => "
|
68
|
-
"4" => "
|
69
|
-
"5" => "
|
139
|
+
"2" => "ワ゛".to_sjis,
|
140
|
+
"3" => "ヰ゛".to_sjis,
|
141
|
+
"4" => "ヱ゛".to_sjis,
|
142
|
+
"5" => "ヲ゛".to_sjis,
|
70
143
|
}
|
71
144
|
|
72
145
|
def initialize(input, output)
|
@@ -82,17 +155,17 @@ class Aozora2Html
|
|
82
155
|
end
|
83
156
|
@buffer = []
|
84
157
|
@ruby_buf = RubyBuffer.new
|
85
|
-
@section = :head ##
|
86
|
-
@header = Aozora2Html::Header.new() ##
|
87
|
-
@style_stack = StyleStack.new
|
88
|
-
@chuuki_table = {} ##
|
89
|
-
@images = [] ##
|
90
|
-
@indent_stack = []
|
158
|
+
@section = :head ## 現在処理中のセクション(:head,:head_end,:chuuki,:chuuki_in,:body,:tail)
|
159
|
+
@header = Aozora2Html::Header.new() ## ヘッダ行の配列
|
160
|
+
@style_stack = StyleStack.new ##スタイルのスタック
|
161
|
+
@chuuki_table = {} ## 最後にどの注記を出すかを保持しておく
|
162
|
+
@images = [] ## 使用した外字の画像保持用
|
163
|
+
@indent_stack = [] ## 基本はシンボルだが、ぶらさげのときはdivタグの文字列が入る
|
91
164
|
@tag_stack = []
|
92
|
-
@midashi_id = 0 ##
|
93
|
-
@terprip = true ##
|
94
|
-
@endchar = :eof ##
|
95
|
-
@noprint = nil
|
165
|
+
@midashi_id = 0 ## 見出しのカウンタ、見出しの種類によって増分が異なる
|
166
|
+
@terprip = true ## 改行制御用 (terpriはLisp由来?)
|
167
|
+
@endchar = :eof ## 解析終了文字、AccentParserやTagParserでは異なる
|
168
|
+
@noprint = nil ## 行末を読み込んだとき、何も出力しないかどうかのフラグ
|
96
169
|
end
|
97
170
|
|
98
171
|
def line_number
|
@@ -100,18 +173,18 @@ class Aozora2Html
|
|
100
173
|
end
|
101
174
|
|
102
175
|
def block_allowed_context?
|
103
|
-
# inline_tag
|
176
|
+
# inline_tagが開いていないかチェックすれば十分
|
104
177
|
@style_stack.empty?
|
105
178
|
end
|
106
179
|
|
107
|
-
#
|
180
|
+
# 一文字読み込む
|
108
181
|
def read_char
|
109
182
|
@stream.read_char
|
110
183
|
end
|
111
184
|
|
112
|
-
#
|
185
|
+
# 指定された終端文字(1文字のStringかCRLF)まで読み込む
|
113
186
|
#
|
114
|
-
# @param [String] endchar
|
187
|
+
# @param [String] endchar 終端文字
|
115
188
|
def read_to(endchar)
|
116
189
|
buf = ""
|
117
190
|
loop do
|
@@ -129,22 +202,27 @@ class Aozora2Html
|
|
129
202
|
end
|
130
203
|
|
131
204
|
def read_accent
|
132
|
-
Aozora2Html::AccentParser.new(@stream,
|
205
|
+
Aozora2Html::AccentParser.new(@stream, ACCENT_END, @chuuki_table, @images).process
|
133
206
|
end
|
134
207
|
|
135
208
|
def read_to_nest(endchar)
|
136
209
|
Aozora2Html::TagParser.new(@stream, endchar, @chuuki_table, @images).process
|
137
210
|
end
|
138
211
|
|
212
|
+
# 1行読み込み
|
213
|
+
#
|
214
|
+
# 合わせて@bufferもクリアする
|
215
|
+
# @return [String] 読み込んだ文字列を返す
|
216
|
+
#
|
139
217
|
def read_line
|
140
218
|
tmp = read_to("\r\n")
|
141
219
|
@buffer = []
|
142
220
|
tmp
|
143
221
|
end
|
144
222
|
|
145
|
-
# parse
|
223
|
+
# parseする
|
146
224
|
#
|
147
|
-
#
|
225
|
+
# 終了時(終端まで来た場合)にはthrow :terminateで脱出する
|
148
226
|
#
|
149
227
|
def process
|
150
228
|
begin
|
@@ -171,6 +249,7 @@ class Aozora2Html
|
|
171
249
|
|
172
250
|
def char_type(char)
|
173
251
|
begin
|
252
|
+
## `String#char_type`も定義されているのに注意
|
174
253
|
char.char_type
|
175
254
|
rescue
|
176
255
|
:else
|
@@ -184,11 +263,7 @@ class Aozora2Html
|
|
184
263
|
end
|
185
264
|
|
186
265
|
def dynamic_contents
|
187
|
-
@out.print
|
188
|
-
"<a href=\"JavaScript:goLibCard();\" id=\"goAZLibCard\">���}���J�[�h</a>" +
|
189
|
-
"<script type=\"text/javascript\" src=\"../../contents.js\"></script>\r\n" +
|
190
|
-
"<script type=\"text/javascript\" src=\"../../golibcard.js\"></script>\r\n" +
|
191
|
-
"</div>"
|
266
|
+
@out.print DYNAMIC_CONTENTS
|
192
267
|
end
|
193
268
|
|
194
269
|
def close
|
@@ -196,6 +271,8 @@ class Aozora2Html
|
|
196
271
|
@out.close
|
197
272
|
end
|
198
273
|
|
274
|
+
# 記法のシンボル名から文字列へ変換する
|
275
|
+
# シンボルが見つからなければそのまま返す
|
199
276
|
def convert_indent_type(type)
|
200
277
|
INDENT_TYPE[type] || type
|
201
278
|
end
|
@@ -228,16 +305,17 @@ class Aozora2Html
|
|
228
305
|
end
|
229
306
|
end
|
230
307
|
|
308
|
+
# 本文が終わってよいかチェックし、終わっていなければ例外をあげる
|
231
309
|
def ensure_close
|
232
310
|
if n = @indent_stack.last
|
233
|
-
raise Aozora2Html::Error,
|
311
|
+
raise Aozora2Html::Error, I18n.t(:terminate_in_style, convert_indent_type(n))
|
234
312
|
end
|
235
313
|
end
|
236
314
|
|
237
315
|
def explicit_close(type)
|
238
316
|
n = check_close_match(type)
|
239
317
|
if n
|
240
|
-
raise Aozora2Html::Error,
|
318
|
+
raise Aozora2Html::Error, I18n.t(:invalid_closing, n, n)
|
241
319
|
end
|
242
320
|
if tag = @tag_stack.pop
|
243
321
|
push_chars(tag)
|
@@ -263,7 +341,7 @@ class Aozora2Html
|
|
263
341
|
end
|
264
342
|
|
265
343
|
def judge_chuuki
|
266
|
-
#
|
344
|
+
# 注記が入るかどうかチェック
|
267
345
|
i = 0
|
268
346
|
loop do
|
269
347
|
case @stream.peek_char(i)
|
@@ -272,11 +350,10 @@ class Aozora2Html
|
|
272
350
|
when "\r\n"
|
273
351
|
if i == 0 && @stream.peek_char(1) == "\r\n"
|
274
352
|
@section = :body
|
275
|
-
return
|
276
353
|
else
|
277
354
|
@section = :chuuki
|
278
|
-
return
|
279
355
|
end
|
356
|
+
return
|
280
357
|
else
|
281
358
|
@section = :body
|
282
359
|
@out.print("<br />\r\n")
|
@@ -285,16 +362,16 @@ class Aozora2Html
|
|
285
362
|
end
|
286
363
|
end
|
287
364
|
|
288
|
-
# header
|
365
|
+
# headerは一行ずつ読む
|
289
366
|
def parse_header
|
290
367
|
string = read_line
|
291
368
|
# refine from Tomita 09/06/14
|
292
|
-
if string == "" #
|
369
|
+
if string == "" # 空行がくれば、そこでヘッダー終了とみなす
|
293
370
|
@section = :head_end
|
294
371
|
@out.print @header.to_html
|
295
372
|
else
|
296
373
|
string.gsub!(RUBY_PREFIX,"")
|
297
|
-
string.gsub!(
|
374
|
+
string.gsub!(PAT_RUBY,"")
|
298
375
|
@header.push(string)
|
299
376
|
end
|
300
377
|
end
|
@@ -311,10 +388,20 @@ class Aozora2Html
|
|
311
388
|
end
|
312
389
|
end
|
313
390
|
|
391
|
+
# 使うべきではない文字があるかチェックする
|
392
|
+
#
|
393
|
+
# 警告を出力するだけで結果には影響を与えない。警告する文字は以下:
|
394
|
+
#
|
395
|
+
# * 1バイト文字
|
396
|
+
# * `#`ではなく`♯`
|
397
|
+
# * JIS(JIS X 0208)外字
|
398
|
+
#
|
399
|
+
# @return [void]
|
400
|
+
#
|
314
401
|
def illegal_char_check(char, line)
|
315
402
|
if char.is_a?(String)
|
316
403
|
code = char.unpack("H*")[0]
|
317
|
-
if
|
404
|
+
if code == "21" or
|
318
405
|
code == "23" or
|
319
406
|
("a1" <= code and code <= "a5") or
|
320
407
|
("28" <= code and code <= "29") or
|
@@ -323,15 +410,15 @@ class Aozora2Html
|
|
323
410
|
code == "3d" or
|
324
411
|
code == "3f" or
|
325
412
|
code == "2b" or
|
326
|
-
("7b" <= code and code <= "7d")
|
327
|
-
puts
|
413
|
+
("7b" <= code and code <= "7d")
|
414
|
+
puts I18n.t(:warn_onebyte, line, char)
|
328
415
|
end
|
329
416
|
|
330
417
|
if code == "81f2"
|
331
|
-
puts
|
418
|
+
puts I18n.t(:warn_chuki, line, char)
|
332
419
|
end
|
333
420
|
|
334
|
-
if (
|
421
|
+
if ("81ad" <= code and code <= "81b7") or
|
335
422
|
("81c0" <= code and code <= "81c7") or
|
336
423
|
("81cf" <= code and code <= "81d9") or
|
337
424
|
("81e9" <= code and code <= "81ef") or
|
@@ -357,35 +444,35 @@ class Aozora2Html
|
|
357
444
|
("ec40" <= code and code <= "ecfc") or
|
358
445
|
("ed40" <= code and code <= "edfc") or
|
359
446
|
("ee40" <= code and code <= "eefc") or
|
360
|
-
("ef40" <= code and code <= "effc")
|
361
|
-
puts
|
447
|
+
("ef40" <= code and code <= "effc")
|
448
|
+
puts I18n.t(:warn_jis_gaiji, line, char)
|
362
449
|
end
|
363
450
|
end
|
364
451
|
end
|
365
452
|
|
366
|
-
#
|
453
|
+
# 本体解析部
|
454
|
+
#
|
455
|
+
# 1文字ずつ読み込み、dispatchして@buffer,@ruby_bufへしまう
|
456
|
+
# 改行コードに当たったら溜め込んだものをgeneral_outputする
|
367
457
|
#
|
368
|
-
# 1�������ǂݍ��݁Adispatch����@buffer,@ruby_buf�ւ��܂�
|
369
|
-
# ���s�R�[�h�ɓ��������痭�ߍ����̂�general_output����
|
370
|
-
|
371
458
|
def parse_body
|
372
459
|
char = read_char
|
373
460
|
check = true
|
374
461
|
case char
|
375
|
-
when
|
462
|
+
when ACCENT_BEGIN
|
376
463
|
check = false
|
377
464
|
char = read_accent
|
378
|
-
when
|
465
|
+
when TEIHON_MARK[0]
|
379
466
|
if @buffer.length == 0
|
380
467
|
ending_check
|
381
468
|
end
|
382
|
-
when
|
469
|
+
when GAIJI_MARK
|
383
470
|
char = dispatch_gaiji
|
384
|
-
when
|
471
|
+
when COMMAND_BEGIN
|
385
472
|
char = dispatch_aozora_command
|
386
473
|
when KU
|
387
474
|
assign_kunoji
|
388
|
-
when
|
475
|
+
when RUBY_BEGIN_MARK
|
389
476
|
char = apply_ruby
|
390
477
|
end
|
391
478
|
|
@@ -393,11 +480,11 @@ class Aozora2Html
|
|
393
480
|
when "\r\n"
|
394
481
|
general_output
|
395
482
|
when RUBY_PREFIX
|
396
|
-
@ruby_buf.
|
483
|
+
@ruby_buf.dump_into(@buffer)
|
397
484
|
@ruby_buf.protected = true
|
398
485
|
when @endchar
|
399
486
|
# suddenly finished the file
|
400
|
-
puts
|
487
|
+
puts I18n.t(:warn_unexpected_terminator, line_number)
|
401
488
|
throw :terminate
|
402
489
|
when nil
|
403
490
|
# noop
|
@@ -409,9 +496,12 @@ class Aozora2Html
|
|
409
496
|
end
|
410
497
|
end
|
411
498
|
|
499
|
+
# 本文が終了したかどうかチェックする
|
500
|
+
#
|
501
|
+
#
|
412
502
|
def ending_check
|
413
|
-
#
|
414
|
-
if @stream.peek_char(0) ==
|
503
|
+
# `底本:`でフッタ(:tail)に遷移
|
504
|
+
if @stream.peek_char(0) == TEIHON_MARK[1] and @stream.peek_char(1) == TEIHON_MARK[2]
|
415
505
|
@section = :tail
|
416
506
|
ensure_close
|
417
507
|
@out.print "</div>\r\n<div class=\"bibliographical_information\">\r\n<hr />\r\n<br />\r\n"
|
@@ -423,23 +513,23 @@ class Aozora2Html
|
|
423
513
|
#
|
424
514
|
def push_chars(obj)
|
425
515
|
if obj.is_a?(Array)
|
426
|
-
obj.each
|
516
|
+
obj.each do |x|
|
427
517
|
push_chars(x)
|
428
|
-
|
518
|
+
end
|
429
519
|
elsif obj.is_a?(String)
|
430
520
|
if obj.length == 1
|
431
521
|
obj = obj.gsub(/[&\"<>]/, {'&' => '&', '"' => '"', '<' => '<', '>' => '>'})
|
432
522
|
end
|
433
|
-
obj.each_char
|
523
|
+
obj.each_char do |x|
|
434
524
|
push_char(x)
|
435
|
-
|
525
|
+
end
|
436
526
|
else
|
437
527
|
push_char(obj)
|
438
528
|
end
|
439
529
|
end
|
440
530
|
|
441
531
|
def push_char(char)
|
442
|
-
|
532
|
+
ctype = char_type(char)
|
443
533
|
if ctype == :hankaku_terminate and @ruby_buf.char_type == :hankaku
|
444
534
|
if @ruby_buf.last_is_string?
|
445
535
|
@ruby_buf.last_concat(char)
|
@@ -455,54 +545,64 @@ class Aozora2Html
|
|
455
545
|
@ruby_buf.push("")
|
456
546
|
end
|
457
547
|
else
|
458
|
-
@ruby_buf.
|
548
|
+
@ruby_buf.dump_into(@buffer)
|
459
549
|
@ruby_buf.clear(char)
|
460
550
|
@ruby_buf.char_type = ctype
|
461
551
|
end
|
462
552
|
end
|
463
553
|
|
554
|
+
# 行出力時に@bufferが空かどうか調べる
|
555
|
+
#
|
556
|
+
# @bufferの中身によって行末の出力が異なるため
|
557
|
+
#
|
558
|
+
# @return [true, false, :inline] 空文字ではない文字列が入っていればfalse、1行注記なら:inline、それ以外しか入っていなければtrue
|
559
|
+
#
|
464
560
|
def buf_is_blank?(buf)
|
465
|
-
buf.each
|
466
|
-
if token.is_a?(String) and
|
561
|
+
buf.each do |token|
|
562
|
+
if token.is_a?(String) and token != ""
|
467
563
|
return false
|
468
564
|
elsif token.is_a?(Aozora2Html::Tag::OnelineIndent)
|
469
565
|
return :inline
|
470
566
|
end
|
471
|
-
|
567
|
+
end
|
472
568
|
true
|
473
569
|
end
|
474
570
|
|
475
|
-
#
|
571
|
+
# 行末で<br />を出力するべきかどうかの判別用
|
572
|
+
#
|
573
|
+
# @return [true, false] Multilineの注記しか入っていなければfalse、Multilineでも空文字でもない要素が含まれていればtrue
|
476
574
|
#
|
477
575
|
def terpri?(buf)
|
478
576
|
flag = true
|
479
|
-
buf.each
|
577
|
+
buf.each do |x|
|
480
578
|
if x.is_a?(Aozora2Html::Tag::Multiline)
|
481
579
|
flag = false
|
482
|
-
elsif
|
483
|
-
|
580
|
+
elsif x == ""
|
581
|
+
# skip
|
484
582
|
else
|
485
583
|
return true
|
486
584
|
end
|
487
|
-
|
585
|
+
end
|
488
586
|
flag
|
489
587
|
end
|
490
588
|
|
491
|
-
#
|
589
|
+
# 読み込んだ行の出力を行う
|
590
|
+
#
|
591
|
+
# parserが改行文字を読み込んだら呼ばれる。
|
592
|
+
# 最終的に@ruby_bufと@bufferは初期化する
|
492
593
|
#
|
493
|
-
#
|
494
|
-
# @ruby_buf��@buffer�͏���������
|
594
|
+
# @return [void]
|
495
595
|
#
|
496
596
|
def general_output
|
497
597
|
if @style_stack.last
|
498
|
-
raise Aozora2Html::Error,
|
598
|
+
raise Aozora2Html::Error, I18n.t(:dont_crlf_in_style, @style_stack.last_command)
|
499
599
|
end
|
500
|
-
# buffer
|
600
|
+
# bufferにインデントタグだけがあったら改行しない!
|
501
601
|
if @noprint
|
502
602
|
@noprint = false
|
503
603
|
return
|
504
604
|
end
|
505
|
-
@ruby_buf.
|
605
|
+
@ruby_buf.dump_into(@buffer)
|
506
606
|
buf = @buffer
|
507
607
|
@ruby_buf.clear
|
508
608
|
@buffer = []
|
@@ -512,23 +612,23 @@ class Aozora2Html
|
|
512
612
|
terprip = (terpri?(buf) and @terprip)
|
513
613
|
@terprip = true
|
514
614
|
|
515
|
-
if @indent_stack.last.is_a?(String) and
|
615
|
+
if @indent_stack.last.is_a?(String) and !indent_type
|
516
616
|
@out.print @indent_stack.last
|
517
617
|
end
|
518
618
|
|
519
|
-
buf.each
|
619
|
+
buf.each do |s|
|
520
620
|
if s.is_a?(Aozora2Html::Tag::OnelineIndent)
|
521
621
|
tail.unshift(s.close_tag)
|
522
622
|
elsif s.is_a?(Aozora2Html::Tag::UnEmbedGaiji) and !s.escaped?
|
523
|
-
#
|
524
|
-
@out.print
|
623
|
+
# 消してあった※を復活させて
|
624
|
+
@out.print GAIJI_MARK
|
525
625
|
end
|
526
626
|
@out.print s.to_s
|
527
|
-
|
627
|
+
end
|
528
628
|
|
529
|
-
#
|
629
|
+
# 最後はCRLFを出力する
|
530
630
|
if @indent_stack.last.is_a?(String)
|
531
|
-
#
|
631
|
+
# ぶら下げindent
|
532
632
|
# tail always active
|
533
633
|
@out.print tail.map{|s| s.to_s}.join("")
|
534
634
|
if indent_type == :inline
|
@@ -546,9 +646,9 @@ class Aozora2Html
|
|
546
646
|
end
|
547
647
|
end
|
548
648
|
|
549
|
-
#
|
649
|
+
# 前方参照の発見 Ruby,style重ねがけ等々のため、要素の配列で返す
|
550
650
|
#
|
551
|
-
#
|
651
|
+
# 前方参照は`○○[#「○○」に傍点]`、`吹喋[#「喋」に「ママ」の注記]`といった表記
|
552
652
|
def search_front_reference(string)
|
553
653
|
if string.length == 0
|
554
654
|
return false
|
@@ -562,9 +662,9 @@ class Aozora2Html
|
|
562
662
|
if last_string.is_a?(String)
|
563
663
|
if last_string == ""
|
564
664
|
searching_buf.pop
|
565
|
-
search_front_reference(string
|
665
|
+
search_front_reference(string)
|
566
666
|
elsif last_string.match(Regexp.new(Regexp.quote(string)+"$"))
|
567
|
-
#
|
667
|
+
# 完全一致
|
568
668
|
# start = match.begin(0)
|
569
669
|
# tail = match.end(0)
|
570
670
|
# last_string[start,tail-start] = ""
|
@@ -572,7 +672,7 @@ class Aozora2Html
|
|
572
672
|
searching_buf.push(last_string.sub(Regexp.new(Regexp.quote(string)+"$"),""))
|
573
673
|
[string]
|
574
674
|
elsif string.match(Regexp.new(Regexp.quote(last_string)+"$"))
|
575
|
-
#
|
675
|
+
# 部分一致
|
576
676
|
tmp = searching_buf.pop
|
577
677
|
found = search_front_reference(string.sub(Regexp.new(Regexp.quote(last_string)+"$"),""))
|
578
678
|
if found
|
@@ -585,11 +685,11 @@ class Aozora2Html
|
|
585
685
|
elsif last_string.is_a?(Aozora2Html::Tag::ReferenceMentioned)
|
586
686
|
inner = last_string.target_string
|
587
687
|
if inner == string
|
588
|
-
#
|
688
|
+
# 完全一致
|
589
689
|
searching_buf.pop
|
590
690
|
[last_string]
|
591
691
|
elsif string.match(Regexp.new(Regexp.quote(inner)+"$"))
|
592
|
-
#
|
692
|
+
# 部分一致
|
593
693
|
tmp = searching_buf.pop
|
594
694
|
found = search_front_reference(string.sub(Regexp.new(Regexp.quote(inner)+"$"),""))
|
595
695
|
if found
|
@@ -604,60 +704,50 @@ class Aozora2Html
|
|
604
704
|
end
|
605
705
|
end
|
606
706
|
|
607
|
-
#
|
707
|
+
# 発見した前方参照を元に戻す
|
708
|
+
#
|
709
|
+
# @ruby_bufがあれば@ruby_bufに、なければ@bufferにpushする
|
710
|
+
# バッファの最後と各要素が文字列ならconcatし、どちらが文字列でなければ(concatできないので)pushする
|
711
|
+
#
|
712
|
+
# @return [void]
|
713
|
+
#
|
608
714
|
def recovery_front_reference(reference)
|
609
|
-
reference.each
|
715
|
+
reference.each do |elt|
|
610
716
|
# if @ruby_buf.protected
|
611
717
|
if @ruby_buf.present?
|
612
|
-
if @ruby_buf.last_is_string?
|
613
|
-
|
614
|
-
@ruby_buf.last_concat(elt)
|
615
|
-
else
|
616
|
-
@ruby_buf.push(elt)
|
617
|
-
end
|
718
|
+
if @ruby_buf.last_is_string? && elt.is_a?(String)
|
719
|
+
@ruby_buf.last_concat(elt)
|
618
720
|
else
|
619
721
|
@ruby_buf.push(elt)
|
620
722
|
end
|
621
|
-
|
622
|
-
if
|
623
|
-
|
624
|
-
@buffer.last.concat(elt)
|
625
|
-
else
|
626
|
-
@buffer.push(elt)
|
627
|
-
end
|
723
|
+
elsif @buffer.last.is_a?(String)
|
724
|
+
if elt.is_a?(String)
|
725
|
+
@buffer.last.concat(elt)
|
628
726
|
else
|
629
|
-
@
|
727
|
+
@buffer.push(elt)
|
630
728
|
end
|
729
|
+
else
|
730
|
+
@ruby_buf.push(elt)
|
631
731
|
end
|
632
|
-
|
633
|
-
end
|
634
|
-
|
635
|
-
def convert_japanese_number(command)
|
636
|
-
tmp = command.tr("�O-�X", "0-9")
|
637
|
-
tmp.tr!("���O�l�ܘZ������Z","1234567890")
|
638
|
-
tmp.gsub!(/(\d)�\(\d)/){"#{$1}#{$2}"}
|
639
|
-
tmp.gsub!(/(\d)�\/){"#{$1}0"}
|
640
|
-
tmp.gsub!(/�\(\d)/){"1#{$1}"}
|
641
|
-
tmp.gsub!(/�\/,"10")
|
642
|
-
tmp
|
732
|
+
end
|
643
733
|
end
|
644
734
|
|
645
735
|
def kuten2png(substring)
|
646
|
-
desc = substring.gsub(
|
736
|
+
desc = substring.gsub(PAT_KUTEN,"")
|
647
737
|
match = desc.match(/[12]\-\d{1,2}\-\d{1,2}/)
|
648
|
-
if
|
738
|
+
if match and !desc.match(NON_0213_GAIJI) and !desc.match(PAT_KUTEN_DUAL)
|
649
739
|
@chuuki_table[:newjis] = true
|
650
740
|
codes = match[0].split("-")
|
651
741
|
folder = sprintf("%1d-%02d", codes[0], codes[1])
|
652
742
|
code = sprintf("%1d-%02d-%02d",*codes)
|
653
|
-
Aozora2Html::Tag::EmbedGaiji.new(self, folder, code, desc.gsub!(
|
743
|
+
Aozora2Html::Tag::EmbedGaiji.new(self, folder, code, desc.gsub!(IGETA_MARK,""))
|
654
744
|
else
|
655
745
|
substring
|
656
746
|
end
|
657
747
|
end
|
658
748
|
|
659
749
|
def escape_gaiji(command)
|
660
|
-
_whole, kanji, line = command.match(
|
750
|
+
_whole, kanji, line = command.match(PAT_GAIJI).to_a
|
661
751
|
tmp = @images.assoc(kanji)
|
662
752
|
if tmp
|
663
753
|
tmp.push(line)
|
@@ -668,68 +758,72 @@ class Aozora2Html
|
|
668
758
|
end
|
669
759
|
|
670
760
|
def dispatch_gaiji
|
671
|
-
|
672
|
-
if
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
761
|
+
# 「※」の次が「[」でなければ外字ではない
|
762
|
+
if @stream.peek_char(0) != COMMAND_BEGIN
|
763
|
+
return GAIJI_MARK
|
764
|
+
end
|
765
|
+
|
766
|
+
# 「[」を読み捨てる
|
767
|
+
_ = read_char
|
768
|
+
# embed?
|
769
|
+
command, _raw = read_to_nest(COMMAND_END)
|
770
|
+
try_emb = kuten2png(command)
|
771
|
+
if try_emb != command
|
772
|
+
try_emb
|
773
|
+
elsif command.match(/U\+([0-9A-F]{4,5})/) && Aozora2Html::Tag::EmbedGaiji.use_unicode
|
774
|
+
unicode_num = $1
|
775
|
+
Aozora2Html::Tag::EmbedGaiji.new(self, nil, nil, command, unicode_num)
|
686
776
|
else
|
687
|
-
|
777
|
+
# Unemb
|
778
|
+
escape_gaiji(command)
|
688
779
|
end
|
689
780
|
end
|
690
781
|
|
782
|
+
# 注記記法の場合分け
|
691
783
|
def dispatch_aozora_command
|
692
|
-
|
693
|
-
|
784
|
+
# 「[」の次が「#」でなければ注記ではない
|
785
|
+
if @stream.peek_char(0) != IGETA_MARK
|
786
|
+
return COMMAND_BEGIN
|
787
|
+
end
|
788
|
+
|
789
|
+
# 「#」を読み捨てる
|
790
|
+
_ = read_char
|
791
|
+
command,raw = read_to_nest(COMMAND_END)
|
792
|
+
# 適用順序はこれで大丈夫か? 誤爆怖いよ誤爆
|
793
|
+
if command.match(ORIKAESHI_COMMAND)
|
794
|
+
apply_burasage(command)
|
795
|
+
|
796
|
+
elsif command.start_with?(OPEN_MARK)
|
797
|
+
exec_block_start_command(command)
|
798
|
+
elsif command.start_with?(CLOSE_MARK)
|
799
|
+
exec_block_end_command(command)
|
800
|
+
|
801
|
+
elsif command.match(WARICHU_COMMAND)
|
802
|
+
apply_warichu(command)
|
803
|
+
elsif command.match(JISAGE_COMMAND)
|
804
|
+
apply_jisage(command)
|
805
|
+
elsif command.match(/fig(\d)+_(\d)+\.png/)
|
806
|
+
exec_img_command(command,raw)
|
807
|
+
# avoid to try complex ruby -- escape to notes
|
808
|
+
elsif command.match(PAT_REST_NOTES)
|
809
|
+
apply_rest_notes(command)
|
810
|
+
elsif command.end_with?(END_MARK)
|
811
|
+
exec_inline_end_command(command)
|
812
|
+
nil
|
813
|
+
elsif command.match(PAT_REF)
|
814
|
+
exec_frontref_command(command)
|
815
|
+
elsif command.match(/1-7-8[2345]/)
|
816
|
+
apply_dakuten_katakana(command)
|
817
|
+
elsif command.match(PAT_KAERITEN)
|
818
|
+
Aozora2Html::Tag::Kaeriten.new(self, command)
|
819
|
+
elsif command.match(PAT_OKURIGANA)
|
820
|
+
Aozora2Html::Tag::Okurigana.new(self, command.gsub!(PAT_REMOVE_OKURIGANA,""))
|
821
|
+
elsif command.match(PAT_CHITSUKI)
|
822
|
+
apply_chitsuki(command)
|
823
|
+
elsif exec_inline_start_command(command)
|
824
|
+
nil
|
694
825
|
else
|
695
|
-
|
696
|
-
command,raw = read_to_nest("�n")
|
697
|
-
# �K�p�����͂���ő��v���H�@�딚�|����딚
|
698
|
-
if command.match(/�܂�Ԃ���/)
|
699
|
-
apply_burasage(command)
|
700
|
-
|
701
|
-
elsif command.match(/^��������/)
|
702
|
-
exec_block_start_command(command)
|
703
|
-
elsif command.match(/^������/)
|
704
|
-
exec_block_end_command(command)
|
705
|
-
|
706
|
-
elsif command.match(/���蒍/)
|
707
|
-
apply_warichu(command)
|
708
|
-
elsif command.match(/������/)
|
709
|
-
apply_jisage(command)
|
710
|
-
elsif command.match(/fig(\d)+_(\d)+\.png/)
|
711
|
-
exec_img_command(command,raw)
|
712
|
-
# avoid to try complex ruby -- escape to notes
|
713
|
-
elsif command.match(/(��|��)�Ɂu(.*)�v��(���r|���L|�T�L)/)
|
714
|
-
apply_rest_notes(command)
|
715
|
-
elsif command.match(/�I���$/)
|
716
|
-
exec_inline_end_command(command)
|
717
|
-
nil
|
718
|
-
elsif command.match(/^�u.+�v/)
|
719
|
-
exec_frontref_command(command)
|
720
|
-
elsif command.match(/1-7-8[2345]/)
|
721
|
-
apply_dakuten_katakana(command)
|
722
|
-
elsif command.match(/^([���O�l�ܘZ������\���㒆���b�������V�n�l]+)$/)
|
723
|
-
Aozora2Html::Tag::Kaeriten.new(self, command)
|
724
|
-
elsif command.match(/^�i(.+)�j$/)
|
725
|
-
Aozora2Html::Tag::Okurigana.new(self, command.gsub!(/[�i�j]/,""))
|
726
|
-
elsif command.match(/(�n�t��|���グ)(�I���)*$/)
|
727
|
-
apply_chitsuki(command)
|
728
|
-
elsif exec_inline_start_command(command)
|
729
|
-
nil
|
730
|
-
else
|
731
|
-
apply_rest_notes(command)
|
732
|
-
end
|
826
|
+
apply_rest_notes(command)
|
733
827
|
end
|
734
828
|
end
|
735
829
|
|
@@ -740,12 +834,12 @@ class Aozora2Html
|
|
740
834
|
general_output
|
741
835
|
end
|
742
836
|
@noprint = true # always no print
|
743
|
-
command = convert_japanese_number(command)
|
744
|
-
if command.match(
|
745
|
-
width = command.match(
|
837
|
+
command = Utils.convert_japanese_number(command)
|
838
|
+
if command.match(TENTSUKI_COMMAND)
|
839
|
+
width = command.match(PAT_ORIKAESHI_JISAGE)[1]
|
746
840
|
tag = '<div class="burasage" style="margin-left: ' + width + 'em; text-indent: -' + width + 'em;">'
|
747
841
|
else
|
748
|
-
match = command.match(
|
842
|
+
match = command.match(PAT_ORIKAESHI_JISAGE2)
|
749
843
|
left, indent = match.to_a[1,2]
|
750
844
|
left = left.to_i - indent.to_i
|
751
845
|
tag = "<div class=\"burasage\" style=\"margin-left: #{indent}em; text-indent: #{left}em;\">"
|
@@ -756,58 +850,52 @@ class Aozora2Html
|
|
756
850
|
end
|
757
851
|
|
758
852
|
def jisage_width(command)
|
759
|
-
convert_japanese_number(command).match(/(\d*)(
|
853
|
+
Utils.convert_japanese_number(command).match(/(\d*)(?:#{JISAGE_COMMAND})/)[1]
|
760
854
|
end
|
761
855
|
|
762
856
|
def apply_jisage(command)
|
763
|
-
if command.match(
|
764
|
-
#
|
857
|
+
if command.match(MADE_MARK) or command.match(END_MARK)
|
858
|
+
# 字下げ終わり
|
765
859
|
explicit_close(:jisage)
|
766
860
|
@indent_stack.pop
|
767
861
|
nil
|
862
|
+
elsif command.match(ONELINE_COMMAND)
|
863
|
+
# 1行だけ
|
864
|
+
@buffer.unshift(Aozora2Html::Tag::OnelineJisage.new(self, jisage_width(command)))
|
865
|
+
nil
|
866
|
+
elsif @buffer.length == 0 and @stream.peek_char(0) == "\r\n"
|
867
|
+
# commandのみ
|
868
|
+
@terprip = false
|
869
|
+
implicit_close(:jisage)
|
870
|
+
# adhook hack
|
871
|
+
@noprint = false
|
872
|
+
@indent_stack.push(:jisage)
|
873
|
+
Aozora2Html::Tag::MultilineJisage.new(self, jisage_width(command))
|
768
874
|
else
|
769
|
-
|
770
|
-
|
771
|
-
@buffer.unshift(Aozora2Html::Tag::OnelineJisage.new(self, jisage_width(command)))
|
772
|
-
nil
|
773
|
-
else
|
774
|
-
if @buffer.length == 0 and @stream.peek_char(0) == "\r\n"
|
775
|
-
# command�̂�
|
776
|
-
@terprip = false
|
777
|
-
implicit_close(:jisage)
|
778
|
-
# adhook hack
|
779
|
-
@noprint = false
|
780
|
-
@indent_stack.push(:jisage)
|
781
|
-
Aozora2Html::Tag::MultilineJisage.new(self, jisage_width(command))
|
782
|
-
else
|
783
|
-
@buffer.unshift(Aozora2Html::Tag::OnelineJisage.new(self, jisage_width(command)))
|
784
|
-
nil
|
785
|
-
end
|
786
|
-
end
|
875
|
+
@buffer.unshift(Aozora2Html::Tag::OnelineJisage.new(self, jisage_width(command)))
|
876
|
+
nil
|
787
877
|
end
|
788
878
|
end
|
789
879
|
|
790
880
|
def apply_warichu(command)
|
791
|
-
if command.match(
|
792
|
-
if @stream.peek_char(0) !=
|
793
|
-
push_chars(
|
881
|
+
if command.match(END_MARK)
|
882
|
+
if @stream.peek_char(0) != PAREN_END_MARK
|
883
|
+
push_chars(PAREN_END_MARK)
|
794
884
|
end
|
795
885
|
push_chars('</span>')
|
796
886
|
else
|
797
887
|
check = @ruby_buf.last
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
push_chars('<span class="warichu">')
|
802
|
-
push_chars('�i')
|
888
|
+
push_chars('<span class="warichu">')
|
889
|
+
unless check.is_a?(String) and check.end_with?(PAREN_BEGIN_MARK)
|
890
|
+
push_chars(PAREN_BEGIN_MARK)
|
803
891
|
end
|
804
892
|
end
|
805
893
|
nil
|
806
894
|
end
|
807
895
|
|
808
896
|
def chitsuki_length(command)
|
809
|
-
command = convert_japanese_number(command)
|
810
|
-
if match = command.match(
|
897
|
+
command = Utils.convert_japanese_number(command)
|
898
|
+
if match = command.match(PAT_JI_LEN)
|
811
899
|
match[1]
|
812
900
|
else
|
813
901
|
"0"
|
@@ -815,54 +903,55 @@ class Aozora2Html
|
|
815
903
|
end
|
816
904
|
|
817
905
|
def apply_chitsuki(string, multiline = false)
|
818
|
-
if string.match(
|
819
|
-
string.match(
|
906
|
+
if string.match(CLOSE_MARK+INDENT_TYPE[:chitsuki]+END_MARK) or
|
907
|
+
string.match(CLOSE_MARK+JIAGE_COMMAND+END_MARK)
|
820
908
|
explicit_close(:chitsuki)
|
821
909
|
@indent_stack.pop
|
822
910
|
nil
|
823
911
|
else
|
824
|
-
|
912
|
+
len = chitsuki_length(string)
|
825
913
|
if multiline
|
826
|
-
#
|
914
|
+
# 複数行指定
|
827
915
|
implicit_close(:chitsuki)
|
828
916
|
@indent_stack.push(:chitsuki)
|
829
|
-
Aozora2Html::Tag::MultilineChitsuki.new(self,
|
917
|
+
Aozora2Html::Tag::MultilineChitsuki.new(self, len)
|
830
918
|
else
|
831
|
-
# 1
|
832
|
-
Aozora2Html::Tag::OnelineChitsuki.new(self,
|
919
|
+
# 1行のみ
|
920
|
+
Aozora2Html::Tag::OnelineChitsuki.new(self, len)
|
833
921
|
end
|
834
922
|
end
|
835
923
|
end
|
836
924
|
|
837
925
|
def new_midashi_id(size)
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
926
|
+
if size.kind_of?(Integer)
|
927
|
+
@midashi_id += size
|
928
|
+
return @midashi_id
|
929
|
+
end
|
930
|
+
|
931
|
+
case size
|
932
|
+
when /#{SIZE_SMALL}/
|
933
|
+
inc = 1
|
934
|
+
when /#{SIZE_MIDDLE}/
|
935
|
+
inc = 10
|
936
|
+
when /#{SIZE_LARGE}/
|
937
|
+
inc = 100
|
849
938
|
else
|
850
|
-
|
939
|
+
raise Aozora2Html::Error, I18n.t(:undefined_header)
|
851
940
|
end
|
852
941
|
@midashi_id += inc
|
853
942
|
end
|
854
943
|
|
855
944
|
def apply_midashi(command)
|
856
945
|
@indent_stack.push(:midashi)
|
946
|
+
if command.match(DOGYO_MARK)
|
947
|
+
midashi_type = :dogyo
|
948
|
+
elsif command.match(MADO_MARK)
|
949
|
+
midashi_type = :mado
|
950
|
+
else
|
857
951
|
midashi_type = :normal
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
midashi_type = :mado
|
862
|
-
else
|
863
|
-
@terprip = false
|
864
|
-
end
|
865
|
-
Aozora2Html::Tag::MultilineMidashi.new(self,command,midashi_type)
|
952
|
+
@terprip = false
|
953
|
+
end
|
954
|
+
Aozora2Html::Tag::MultilineMidashi.new(self, command, midashi_type)
|
866
955
|
end
|
867
956
|
|
868
957
|
def apply_yokogumi(command)
|
@@ -881,7 +970,7 @@ class Aozora2Html
|
|
881
970
|
end
|
882
971
|
|
883
972
|
def apply_jizume(command)
|
884
|
-
w = convert_japanese_number(command).match(/(\d*)(
|
973
|
+
w = Utils.convert_japanese_number(command).match(/(\d*)(?:#{INDENT_TYPE[:jizume]})/)[1]
|
885
974
|
@indent_stack.push(:jizume)
|
886
975
|
Aozora2Html::Tag::Jizume.new(self, w)
|
887
976
|
end
|
@@ -891,175 +980,177 @@ class Aozora2Html
|
|
891
980
|
closing.concat(tag.close_tag)
|
892
981
|
end
|
893
982
|
|
983
|
+
def detect_style_size(style)
|
984
|
+
if style.match("小".to_sjis)
|
985
|
+
:sho
|
986
|
+
else
|
987
|
+
:dai
|
988
|
+
end
|
989
|
+
end
|
990
|
+
|
894
991
|
def exec_inline_start_command(command)
|
895
992
|
case command
|
896
|
-
when
|
993
|
+
when CHUUKI_COMMAND
|
897
994
|
@style_stack.push([command,'</ruby>'])
|
898
995
|
push_char('<ruby><rb>')
|
899
|
-
when
|
996
|
+
when TCY_COMMAND
|
900
997
|
@style_stack.push([command,'</span>'])
|
901
998
|
push_char('<span dir="ltr">')
|
902
|
-
when
|
999
|
+
when KEIGAKOMI_COMMAND
|
903
1000
|
@style_stack.push([command,'</span>'])
|
904
1001
|
push_chars('<span class="keigakomi">')
|
905
|
-
when
|
1002
|
+
when YOKOGUMI_COMMAND
|
906
1003
|
@style_stack.push([command,'</span>'])
|
907
1004
|
push_chars('<span class="yokogumi">')
|
908
|
-
when
|
1005
|
+
when CAPTION_COMMAND
|
909
1006
|
@style_stack.push([command,'</span>'])
|
910
1007
|
push_chars('<span class="caption">')
|
911
|
-
when
|
1008
|
+
when WARIGAKI_COMMAND
|
912
1009
|
@style_stack.push([command,'</span>'])
|
913
1010
|
push_chars('<span class="warigaki">')
|
914
|
-
when
|
1011
|
+
when OMIDASHI_COMMAND
|
915
1012
|
@style_stack.push([command,'</a></h3>'])
|
916
1013
|
@terprip = false
|
917
1014
|
push_chars("<h3 class=\"o-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(100)}\">")
|
918
|
-
when
|
1015
|
+
when NAKAMIDASHI_COMMAND
|
919
1016
|
@style_stack.push([command,'</a></h4>'])
|
920
1017
|
@terprip = false
|
921
1018
|
push_chars("<h4 class=\"naka-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(10)}\">")
|
922
|
-
when
|
1019
|
+
when KOMIDASHI_COMMAND
|
923
1020
|
@style_stack.push([command,'</a></h5>'])
|
924
1021
|
@terprip = false
|
925
1022
|
push_chars("<h5 class=\"ko-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(1)}\">")
|
926
|
-
when
|
1023
|
+
when DOGYO_OMIDASHI_COMMAND
|
927
1024
|
@style_stack.push([command,'</a></h3>'])
|
928
1025
|
push_chars("<h3 class=\"dogyo-o-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(100)}\">")
|
929
|
-
when
|
1026
|
+
when DOGYO_NAKAMIDASHI_COMMAND
|
930
1027
|
@style_stack.push([command,'</a></h4>'])
|
931
1028
|
push_chars("<h4 class=\"dogyo-naka-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(10)}\">")
|
932
|
-
when
|
1029
|
+
when DOGYO_KOMIDASHI_COMMAND
|
933
1030
|
@style_stack.push([command,'</a></h5>'])
|
934
1031
|
push_chars("<h5 class=\"dogyo-ko-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(1)}\">")
|
935
|
-
when
|
1032
|
+
when MADO_OMIDASHI_COMMAND
|
936
1033
|
@style_stack.push([command,'</a></h3>'])
|
937
1034
|
push_chars("<h3 class=\"mado-o-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(100)}\">")
|
938
|
-
when
|
1035
|
+
when MADO_NAKAMIDASHI_COMMAND
|
939
1036
|
@style_stack.push([command,'</a></h4>'])
|
940
1037
|
push_chars("<h4 class=\"mado-naka-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(10)}\">")
|
941
|
-
when
|
1038
|
+
when MADO_KOMIDASHI_COMMAND
|
942
1039
|
@style_stack.push([command,'</a></h5>'])
|
943
1040
|
push_chars("<h5 class=\"mado-ko-midashi\"><a class=\"midashi_anchor\" id=\"midashi#{new_midashi_id(1)}\">")
|
1041
|
+
when PAT_CHARSIZE
|
1042
|
+
@style_stack.push([command,'</span>'])
|
1043
|
+
_whole, nest, style = command.match(PAT_CHARSIZE).to_a
|
1044
|
+
times = Utils.convert_japanese_number(nest).to_i
|
1045
|
+
daisho = detect_style_size(style)
|
1046
|
+
html_class = daisho.to_s + times.to_s
|
1047
|
+
size = Utils.create_font_size(times, daisho)
|
1048
|
+
push_chars("<span class=\"#{html_class}\" style=\"font-size: #{size};\">")
|
944
1049
|
else
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
if command.match(/(�E|��|��|��)��(.*)/)
|
962
|
-
_whole, dir, com = command.match(/(�E|��|��|��)��(.*)/).to_a
|
963
|
-
# renew command
|
964
|
-
key = com
|
965
|
-
if command.match(/�_/)
|
966
|
-
case dir
|
967
|
-
when "��", "��"
|
968
|
-
filter = lambda{|x| x + "_after"}
|
969
|
-
end
|
970
|
-
elsif command.match(/��/)
|
971
|
-
case dir
|
972
|
-
when "��", "��"
|
973
|
-
filter = lambda{|x| x.sub("under","over")}
|
974
|
-
end
|
1050
|
+
## Decoration ##
|
1051
|
+
key = command
|
1052
|
+
filter = lambda{|x| x}
|
1053
|
+
if command.match(PAT_DIRECTION)
|
1054
|
+
_whole, dir, com = command.match(PAT_DIRECTION).to_a
|
1055
|
+
# renew command
|
1056
|
+
key = com
|
1057
|
+
if command.match(TEN_MARK)
|
1058
|
+
case dir
|
1059
|
+
when LEFT_MARK, UNDER_MARK
|
1060
|
+
filter = lambda{|x| x + "_after"}
|
1061
|
+
end
|
1062
|
+
elsif command.match(SEN_MARK)
|
1063
|
+
case dir
|
1064
|
+
when LEFT_MARK, OVER_MARK
|
1065
|
+
filter = lambda{|x| x.sub("under","over")}
|
975
1066
|
end
|
976
1067
|
end
|
1068
|
+
end
|
977
1069
|
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
end
|
987
|
-
nil
|
1070
|
+
found = COMMAND_TABLE[key]
|
1071
|
+
# found = [class, tag]
|
1072
|
+
if found
|
1073
|
+
@style_stack.push([command,"</#{found[1]}>"])
|
1074
|
+
push_chars("<#{found[1]} class=\"#{filter.call(found[0])}\">")
|
1075
|
+
else
|
1076
|
+
if $DEBUG
|
1077
|
+
puts I18n.t(:warn_undefined_command, line_number, key)
|
988
1078
|
end
|
1079
|
+
nil
|
989
1080
|
end
|
990
1081
|
end
|
991
1082
|
end
|
992
1083
|
|
993
1084
|
def exec_inline_end_command(command)
|
994
|
-
encount = command.sub(
|
995
|
-
if encount ==
|
1085
|
+
encount = command.sub(END_MARK,"")
|
1086
|
+
if encount == MAIN_MARK
|
996
1087
|
# force to finish main_text
|
997
1088
|
@section = :tail
|
998
1089
|
ensure_close
|
999
1090
|
@noprint = true
|
1000
1091
|
@out.print "</div>\r\n<div class=\"after_text\">\r\n<hr />\r\n"
|
1001
|
-
elsif encount.match(
|
1092
|
+
elsif encount.match(CHUUKI_COMMAND) and @style_stack.last_command == CHUUKI_COMMAND
|
1002
1093
|
# special inline ruby
|
1003
1094
|
@style_stack.pop
|
1004
|
-
_whole, ruby = encount.match(
|
1005
|
-
push_char("</rb><rp
|
1095
|
+
_whole, ruby = encount.match(PAT_INLINE_RUBY).to_a
|
1096
|
+
push_char("</rb><rp>(</rp><rt>".to_sjis + ruby + "</rt><rp>)</rp></ruby>".to_sjis)
|
1006
1097
|
elsif @style_stack.last_command.match(encount)
|
1007
1098
|
push_chars(@style_stack.pop[1])
|
1008
1099
|
else
|
1009
|
-
raise Aozora2Html::Error,
|
1100
|
+
raise Aozora2Html::Error, I18n.t(:invalid_nesting, encount, @style_stack.last_command)
|
1010
1101
|
end
|
1011
1102
|
end
|
1012
1103
|
|
1013
1104
|
def exec_block_start_command(command)
|
1014
1105
|
original_command = command.dup
|
1015
|
-
command.sub!(
|
1106
|
+
command.sub!(/^#{OPEN_MARK}/, "")
|
1016
1107
|
match = ""
|
1017
|
-
if command.match(
|
1108
|
+
if command.match(INDENT_TYPE[:jisage])
|
1018
1109
|
push_block_tag(apply_jisage(command),match)
|
1019
|
-
elsif command.match(/(
|
1110
|
+
elsif command.match(/(#{INDENT_TYPE[:chitsuki]}|#{JIAGE_COMMAND})$/)
|
1020
1111
|
push_block_tag(apply_chitsuki(command,true),match)
|
1021
1112
|
end
|
1022
1113
|
|
1023
|
-
if command.match(
|
1114
|
+
if command.match(INDENT_TYPE[:midashi])
|
1024
1115
|
push_block_tag(apply_midashi(command),match)
|
1025
1116
|
end
|
1026
1117
|
|
1027
|
-
if command.match(
|
1118
|
+
if command.match(INDENT_TYPE[:jizume])
|
1028
1119
|
if match != ""
|
1029
1120
|
@indent_stack.pop
|
1030
1121
|
end
|
1031
1122
|
push_block_tag(apply_jizume(command),match)
|
1032
1123
|
end
|
1033
1124
|
|
1034
|
-
if command.match(
|
1125
|
+
if command.match(INDENT_TYPE[:yokogumi])
|
1035
1126
|
if match != ""
|
1036
1127
|
@indent_stack.pop
|
1037
1128
|
end
|
1038
1129
|
push_block_tag(apply_yokogumi(command),match)
|
1039
1130
|
end
|
1040
1131
|
|
1041
|
-
if command.match(
|
1132
|
+
if command.match(INDENT_TYPE[:keigakomi])
|
1042
1133
|
if match != ""
|
1043
1134
|
@indent_stack.pop
|
1044
1135
|
end
|
1045
1136
|
push_block_tag(apply_keigakomi(command),match)
|
1046
1137
|
end
|
1047
1138
|
|
1048
|
-
if command.match(
|
1139
|
+
if command.match(INDENT_TYPE[:caption])
|
1049
1140
|
if match != ""
|
1050
1141
|
@indent_stack.pop
|
1051
1142
|
end
|
1052
1143
|
push_block_tag(apply_caption(command),match)
|
1053
1144
|
end
|
1054
1145
|
|
1055
|
-
if command.match(
|
1146
|
+
if command.match(INDENT_TYPE[:futoji])
|
1056
1147
|
if match != ""
|
1057
1148
|
@indent_stack.pop
|
1058
1149
|
end
|
1059
1150
|
push_block_tag(Aozora2Html::Tag::MultilineStyle.new(self, "futoji"),match)
|
1060
1151
|
@indent_stack.push(:futoji)
|
1061
1152
|
end
|
1062
|
-
if command.match(
|
1153
|
+
if command.match(INDENT_TYPE[:shatai])
|
1063
1154
|
if match != ""
|
1064
1155
|
@indent_stack.pop
|
1065
1156
|
end
|
@@ -1067,18 +1158,14 @@ class Aozora2Html
|
|
1067
1158
|
@indent_stack.push(:shatai)
|
1068
1159
|
end
|
1069
1160
|
|
1070
|
-
if command.match(
|
1071
|
-
_whole, nest, style = command.match(
|
1161
|
+
if command.match(PAT_CHARSIZE)
|
1162
|
+
_whole, nest, style = command.match(PAT_CHARSIZE).to_a
|
1072
1163
|
if match != ""
|
1073
1164
|
@indent_stack.pop
|
1074
1165
|
end
|
1075
|
-
daisho =
|
1076
|
-
:sho
|
1077
|
-
else
|
1078
|
-
:dai
|
1079
|
-
end
|
1166
|
+
daisho = detect_style_size(style)
|
1080
1167
|
push_block_tag(Aozora2Html::Tag::FontSize.new(self,
|
1081
|
-
convert_japanese_number(nest).to_i,
|
1168
|
+
Utils.convert_japanese_number(nest).to_i,
|
1082
1169
|
daisho),
|
1083
1170
|
match)
|
1084
1171
|
@indent_stack.push(daisho)
|
@@ -1092,37 +1179,25 @@ class Aozora2Html
|
|
1092
1179
|
end
|
1093
1180
|
end
|
1094
1181
|
|
1182
|
+
# コマンド文字列からモードのシンボルを取り出す
|
1183
|
+
#
|
1184
|
+
# @return [Symbol]
|
1185
|
+
#
|
1095
1186
|
def detect_command_mode(command)
|
1096
|
-
if command.match(
|
1097
|
-
:
|
1098
|
-
elsif command.match(/(�n�t��|���グ)�I���$/)
|
1099
|
-
:chitsuki
|
1100
|
-
elsif command.match(/���o��/)
|
1101
|
-
:midashi
|
1102
|
-
elsif command.match(/���l��/)
|
1103
|
-
:jizume
|
1104
|
-
elsif command.match(/���g��/)
|
1105
|
-
:yokogumi
|
1106
|
-
elsif command.match(/�r�͂�/)
|
1107
|
-
:keigakomi
|
1108
|
-
elsif command.match(/�L���v�V����/)
|
1109
|
-
:caption
|
1110
|
-
elsif command.match(/����/)
|
1111
|
-
:futoji
|
1112
|
-
elsif command.match(/�Α�/)
|
1113
|
-
:shatai
|
1114
|
-
elsif command.match(/�傫�ȕ���/)
|
1115
|
-
:dai
|
1116
|
-
elsif command.match(/�����ȕ���/)
|
1117
|
-
:sho
|
1118
|
-
else
|
1119
|
-
nil
|
1187
|
+
if command.match(INDENT_TYPE[:chitsuki]+END_MARK) || command.match(JIAGE_COMMAND+END_MARK)
|
1188
|
+
return :chitsuki
|
1120
1189
|
end
|
1190
|
+
INDENT_TYPE.keys.each do |key|
|
1191
|
+
if command.match(INDENT_TYPE[key])
|
1192
|
+
return key
|
1193
|
+
end
|
1194
|
+
end
|
1195
|
+
return nil
|
1121
1196
|
end
|
1122
1197
|
|
1123
1198
|
def exec_block_end_command(command)
|
1124
1199
|
original_command = command.dup
|
1125
|
-
command.sub!(
|
1200
|
+
command.sub!(/^#{CLOSE_MARK}/, "")
|
1126
1201
|
match = false
|
1127
1202
|
mode = detect_command_mode(command)
|
1128
1203
|
if mode
|
@@ -1141,10 +1216,10 @@ class Aozora2Html
|
|
1141
1216
|
end
|
1142
1217
|
|
1143
1218
|
def exec_img_command(command,raw)
|
1144
|
-
match = raw.match(
|
1219
|
+
match = raw.match(PAT_IMAGE)
|
1145
1220
|
if match
|
1146
1221
|
_whole, alt, src, _wh, width, height = match.to_a
|
1147
|
-
css_class = if alt.match(
|
1222
|
+
css_class = if alt.match(PHOTO_COMMAND)
|
1148
1223
|
"photo"
|
1149
1224
|
else
|
1150
1225
|
"illustration"
|
@@ -1156,12 +1231,12 @@ class Aozora2Html
|
|
1156
1231
|
end
|
1157
1232
|
|
1158
1233
|
def exec_frontref_command(command)
|
1159
|
-
_whole, reference, spec1, spec2 = command.match(
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1234
|
+
_whole, reference, spec1, spec2 = command.match(PAT_FRONTREF).to_a
|
1235
|
+
if spec1
|
1236
|
+
spec = spec1 + spec2
|
1237
|
+
else
|
1238
|
+
spec = spec2
|
1239
|
+
end
|
1165
1240
|
if reference and found = search_front_reference(reference)
|
1166
1241
|
tmp = exec_style(found, spec)
|
1167
1242
|
if tmp
|
@@ -1174,17 +1249,19 @@ class Aozora2Html
|
|
1174
1249
|
apply_rest_notes(command)
|
1175
1250
|
end
|
1176
1251
|
|
1252
|
+
# 傍記を並べる用
|
1253
|
+
#
|
1177
1254
|
def multiply(bouki, times)
|
1178
|
-
|
1179
|
-
(times
|
1180
|
-
s += bouki
|
1181
|
-
s += " "
|
1182
|
-
}
|
1183
|
-
s + bouki
|
1255
|
+
sep = " "
|
1256
|
+
([bouki]*times).join(sep)
|
1184
1257
|
end
|
1185
1258
|
|
1259
|
+
# arrayがルビを含んでいればそのインデックスを返す
|
1260
|
+
#
|
1261
|
+
# @return [Integer, nil]
|
1262
|
+
#
|
1186
1263
|
def include_ruby?(array)
|
1187
|
-
array.index
|
1264
|
+
array.index do |elt|
|
1188
1265
|
if elt.is_a?(Aozora2Html::Tag::Ruby)
|
1189
1266
|
true
|
1190
1267
|
elsif elt.is_a?(Aozora2Html::Tag::ReferenceMentioned)
|
@@ -1194,16 +1271,19 @@ class Aozora2Html
|
|
1194
1271
|
elt.target.is_a?(Aozora2Html::Tag::Ruby)
|
1195
1272
|
end
|
1196
1273
|
end
|
1197
|
-
|
1274
|
+
end
|
1198
1275
|
end
|
1199
1276
|
|
1277
|
+
# rubyタグの再生成(本体はrearrange_ruby)
|
1278
|
+
#
|
1200
1279
|
# complex ruby wrap up utilities -- don't erase! we will use soon ...
|
1280
|
+
#
|
1201
1281
|
def rearrange_ruby_tag(targets, upper_ruby, under_ruby = "")
|
1202
|
-
target,upper,under = rearrange_ruby(targets, upper_ruby, under_ruby)
|
1203
|
-
Aozora2Html::Tag::Ruby.new(self, target,upper,under)
|
1282
|
+
target, upper, under = rearrange_ruby(targets, upper_ruby, under_ruby)
|
1283
|
+
Aozora2Html::Tag::Ruby.new(self, target, upper, under)
|
1204
1284
|
end
|
1205
1285
|
|
1206
|
-
# ruby
|
1286
|
+
# rubyタグの再割り当て
|
1207
1287
|
def rearrange_ruby(targets, upper_ruby, under_ruby = "")
|
1208
1288
|
if include_ruby?(targets)
|
1209
1289
|
new_targets = []
|
@@ -1218,26 +1298,26 @@ class Aozora2Html
|
|
1218
1298
|
[]
|
1219
1299
|
end
|
1220
1300
|
if new_upper.length > 1 and new_under.length > 1
|
1221
|
-
raise Aozora2Html::Error,
|
1301
|
+
raise Aozora2Html::Error, I18n.t(:dont_allow_triple_ruby)
|
1222
1302
|
end
|
1223
1303
|
|
1224
1304
|
targets.each{|x|
|
1225
1305
|
if x.is_a?(Aozora2Html::Tag::Ruby)
|
1226
1306
|
if x.target.is_a?(Array)
|
1227
1307
|
# inner Aozora2Html::Tag::Ruby is already complex ... give up
|
1228
|
-
raise Aozora2Html::Error,
|
1308
|
+
raise Aozora2Html::Error, I18n.t(:dont_use_double_ruby)
|
1229
1309
|
else
|
1230
1310
|
if x.ruby != ""
|
1231
1311
|
if new_upper.is_a?(Array)
|
1232
1312
|
new_upper.push(x.ruby)
|
1233
1313
|
else
|
1234
|
-
|
1314
|
+
raise Aozora2Html::Error, I18n.t(:dont_use_double_ruby)
|
1235
1315
|
end
|
1236
1316
|
else
|
1237
1317
|
if new_under.is_a?(Array)
|
1238
|
-
|
1318
|
+
new_under.push(x.under_ruby)
|
1239
1319
|
else
|
1240
|
-
raise Aozora2Html::Error,
|
1320
|
+
raise Aozora2Html::Error, I18n.t(:dont_use_double_ruby)
|
1241
1321
|
end
|
1242
1322
|
end
|
1243
1323
|
new_targets.push(x.target)
|
@@ -1245,7 +1325,7 @@ class Aozora2Html
|
|
1245
1325
|
elsif x.is_a?(Aozora2Html::Tag::ReferenceMentioned)
|
1246
1326
|
if x.target.is_a?(Array)
|
1247
1327
|
# recursive
|
1248
|
-
tar,up,un = rearrange_ruby(x.target,"","")
|
1328
|
+
tar,up,un = rearrange_ruby(x.target, "", "")
|
1249
1329
|
# rotation!!
|
1250
1330
|
tar.each{|y|
|
1251
1331
|
tmp = x.dup
|
@@ -1254,12 +1334,12 @@ class Aozora2Html
|
|
1254
1334
|
if new_under.is_a?(Array)
|
1255
1335
|
new_under.concat(un)
|
1256
1336
|
elsif un.to_s.length > 0
|
1257
|
-
raise Aozora2Html::Error,
|
1337
|
+
raise Aozora2Html::Error, I18n.t(:dont_use_double_ruby)
|
1258
1338
|
end
|
1259
1339
|
if new_upper.is_a?(Array)
|
1260
1340
|
new_upper.concat(up)
|
1261
1341
|
elsif up.to_s.length > 0
|
1262
|
-
raise Aozora2Html::Error,
|
1342
|
+
raise Aozora2Html::Error, I18n.t(:dont_use_double_ruby)
|
1263
1343
|
end
|
1264
1344
|
else
|
1265
1345
|
new_targets.push(x)
|
@@ -1290,69 +1370,65 @@ class Aozora2Html
|
|
1290
1370
|
try_kuten = kuten2png(command)
|
1291
1371
|
if try_kuten != command
|
1292
1372
|
try_kuten
|
1293
|
-
elsif command.match(
|
1373
|
+
elsif command.match(TCY_COMMAND)
|
1294
1374
|
Aozora2Html::Tag::Dir.new(self, targets)
|
1295
|
-
elsif command.match(
|
1375
|
+
elsif command.match(YOKOGUMI_COMMAND)
|
1296
1376
|
Aozora2Html::Tag::InlineYokogumi.new(self, targets)
|
1297
|
-
elsif command.match(
|
1377
|
+
elsif command.match(KEIGAKOMI_COMMAND)
|
1298
1378
|
Aozora2Html::Tag::InlineKeigakomi.new(self, targets)
|
1299
|
-
elsif command.match(
|
1379
|
+
elsif command.match(CAPTION_COMMAND)
|
1300
1380
|
Aozora2Html::Tag::InlineCaption.new(self, targets)
|
1301
|
-
elsif command.match(
|
1381
|
+
elsif command.match(KAERITEN_COMMAND)
|
1302
1382
|
Aozora2Html::Tag::Kaeriten.new(self, targets)
|
1303
|
-
elsif command.match(
|
1383
|
+
elsif command.match(KUNTEN_OKURIGANA_COMMAND)
|
1304
1384
|
Aozora2Html::Tag::Okurigana.new(self, targets)
|
1305
|
-
elsif command.match(
|
1385
|
+
elsif command.match(MIDASHI_COMMAND)
|
1306
1386
|
midashi_type = :normal
|
1307
|
-
if command.match(
|
1387
|
+
if command.match(DOGYO_MARK)
|
1308
1388
|
midashi_type = :dogyo
|
1309
|
-
elsif command.match(
|
1389
|
+
elsif command.match(MADO_MARK)
|
1310
1390
|
midashi_type = :mado
|
1311
1391
|
else
|
1312
1392
|
@terprip = false
|
1313
1393
|
end
|
1314
1394
|
Aozora2Html::Tag::Midashi.new(self, targets, command, midashi_type)
|
1315
|
-
elsif command.match(
|
1316
|
-
_whole, nest, style = command.match(
|
1395
|
+
elsif command.match(PAT_CHARSIZE)
|
1396
|
+
_whole, nest, style = command.match(PAT_CHARSIZE).to_a
|
1317
1397
|
Aozora2Html::Tag::InlineFontSize.new(self,targets,
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
:dai
|
1323
|
-
end)
|
1324
|
-
elsif command.match(/(��|��)�Ɂu([^�v]*)�v��(���r|���L)/)
|
1325
|
-
_whole, dir, under = command.match(/(��|��)�Ɂu([^�v]*)�v��(���r|���L)/).to_a
|
1398
|
+
Utils.convert_japanese_number(nest).to_i,
|
1399
|
+
detect_style_size(style))
|
1400
|
+
elsif command.match(PAT_RUBY_DIR)
|
1401
|
+
_whole, _dir, under = command.match(PAT_RUBY_DIR).to_a
|
1326
1402
|
if targets.length == 1 and targets[0].is_a?(Aozora2Html::Tag::Ruby)
|
1327
1403
|
tag = targets[0]
|
1328
1404
|
if tag.under_ruby == ""
|
1329
1405
|
tag.under_ruby = under
|
1330
1406
|
tag
|
1331
1407
|
else
|
1332
|
-
raise Aozora2Html::Error,
|
1408
|
+
raise Aozora2Html::Error, I18n.t(:dont_allow_triple_ruby)
|
1333
1409
|
end
|
1334
1410
|
else
|
1335
|
-
rearrange_ruby_tag(targets,"",under)
|
1411
|
+
rearrange_ruby_tag(targets, "", under)
|
1336
1412
|
end
|
1337
|
-
elsif command.match(
|
1338
|
-
rearrange_ruby_tag(targets
|
1339
|
-
elsif command.match(
|
1340
|
-
rearrange_ruby_tag(targets,multiply(
|
1413
|
+
elsif command.match(PAT_CHUUKI)
|
1414
|
+
rearrange_ruby_tag(targets, PAT_CHUUKI.match(command).to_a[1])
|
1415
|
+
elsif command.match(PAT_BOUKI)
|
1416
|
+
rearrange_ruby_tag(targets, multiply(PAT_BOUKI.match(command).to_a[1], targets.to_s.length))
|
1341
1417
|
else
|
1342
1418
|
## direction fix! ##
|
1343
1419
|
filter = lambda{|x| x}
|
1344
|
-
if command.match(
|
1345
|
-
_whole, dir, com = command.match(
|
1420
|
+
if command.match(PAT_DIRECTION)
|
1421
|
+
_whole, dir, com = command.match(PAT_DIRECTION).to_a
|
1346
1422
|
# renew command
|
1347
1423
|
command = com
|
1348
|
-
if command.match(
|
1424
|
+
if command.match(TEN_MARK)
|
1349
1425
|
case dir
|
1350
|
-
when
|
1426
|
+
when LEFT_MARK, UNDER_MARK
|
1351
1427
|
filter = lambda{|x| x + "_after"}
|
1352
1428
|
end
|
1353
|
-
elsif command.match(
|
1429
|
+
elsif command.match(SEN_MARK)
|
1354
1430
|
case dir
|
1355
|
-
when
|
1431
|
+
when LEFT_MARK, OVER_MARK
|
1356
1432
|
filter = lambda{|x| x.sub("under","over")}
|
1357
1433
|
end
|
1358
1434
|
end
|
@@ -1378,9 +1454,9 @@ class Aozora2Html
|
|
1378
1454
|
end
|
1379
1455
|
end
|
1380
1456
|
|
1381
|
-
#
|
1457
|
+
# くの字点の処理
|
1382
1458
|
#
|
1383
|
-
#
|
1459
|
+
# くの字点は現状そのまま出力するのでフッタの「表記について」で出力するかどうかのフラグ処理だけ行う
|
1384
1460
|
def assign_kunoji
|
1385
1461
|
second = @stream.peek_char(0)
|
1386
1462
|
case second
|
@@ -1398,19 +1474,19 @@ class Aozora2Html
|
|
1398
1474
|
Aozora2Html::Tag::EditorNote.new(self, command)
|
1399
1475
|
end
|
1400
1476
|
|
1401
|
-
#
|
1477
|
+
# |が来たときは文字種を無視してruby_bufを守らなきゃいけない
|
1402
1478
|
def apply_ruby
|
1403
1479
|
@ruby_buf.protected = nil
|
1404
|
-
ruby, _raw = read_to_nest(
|
1480
|
+
ruby, _raw = read_to_nest(RUBY_END_MARK)
|
1405
1481
|
if ruby.length == 0
|
1406
1482
|
# escaped ruby character
|
1407
|
-
return
|
1483
|
+
return RUBY_BEGIN_MARK+RUBY_END_MARK
|
1408
1484
|
end
|
1409
1485
|
ans = ""
|
1410
1486
|
notes = []
|
1411
1487
|
@ruby_buf.each do |token|
|
1412
1488
|
if token.is_a?(Aozora2Html::Tag::UnEmbedGaiji)
|
1413
|
-
ans.concat(
|
1489
|
+
ans.concat(GAIJI_MARK)
|
1414
1490
|
token.escape!
|
1415
1491
|
notes.push(token)
|
1416
1492
|
else
|
@@ -1418,28 +1494,28 @@ class Aozora2Html
|
|
1418
1494
|
end
|
1419
1495
|
end
|
1420
1496
|
@buffer.push(Aozora2Html::Tag::Ruby.new(self, ans, ruby))
|
1421
|
-
@buffer
|
1497
|
+
@buffer += notes
|
1422
1498
|
@ruby_buf.clear
|
1423
1499
|
nil
|
1424
1500
|
end
|
1425
1501
|
|
1426
|
-
# parse_body
|
1502
|
+
# parse_bodyのフッタ版
|
1427
1503
|
def parse_tail
|
1428
1504
|
char = read_char
|
1429
1505
|
check = true
|
1430
1506
|
case char
|
1431
|
-
when
|
1507
|
+
when ACCENT_BEGIN
|
1432
1508
|
check = false
|
1433
1509
|
char = read_accent
|
1434
1510
|
when @endchar
|
1435
1511
|
throw :terminate
|
1436
|
-
when
|
1512
|
+
when GAIJI_MARK
|
1437
1513
|
char = dispatch_gaiji
|
1438
|
-
when
|
1514
|
+
when COMMAND_BEGIN
|
1439
1515
|
char = dispatch_aozora_command
|
1440
1516
|
when KU
|
1441
1517
|
assign_kunoji
|
1442
|
-
when
|
1518
|
+
when RUBY_BEGIN_MARK
|
1443
1519
|
char = apply_ruby
|
1444
1520
|
end
|
1445
1521
|
|
@@ -1447,7 +1523,7 @@ class Aozora2Html
|
|
1447
1523
|
when "\r\n"
|
1448
1524
|
tail_output
|
1449
1525
|
when RUBY_PREFIX
|
1450
|
-
@ruby_buf.
|
1526
|
+
@ruby_buf.dump_into(@buffer)
|
1451
1527
|
@ruby_buf.protected = true
|
1452
1528
|
when nil
|
1453
1529
|
# noop
|
@@ -1459,14 +1535,14 @@ class Aozora2Html
|
|
1459
1535
|
end
|
1460
1536
|
end
|
1461
1537
|
|
1462
|
-
# general_output
|
1538
|
+
# general_outputのフッタ版
|
1463
1539
|
def tail_output
|
1464
|
-
@ruby_buf.
|
1540
|
+
@ruby_buf.dump_into(@buffer)
|
1465
1541
|
string = @buffer.join
|
1466
1542
|
@ruby_buf.clear
|
1467
1543
|
@buffer = []
|
1468
1544
|
string.gsub!("info@aozora.gr.jp",'<a href="mailto: info@aozora.gr.jp">info@aozora.gr.jp</a>')
|
1469
|
-
string.gsub!("
|
1545
|
+
string.gsub!("青空文庫(http://www.aozora.gr.jp/)".to_sjis){"<a href=\"http://www.aozora.gr.jp/\">#{$&}</a>"}
|
1470
1546
|
if string.match(/(<br \/>$|<\/p>$|<\/h\d>$|<div.*>$|<\/div>$|^<[^>]*>$)/)
|
1471
1547
|
@out.print string, "\r\n"
|
1472
1548
|
else
|
@@ -1474,57 +1550,58 @@ class Aozora2Html
|
|
1474
1550
|
end
|
1475
1551
|
end
|
1476
1552
|
|
1477
|
-
#
|
1553
|
+
# `●表記について`で使用した注記等を出力する
|
1478
1554
|
def hyoki
|
1479
1555
|
# <br /> times fix
|
1480
|
-
@out.print "<br />\r\n</div>\r\n<div class=\"notation_notes\">\r\n<hr />\r\n<br />\r\n
|
1481
|
-
@out.print "\t<li
|
1556
|
+
@out.print "<br />\r\n</div>\r\n<div class=\"notation_notes\">\r\n<hr />\r\n<br />\r\n●表記について<br />\r\n<ul>\r\n".to_sjis
|
1557
|
+
@out.print "\t<li>このファイルは W3C 勧告 XHTML1.1 にそった形式で作成されています。</li>\r\n".to_sjis
|
1482
1558
|
if @chuuki_table[:chuki]
|
1483
|
-
@out.print "\t<li
|
1559
|
+
@out.print "\t<li>[#…]は、入力者による注を表す記号です。</li>\r\n".to_sjis
|
1484
1560
|
end
|
1485
1561
|
if @chuuki_table[:kunoji]
|
1486
1562
|
if @chuuki_table[:dakutenkunoji]
|
1487
|
-
@out.
|
1563
|
+
@out.printf("\t<li>「くの字点」は「%s」で、「濁点付きくの字点」は「%s」で表しました。</li>\r\n".to_sjis, KU+NOJI, KU+DAKUTEN+NOJI)
|
1488
1564
|
else
|
1489
|
-
@out.
|
1565
|
+
@out.printf("\t<li>「くの字点」は「%s」で表しました。</li>\r\n".to_sjis, KU+NOJI)
|
1490
1566
|
end
|
1491
1567
|
elsif @chuuki_table[:dakutenkunoji]
|
1492
|
-
@out.
|
1568
|
+
@out.printf("\t<li>「濁点付きくの字点」は「%s」で表しました。</li>\r\n".to_sjis, KU+DAKUTEN+NOJI)
|
1493
1569
|
end
|
1494
1570
|
if @chuuki_table[:newjis] && !Aozora2Html::Tag::EmbedGaiji.use_jisx0213
|
1495
|
-
@out.print "\t<li
|
1571
|
+
@out.print "\t<li>「くの字点」をのぞくJIS X 0213にある文字は、画像化して埋め込みました。</li>\r\n".to_sjis
|
1496
1572
|
end
|
1497
1573
|
if @chuuki_table[:accent] && !Aozora2Html::Tag::Accent.use_jisx0213
|
1498
|
-
@out.print "\t<li
|
1574
|
+
@out.print "\t<li>アクセント符号付きラテン文字は、画像化して埋め込みました。</li>\r\n".to_sjis
|
1499
1575
|
end
|
1500
1576
|
if @images[0]
|
1501
|
-
@out.print "\t<li
|
1577
|
+
@out.print "\t<li>この作品には、JIS X 0213にない、以下の文字が用いられています。(数字は、底本中の出現「ページ-行」数。)これらの文字は本文内では「※[#…]」の形で示しました。</li>\r\n</ul>\r\n<br />\r\n\t\t<table class=\"gaiji_list\">\r\n".to_sjis
|
1502
1578
|
@images.each{|cell|
|
1503
1579
|
k,*v = cell
|
1580
|
+
vs = v.join("、".to_sjis)
|
1504
1581
|
@out.print " <tr>
|
1505
1582
|
<td>
|
1506
1583
|
#{k}
|
1507
1584
|
</td>
|
1508
1585
|
<td> </td>
|
1509
1586
|
<td>
|
1510
|
-
#{
|
1587
|
+
#{vs} </td>
|
1511
1588
|
<!--
|
1512
1589
|
<td>
|
1513
|
-
|
1590
|
+
<img src=\"../../../gaiji/others/xxxx.png\" alt=\"#{k}\" width=32 height=32 />
|
1514
1591
|
</td>
|
1515
1592
|
-->
|
1516
1593
|
</tr>
|
1517
|
-
"
|
1594
|
+
".to_sjis
|
1518
1595
|
}
|
1519
|
-
@out.print "\t\t</table>\r\n"
|
1596
|
+
@out.print "\t\t</table>\r\n".to_sjis
|
1520
1597
|
else
|
1521
|
-
@out.print "</ul>\r\n" # <ul
|
1598
|
+
@out.print "</ul>\r\n" # <ul>内に<li>以外のエレメントが来るのは不正なので修正
|
1522
1599
|
end
|
1523
1600
|
@out.print "</div>\r\n"
|
1524
1601
|
end
|
1525
1602
|
end
|
1526
1603
|
|
1527
1604
|
if $0 == __FILE__
|
1528
|
-
# todo:
|
1605
|
+
# todo: 引数チェックとか
|
1529
1606
|
Aozora2Html.new($*[0],$*[1]).process
|
1530
1607
|
end
|