aozora2html 2.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rubocop.yml +19 -0
- data/.github/workflows/ruby.yml +5 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +38 -151
- data/.rubocop_todo.yml +7 -0
- data/CHANGELOG.md +41 -0
- data/Gemfile +2 -0
- data/Guardfile +3 -1
- data/HACKING.md +45 -0
- data/README.md +14 -6
- data/Rakefile +12 -5
- data/aozora2html.gemspec +25 -23
- data/bin/aozora2html +21 -19
- data/lib/aozora2html/accent_parser.rb +62 -54
- data/lib/aozora2html/error.rb +5 -4
- data/lib/aozora2html/header.rb +20 -18
- data/lib/aozora2html/i18n.rb +40 -20
- data/lib/aozora2html/midashi_counter.rb +32 -0
- data/lib/aozora2html/ruby_buffer.rb +63 -28
- data/lib/aozora2html/string_refinements.rb +36 -0
- data/lib/aozora2html/style_stack.rb +6 -0
- data/lib/aozora2html/tag/accent.rb +10 -12
- data/lib/aozora2html/tag/block.rb +11 -9
- data/lib/aozora2html/tag/chitsuki.rb +6 -2
- data/lib/aozora2html/tag/dakuten_katakana.rb +10 -8
- data/lib/aozora2html/tag/decorate.rb +4 -3
- data/lib/aozora2html/tag/dir.rb +4 -2
- data/lib/aozora2html/tag/editor_note.rb +7 -4
- data/lib/aozora2html/tag/embed_gaiji.rb +15 -11
- data/lib/aozora2html/tag/font_size.rb +5 -2
- data/lib/aozora2html/tag/gaiji.rb +4 -3
- data/lib/aozora2html/tag/img.rb +4 -4
- data/lib/aozora2html/tag/indent.rb +3 -3
- data/lib/aozora2html/tag/inline.rb +10 -7
- data/lib/aozora2html/tag/inline_caption.rb +4 -2
- data/lib/aozora2html/tag/inline_font_size.rb +4 -3
- data/lib/aozora2html/tag/inline_keigakomi.rb +4 -2
- data/lib/aozora2html/tag/inline_yokogumi.rb +4 -3
- data/lib/aozora2html/tag/jisage.rb +3 -1
- data/lib/aozora2html/tag/jizume.rb +3 -0
- data/lib/aozora2html/tag/kaeriten.rb +4 -2
- data/lib/aozora2html/tag/keigakomi.rb +15 -9
- data/lib/aozora2html/tag/kunten.rb +4 -4
- data/lib/aozora2html/tag/midashi.rb +3 -1
- data/lib/aozora2html/tag/multiline.rb +3 -0
- data/lib/aozora2html/tag/multiline_caption.rb +6 -8
- data/lib/aozora2html/tag/multiline_chitsuki.rb +3 -1
- data/lib/aozora2html/tag/multiline_jisage.rb +3 -1
- data/lib/aozora2html/tag/multiline_midashi.rb +6 -3
- data/lib/aozora2html/tag/multiline_style.rb +5 -3
- data/lib/aozora2html/tag/multiline_yokogumi.rb +6 -9
- data/lib/aozora2html/tag/okurigana.rb +4 -2
- data/lib/aozora2html/tag/oneline_chitsuki.rb +3 -2
- data/lib/aozora2html/tag/oneline_indent.rb +8 -1
- data/lib/aozora2html/tag/oneline_jisage.rb +3 -0
- data/lib/aozora2html/tag/reference_mentioned.rb +22 -21
- data/lib/aozora2html/tag/ruby.rb +174 -70
- data/lib/aozora2html/tag/un_embed_gaiji.rb +8 -2
- data/lib/aozora2html/tag.rb +40 -38
- data/lib/aozora2html/tag_parser.rb +23 -16
- data/lib/aozora2html/text_buffer.rb +50 -0
- data/lib/aozora2html/utils.rb +113 -50
- data/lib/aozora2html/version.rb +3 -1
- data/lib/aozora2html/yaml_loader.rb +8 -2
- data/lib/aozora2html/zip.rb +4 -0
- data/lib/aozora2html.rb +1329 -3
- data/lib/extensions.rb +2 -34
- data/lib/jstream.rb +96 -25
- data/sample/chukiichiran_kinyurei.html +42 -29
- data/sample/chukiichiran_kinyurei.txt +16 -3
- metadata +80 -83
- data/.travis.yml +0 -12
- data/lib/t2hs.rb +0 -1607
- data/test/test_aozora2html.rb +0 -379
- data/test/test_aozora_accent_parser.rb +0 -31
- data/test/test_command_parse.rb +0 -213
- data/test/test_compat.rb +0 -11
- data/test/test_dakuten_katakana_tag.rb +0 -27
- data/test/test_decorate_tag.rb +0 -24
- data/test/test_dir_tag.rb +0 -24
- data/test/test_editor_note_tag.rb +0 -22
- data/test/test_exception.rb +0 -23
- data/test/test_font_size_tag.rb +0 -41
- data/test/test_gaiji_tag.rb +0 -49
- data/test/test_header.rb +0 -60
- data/test/test_helper.rb +0 -5
- data/test/test_i18n.rb +0 -23
- data/test/test_img_tag.rb +0 -23
- data/test/test_inline_caption_tag.rb +0 -24
- data/test/test_inline_font_size_tag.rb +0 -34
- data/test/test_inline_keigakomi_tag.rb +0 -24
- data/test/test_inline_yokogumi_tag.rb +0 -24
- data/test/test_jizume_tag.rb +0 -25
- data/test/test_jstream.rb +0 -57
- data/test/test_kaeriten_tag.rb +0 -24
- data/test/test_keigakomi_tag.rb +0 -31
- data/test/test_midashi_tag.rb +0 -38
- data/test/test_multiline_caption_tag.rb +0 -25
- data/test/test_multiline_midashi_tag.rb +0 -55
- data/test/test_multiline_style_tag.rb +0 -25
- data/test/test_multiline_yokogumi_tag.rb +0 -25
- data/test/test_okurigana_tag.rb +0 -24
- data/test/test_ruby_parse.rb +0 -130
- data/test/test_ruby_tag.rb +0 -24
- data/test/test_tag_parser.rb +0 -80
@@ -1,16 +1,18 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'ruby_buffer'
|
4
4
|
|
5
|
+
class Aozora2Html
|
5
6
|
# accent特殊文字を生かすための再帰呼び出し
|
6
7
|
class AccentParser < Aozora2Html
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
raise ArgumentError, "tag_parser must supply Jstream as input"
|
8
|
+
def initialize(input, endchar, chuuki, image, gaiji_dir:) # rubocop:disable Lint/MissingSuper
|
9
|
+
unless input.is_a?(Jstream)
|
10
|
+
raise ArgumentError, 'tag_parser must supply Jstream as input'
|
11
11
|
end
|
12
|
+
|
12
13
|
@stream = input
|
13
|
-
@
|
14
|
+
@gaiji_dir = gaiji_dir
|
15
|
+
@buffer = Aozora2Html::TextBuffer.new
|
14
16
|
@ruby_buf = Aozora2Html::RubyBuffer.new
|
15
17
|
@chuuki_table = chuuki
|
16
18
|
@images = image # globalな環境を記録するアイテムは共有する必要あり
|
@@ -19,71 +21,77 @@ class Aozora2Html
|
|
19
21
|
@encount_accent = nil
|
20
22
|
end
|
21
23
|
|
22
|
-
|
24
|
+
# 出力は配列で返す
|
25
|
+
def general_output
|
23
26
|
@ruby_buf.dump_into(@buffer)
|
24
|
-
|
25
|
-
@buffer.unshift(
|
27
|
+
unless @encount_accent
|
28
|
+
@buffer.unshift(ACCENT_BEGIN)
|
26
29
|
end
|
27
|
-
if @closed
|
28
|
-
@buffer.push(
|
29
|
-
elsif
|
30
|
+
if @closed && !@encount_accent
|
31
|
+
@buffer.push(ACCENT_END)
|
32
|
+
elsif !@closed
|
30
33
|
@buffer.push("<br />\r\n")
|
31
34
|
end
|
32
35
|
@buffer
|
33
36
|
end
|
34
37
|
|
35
38
|
def parse
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
loop do
|
40
|
+
first = read_char
|
41
|
+
|
42
|
+
found = Aozora2Html::ACCENT_TABLE[first]
|
43
|
+
if found
|
44
|
+
found2 = found[@stream.peek_char(0)]
|
45
|
+
if found2
|
46
|
+
if found2.is_a?(Hash)
|
47
|
+
found3 = found2[@stream.peek_char(1)]
|
48
|
+
if found3
|
49
|
+
first = Aozora2Html::Tag::Accent.new(self, *found3, gaiji_dir: @gaiji_dir)
|
50
|
+
@encount_accent = true
|
51
|
+
@chuuki_table[:accent] = true
|
52
|
+
read_char
|
53
|
+
read_char
|
54
|
+
end
|
55
|
+
elsif found2
|
56
|
+
first = Aozora2Html::Tag::Accent.new(self, *found2, gaiji_dir: @gaiji_dir)
|
42
57
|
@encount_accent = true
|
43
|
-
@chuuki_table[:accent] = true
|
44
|
-
read_char
|
45
58
|
read_char
|
59
|
+
@chuuki_table[:accent] = true
|
46
60
|
end
|
47
|
-
elsif found2
|
48
|
-
first = Aozora2Html::Tag::Accent.new(self, *found2)
|
49
|
-
@encount_accent = true
|
50
|
-
read_char
|
51
|
-
@chuuki_table[:accent] = true
|
52
61
|
end
|
53
62
|
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
|
64
|
+
case first
|
65
|
+
when Aozora2Html::GAIJI_MARK
|
66
|
+
first = dispatch_gaiji
|
67
|
+
when COMMAND_BEGIN
|
68
|
+
first = dispatch_aozora_command
|
69
|
+
when Aozora2Html::KU
|
70
|
+
assign_kunoji
|
71
|
+
when RUBY_BEGIN_MARK
|
72
|
+
first = apply_ruby
|
73
|
+
end
|
74
|
+
if first == "\r\n"
|
75
|
+
if @encount_accent
|
76
|
+
puts I18n.t(:warn_invalid_accent_brancket, line_number)
|
77
|
+
end
|
78
|
+
throw :terminate
|
79
|
+
elsif first == ACCENT_END
|
80
|
+
@closed = true
|
81
|
+
throw :terminate
|
82
|
+
elsif first == RUBY_PREFIX
|
83
|
+
@ruby_buf.dump_into(@buffer)
|
84
|
+
@ruby_buf.protected = true
|
85
|
+
elsif (first != '') && !first.nil?
|
86
|
+
Utils.illegal_char_check(first, line_number)
|
87
|
+
push_chars(escape_special_chars(first))
|
68
88
|
end
|
69
|
-
throw :terminate
|
70
|
-
elsif first == "〕".encode("shift_jis")
|
71
|
-
@closed = true
|
72
|
-
throw :terminate
|
73
|
-
elsif first == RUBY_PREFIX
|
74
|
-
@ruby_buf.dump_into(@buffer)
|
75
|
-
@ruby_buf.protected = true
|
76
|
-
elsif first != "" and first != nil
|
77
|
-
illegal_char_check(first, line_number)
|
78
|
-
push_chars(first)
|
79
89
|
end
|
80
90
|
end
|
81
91
|
|
82
92
|
def process
|
83
93
|
catch(:terminate) do
|
84
|
-
|
85
|
-
parse
|
86
|
-
end
|
94
|
+
parse
|
87
95
|
end
|
88
96
|
general_output
|
89
97
|
end
|
data/lib/aozora2html/error.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'i18n'
|
2
4
|
|
3
|
-
# 例外class
|
4
5
|
class Aozora2Html
|
6
|
+
# 例外class
|
5
7
|
class Error < StandardError
|
6
|
-
|
7
8
|
def initialize(msg)
|
9
|
+
super
|
8
10
|
@message = msg
|
9
11
|
end
|
10
12
|
|
@@ -13,4 +15,3 @@ class Aozora2Html
|
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
data/lib/aozora2html/header.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
class Aozora2Html
|
4
|
+
# ヘッダ生成用
|
3
5
|
class Header
|
4
|
-
def initialize()
|
6
|
+
def initialize(css_files:)
|
5
7
|
@header = []
|
8
|
+
@css_files = css_files
|
6
9
|
end
|
7
10
|
|
8
11
|
def push(line)
|
@@ -14,17 +17,17 @@ class Aozora2Html
|
|
14
17
|
if found
|
15
18
|
"<h2 class=\"#{true_name or attr}\">#{found}</h2>\r\n"
|
16
19
|
else
|
17
|
-
|
20
|
+
''
|
18
21
|
end
|
19
22
|
end
|
20
23
|
|
21
24
|
def header_element_type(string)
|
22
25
|
original = true
|
23
26
|
string.each_char do |ch|
|
24
|
-
code = ch.
|
25
|
-
if (
|
26
|
-
|
27
|
-
|
27
|
+
code = ch.unpack1('H*')
|
28
|
+
if ((code >= '00') && (code <= '7f')) || # 1byte
|
29
|
+
((code >= '8140') && (code <= '8258')) || # 1-1, 3-25
|
30
|
+
((code >= '839f') && (code <= '8491')) # 6-1, 7-81
|
28
31
|
# continue
|
29
32
|
else
|
30
33
|
original = false
|
@@ -61,13 +64,13 @@ class Aozora2Html
|
|
61
64
|
def build_title(header_info)
|
62
65
|
buf = [:author, :translator, :editor, :henyaku,
|
63
66
|
:title, :original_title,
|
64
|
-
:subtitle, :original_subtitle].
|
65
|
-
buf_str = buf.join(
|
67
|
+
:subtitle, :original_subtitle].filter_map { |item| header_info[item] }
|
68
|
+
buf_str = buf.join(' ')
|
66
69
|
"<title>#{buf_str}</title>"
|
67
70
|
end
|
68
71
|
|
69
72
|
def build_header_info
|
70
|
-
header_info = {:
|
73
|
+
header_info = { title: @header[0] }
|
71
74
|
case @header.length
|
72
75
|
when 2
|
73
76
|
process_person(@header[1], header_info)
|
@@ -96,7 +99,7 @@ class Aozora2Html
|
|
96
99
|
header_info[:subtitle] = @header[2]
|
97
100
|
header_info[:author] = @header[3]
|
98
101
|
if process_person(@header[4], header_info) == :author
|
99
|
-
raise Aozora2Html::Error,
|
102
|
+
raise Aozora2Html::Error, 'parser encounted author twice'
|
100
103
|
end
|
101
104
|
when 6
|
102
105
|
header_info[:original_title] = @header[1]
|
@@ -104,14 +107,14 @@ class Aozora2Html
|
|
104
107
|
header_info[:original_subtitle] = @header[3]
|
105
108
|
header_info[:author] = @header[4]
|
106
109
|
if process_person(@header[5], header_info) == :author
|
107
|
-
raise Aozora2Html::Error,
|
110
|
+
raise Aozora2Html::Error, 'parser encounted author twice'
|
108
111
|
end
|
109
112
|
end
|
110
113
|
header_info
|
111
114
|
end
|
112
115
|
|
113
116
|
def to_html
|
114
|
-
header_info = build_header_info
|
117
|
+
header_info = build_header_info
|
115
118
|
|
116
119
|
# <title> 行を構築
|
117
120
|
html_title = build_title(header_info)
|
@@ -119,8 +122,8 @@ class Aozora2Html
|
|
119
122
|
# 出力
|
120
123
|
out_buf = []
|
121
124
|
out_buf.push("<?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")
|
122
|
-
|
123
|
-
out_buf.push("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"
|
125
|
+
@css_files.each do |css|
|
126
|
+
out_buf.push("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"#{css}\" />\r\n")
|
124
127
|
end
|
125
128
|
out_buf.push("\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=\"#{AOZORABUNKO}\" />\r\n</head>\r\n<body>\r\n<div class=\"metadata\">\r\n")
|
126
129
|
out_buf.push("<h1 class=\"title\">#{header_info[:title]}</h1>\r\n" +
|
@@ -130,10 +133,9 @@ class Aozora2Html
|
|
130
133
|
out_header_info(header_info, :author) +
|
131
134
|
out_header_info(header_info, :editor) +
|
132
135
|
out_header_info(header_info, :translator) +
|
133
|
-
out_header_info(header_info, :henyaku,
|
136
|
+
out_header_info(header_info, :henyaku, 'editor-translator'))
|
134
137
|
out_buf.push("<br />\r\n<br />\r\n</div>\r\n<div id=\"contents\" style=\"display:none\"></div><div class=\"main_text\">")
|
135
|
-
out_buf.join
|
138
|
+
out_buf.join
|
136
139
|
end
|
137
|
-
|
138
140
|
end
|
139
141
|
end
|
data/lib/aozora2html/i18n.rb
CHANGED
@@ -1,28 +1,48 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'string_refinements'
|
4
|
+
|
2
5
|
class Aozora2Html
|
6
|
+
# Internationalization(I18n) class
|
7
|
+
#
|
8
|
+
# コード内に日本語メッセージが氾濫しないようにするためのクラス
|
3
9
|
class I18n
|
10
|
+
@use_utf8 = nil
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_accessor :use_utf8
|
14
|
+
end
|
15
|
+
|
4
16
|
MSG = {
|
5
|
-
:
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
|
17
|
+
tag_syntax_error: '注記を重ねる際の原則、「狭い範囲を先に、広い範囲を後に」が守られていません。リンク先の指針を参考に、書き方をあらためてください',
|
18
|
+
undefined_header: '未定義な見出しです',
|
19
|
+
use_crlf: '改行コードを、「CR+LF」にあらためてください',
|
20
|
+
error_stop: "エラー(%d行目):%s. \r\n処理を停止します",
|
21
|
+
invalid_font_size: '文字サイズの指定が不正です',
|
22
|
+
unsupported_ruby: 'サポートされていない複雑なルビ付けです',
|
23
|
+
warn_onebyte: '警告(%d行目):1バイトの「%s」が使われています',
|
24
|
+
warn_chuki: '警告(%d行目):注記記号の誤用の可能性がある、「%s」が使われています',
|
25
|
+
warn_jis_gaiji: '警告(%d行目):JIS外字「%s」が使われています',
|
26
|
+
dont_crlf_in_style: '%s中に改行されました。改行をまたぐ要素にはブロック表記を用いてください',
|
27
|
+
terminate_in_style: '%s中に本文が終了しました',
|
28
|
+
invalid_closing: '%sを閉じようとしましたが、%s中ではありません',
|
29
|
+
invalid_nesting: '%sを終了しようとしましたが、%s中です',
|
30
|
+
dont_use_double_ruby: '同じ箇所に2つのルビはつけられません',
|
31
|
+
dont_allow_triple_ruby: '1つの単語に3つのルビはつけられません',
|
32
|
+
warn_invalid_accent_brancket: '警告(%d行目):アクセント分解の亀甲括弧の始めと終わりが、行中で揃っていません',
|
33
|
+
warn_unexpected_terminator: '警告(%d行目):予期せぬファイル終端',
|
34
|
+
warn_undefined_command: '警告(%d行目):「%s」は未対応のコマンドのため無視します'
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
using StringRefinements
|
23
38
|
|
24
39
|
def self.t(msg, *args)
|
25
|
-
|
40
|
+
if Aozora2Html::I18n.use_utf8
|
41
|
+
args_sjis = args.map { |arg| arg.is_a?(String) ? arg.to_sjis : arg }
|
42
|
+
(MSG[msg].to_sjis % args_sjis).force_encoding('cp932').to_utf8
|
43
|
+
else
|
44
|
+
MSG[msg].to_sjis % args
|
45
|
+
end
|
26
46
|
end
|
27
47
|
end
|
28
48
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Aozora2Html
|
4
|
+
# 見出しIDカウンター
|
5
|
+
#
|
6
|
+
# 主にmidashi_idを管理する
|
7
|
+
class MidashiCounter
|
8
|
+
def initialize(current_id)
|
9
|
+
@midashi_id = current_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_id(size)
|
13
|
+
if size.is_a?(Integer)
|
14
|
+
@midashi_id += size
|
15
|
+
return @midashi_id
|
16
|
+
end
|
17
|
+
|
18
|
+
case size
|
19
|
+
when /#{Aozora2Html::SIZE_SMALL}/o
|
20
|
+
inc = 1
|
21
|
+
when /#{Aozora2Html::SIZE_MIDDLE}/o
|
22
|
+
inc = 10
|
23
|
+
when /#{Aozora2Html::SIZE_LARGE}/o
|
24
|
+
inc = 100
|
25
|
+
else
|
26
|
+
raise Aozora2Html::Error, I18n.t(:undefined_header)
|
27
|
+
end
|
28
|
+
|
29
|
+
@midashi_id += inc
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,24 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'string_refinements'
|
4
|
+
|
1
5
|
class Aozora2Html
|
6
|
+
# ルビ文字列解析用バッファ
|
2
7
|
class RubyBuffer
|
3
|
-
|
4
8
|
# `|`が来た時に真にする。ルビの親文字のガード用。
|
5
9
|
attr_accessor :protected
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def initialize(item=nil)
|
11
|
-
clear(item)
|
11
|
+
def initialize
|
12
|
+
clear
|
12
13
|
end
|
13
14
|
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
if item
|
18
|
-
@ruby_buf = [item]
|
19
|
-
else
|
20
|
-
@ruby_buf = [""]
|
21
|
-
end
|
15
|
+
# バッファの初期化。`""`の1要素のバッファにする。
|
16
|
+
def clear
|
17
|
+
@ruby_buf = [+'']
|
22
18
|
@protected = nil
|
23
19
|
@char_type = nil
|
24
20
|
end
|
@@ -35,30 +31,46 @@ class Aozora2Html
|
|
35
31
|
@ruby_buf
|
36
32
|
end
|
37
33
|
|
38
|
-
def
|
39
|
-
|
34
|
+
def create_ruby(parser, ruby)
|
35
|
+
ans = +''
|
36
|
+
notes = []
|
37
|
+
|
38
|
+
@ruby_buf.each do |token|
|
39
|
+
if token.is_a?(Aozora2Html::Tag::UnEmbedGaiji)
|
40
|
+
ans.concat(GAIJI_MARK)
|
41
|
+
token.escape!
|
42
|
+
notes.push(token)
|
43
|
+
else
|
44
|
+
ans.concat(token.to_s)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
notes.unshift(Aozora2Html::Tag::Ruby.new(parser, ans, ruby))
|
49
|
+
clear
|
50
|
+
|
51
|
+
notes
|
40
52
|
end
|
41
53
|
|
42
54
|
def last
|
43
55
|
@ruby_buf.last
|
44
56
|
end
|
45
57
|
|
58
|
+
# バッファ末尾にitemを追加する
|
59
|
+
#
|
60
|
+
# itemとバッファの最後尾がどちらもStringであれば連結したStringにし、
|
61
|
+
# そうでなければバッファの末尾に新しい要素として追加する
|
46
62
|
def push(item)
|
47
|
-
|
63
|
+
if last.is_a?(String) && item.is_a?(String)
|
64
|
+
@ruby_buf.last.concat(item)
|
65
|
+
else
|
66
|
+
@ruby_buf.push(item)
|
67
|
+
end
|
48
68
|
end
|
49
69
|
|
50
70
|
def length
|
51
71
|
@ruby_buf.length
|
52
72
|
end
|
53
73
|
|
54
|
-
def last_concat(item)
|
55
|
-
@ruby_buf.last.concat(item)
|
56
|
-
end
|
57
|
-
|
58
|
-
def last_is_string?
|
59
|
-
@ruby_buf.last.is_a?(String)
|
60
|
-
end
|
61
|
-
|
62
74
|
# buffer management
|
63
75
|
def dump_into(buffer)
|
64
76
|
if @protected
|
@@ -66,9 +78,9 @@ class Aozora2Html
|
|
66
78
|
@protected = nil
|
67
79
|
end
|
68
80
|
top = @ruby_buf[0]
|
69
|
-
if top.is_a?(String)
|
81
|
+
if top.is_a?(String) && buffer.last.is_a?(String)
|
70
82
|
buffer.last.concat(top)
|
71
|
-
buffer.concat(@ruby_buf[1
|
83
|
+
buffer.concat(@ruby_buf[1, @ruby_buf.length])
|
72
84
|
else
|
73
85
|
buffer.concat(@ruby_buf)
|
74
86
|
end
|
@@ -76,6 +88,29 @@ class Aozora2Html
|
|
76
88
|
buffer
|
77
89
|
end
|
78
90
|
|
91
|
+
def push_char(char, buffer)
|
92
|
+
ctype = char_type(char)
|
93
|
+
if (ctype == :hankaku_terminate) && (@char_type == :hankaku)
|
94
|
+
push(char)
|
95
|
+
@char_type = :else
|
96
|
+
elsif @protected || ((ctype != :else) && (ctype == @char_type))
|
97
|
+
push(char)
|
98
|
+
else
|
99
|
+
dump_into(buffer)
|
100
|
+
push(char)
|
101
|
+
@char_type = ctype
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
using StringRefinements
|
108
|
+
|
109
|
+
def char_type(char)
|
110
|
+
## `String#char_type`も定義されているのに注意
|
111
|
+
char.char_type
|
112
|
+
rescue StandardError
|
113
|
+
:else
|
114
|
+
end
|
79
115
|
end
|
80
116
|
end
|
81
|
-
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Aozora2Html
|
4
|
+
# String extension
|
5
|
+
module StringRefinements
|
6
|
+
refine String do
|
7
|
+
# used in RubyBuffer#char_type
|
8
|
+
def char_type
|
9
|
+
case self
|
10
|
+
when Aozora2Html::REGEX_HIRAGANA
|
11
|
+
:hiragana
|
12
|
+
when Aozora2Html::REGEX_KATAKANA
|
13
|
+
:katakana
|
14
|
+
when Aozora2Html::REGEX_ZENKAKU
|
15
|
+
:zenkaku
|
16
|
+
when Aozora2Html::REGEX_HANKAKU
|
17
|
+
:hankaku
|
18
|
+
when Aozora2Html::REGEX_KANJI
|
19
|
+
:kanji
|
20
|
+
when /[.;"?!)]/
|
21
|
+
:hankaku_terminate
|
22
|
+
else
|
23
|
+
:else
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_sjis
|
28
|
+
encode(Encoding::Shift_JIS)
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_utf8
|
32
|
+
encode(Encoding::UTF_8)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,21 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Aozora2Html
|
2
4
|
class Tag
|
3
|
-
|
4
|
-
|
5
|
+
# 欧文アクセント文字用
|
6
|
+
class Accent < Aozora2Html::Tag::Inline
|
5
7
|
@use_jisx0213 = nil
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.use_jisx0213
|
12
|
-
@use_jisx0213
|
9
|
+
class << self
|
10
|
+
attr_accessor :use_jisx0213
|
13
11
|
end
|
14
12
|
|
15
|
-
|
16
|
-
def initialize(parser, code, name)
|
13
|
+
def initialize(parser, code, name, gaiji_dir:)
|
17
14
|
@code = code
|
18
15
|
@name = name
|
16
|
+
@gaiji_dir = gaiji_dir
|
19
17
|
super
|
20
18
|
end
|
21
19
|
|
@@ -29,9 +27,9 @@ class Aozora2Html
|
|
29
27
|
|
30
28
|
def to_s
|
31
29
|
if Aozora2Html::Tag::Accent.use_jisx0213
|
32
|
-
jisx0213_to_unicode(@code.sub(%r
|
30
|
+
jisx0213_to_unicode(@code.sub(%r{.*/}, '').to_sym)
|
33
31
|
else
|
34
|
-
"<img src=\"#{
|
32
|
+
"<img src=\"#{@gaiji_dir}#{@code}.png\" alt=\"" + GAIJI_MARK + "(#{@name})\" class=\"gaiji\" />"
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
@@ -1,19 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Aozora2Html
|
2
4
|
class Tag
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
# ブロックタグ用class
|
6
|
+
#
|
7
|
+
# 各Tagクラスはこれを継承する
|
8
|
+
class Block < Aozora2Html::Tag
|
9
|
+
def initialize(parser, *_args)
|
10
|
+
super()
|
11
|
+
|
12
|
+
syntax_error unless parser.block_allowed_context?
|
10
13
|
end
|
11
14
|
|
12
15
|
# 必要に基づきmethod overrideする
|
13
16
|
def close_tag
|
14
|
-
|
17
|
+
'</div>'
|
15
18
|
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
end
|
19
|
-
|
@@ -1,14 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Aozora2Html
|
2
4
|
class Tag
|
5
|
+
# 地付き記法
|
6
|
+
#
|
7
|
+
# 直接使わない。実際に使うのはサブクラス
|
3
8
|
class Chitsuki < Aozora2Html::Tag::Indent
|
4
|
-
|
5
9
|
def initialize(parser, length)
|
6
10
|
@length = length
|
7
11
|
super
|
8
12
|
end
|
9
13
|
|
10
14
|
def to_s
|
11
|
-
|
15
|
+
"<div class=\"chitsuki_#{@length}\" style=\"text-align:right; margin-right: #{@length}em\">"
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|