1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
# frozen_string_literal: false
##
# An i18n supported text.
#
# This object provides the following two features:
#
# * Extracts translation messages from wrapped raw text.
# * Translates wrapped raw text in specified locale.
#
# Wrapped raw text is one of String, RDoc::Comment or Array of them.
class RDoc::I18n::Text
##
# Creates a new i18n supported text for +raw+ text.
def initialize(raw)
@raw = raw
end
##
# Extracts translation target messages and yields each message.
#
# Each yielded message is a Hash. It consists of the followings:
#
# :type :: :paragraph
# :paragraph :: String (The translation target message itself.)
# :line_no :: Integer (The line number of the :paragraph is started.)
#
# The above content may be added in the future.
def extract_messages
parse do |part|
case part[:type]
when :empty_line
# ignore
when :paragraph
yield(part)
end
end
end
# Translates raw text into +locale+.
def translate(locale)
translated_text = ''
parse do |part|
case part[:type]
when :paragraph
translated_text << locale.translate(part[:paragraph])
when :empty_line
translated_text << part[:line]
else
raise "should not reach here: unexpected type: #{type}"
end
end
translated_text
end
private
def parse(&block)
paragraph = ''
paragraph_start_line = 0
line_no = 0
each_line(@raw) do |line|
line_no += 1
case line
when /\A\s*\z/
if paragraph.empty?
emit_empty_line_event(line, line_no, &block)
else
paragraph << line
emit_paragraph_event(paragraph, paragraph_start_line, line_no,
&block)
paragraph = ''
end
else
paragraph_start_line = line_no if paragraph.empty?
paragraph << line
end
end
unless paragraph.empty?
emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
end
end
def each_line(raw, &block)
case raw
when RDoc::Comment
raw.text.each_line(&block)
when Array
raw.each do |comment, location|
each_line(comment, &block)
end
else
raw.each_line(&block)
end
end
def emit_empty_line_event(line, line_no)
part = {
:type => :empty_line,
:line => line,
:line_no => line_no,
}
yield(part)
end
def emit_paragraph_event(paragraph, paragraph_start_line, line_no, &block)
paragraph_part = {
:type => :paragraph,
:line_no => paragraph_start_line,
}
match_data = /(\s*)\z/.match(paragraph)
if match_data
paragraph_part[:paragraph] = match_data.pre_match
yield(paragraph_part)
emit_empty_line_event(match_data[1], line_no, &block)
else
paragraph_part[:paragraph] = paragraph
yield(paragraph_part)
end
end
end
|