Class: IsoDoc::I18n

Inherits:
Object
  • Object
show all
Defined in:
lib/isodoc/i18n.rb,
lib/isodoc/version.rb

Constant Summary collapse

ZH_CHAR =
"\\p{Han}|\\p{In CJK Symbols And Punctuation}|"\
"\\p{In Halfwidth And Fullwidth Forms}".freeze
VERSION =
"1.0.3".freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(lang, script, i18nyaml = nil) ⇒ I18n

Returns a new instance of I18n.



56
57
58
59
60
61
62
63
64
65
66
# File 'lib/isodoc/i18n.rb', line 56

def initialize(lang, script, i18nyaml = nil)
  @lang = lang
  @script = script
  y = load_yaml(lang, script, i18nyaml)
  @labels = y
  @labels["language"] = @lang
  @labels["script"] = @script
  @labels.each do |k, _v|
    self.class.send(:define_method, k.downcase) { get[k] }
  end
end

Class Method Details

.l10n(text, lang = @lang, script = @script) ⇒ Object



68
69
70
# File 'lib/isodoc/i18n.rb', line 68

def self.l10n(text, lang = @lang, script = @script)
  l10n(text, lang, script)
end

Instance Method Details

#bidiwrap(text, lang, script) ⇒ Object



81
82
83
84
85
86
87
88
89
# File 'lib/isodoc/i18n.rb', line 81

def bidiwrap(text, lang, script)
  my_script, my_rtl, outer_rtl = bidiwrap_vars(lang, script)
  if my_rtl && !outer_rtl
    mark = %w(Arab Aran).include?(my_script) ? "؜" : "‏"
    "#{mark}#{text}#{mark}"
  elsif !my_rtl && outer_rtl then "‎#{text}‎"
  else text
  end
end

#bidiwrap_vars(lang, script) ⇒ Object



91
92
93
94
95
96
97
# File 'lib/isodoc/i18n.rb', line 91

def bidiwrap_vars(lang, script)
  my_script = script || Metanorma::Utils.default_script(lang)
  [my_script,
   Metanorma::Utils.rtl_script?(my_script),
   Metanorma::Utils.rtl_script?(@script || Metanorma::Utils
     .default_script(@lang))]
end

#boolean_conj(list, conn) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/isodoc/i18n.rb', line 126

def boolean_conj(list, conn)
  case list.size
  when 0 then ""
  when 1 then list.first
  when 2 then @labels["binary_#{conn}"].sub(/%1/, list[0])
    .sub(/%2/, list[1])
  else
    @labels["multiple_#{conn}"]
      .sub(/%1/, l10n(list[0..-2].join(", "), @lang, @script))
      .sub(/%2/, list[-1])
  end
end

#cleanup_entities(text, is_xml: true) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/isodoc/i18n.rb', line 139

def cleanup_entities(text, is_xml: true)
  c = HTMLEntities.new
  if is_xml
    text.split(/([<>])/).each_slice(4).map do |a|
      a[0] = c.encode(c.decode(a[0]), :hexadecimal)
      a
    end.join
  else
    c.encode(c.decode(text), :hexadecimal)
  end
end

#getObject



48
49
50
# File 'lib/isodoc/i18n.rb', line 48

def get
  @labels
end

#inflect_ordinal(num, term, ord_class) ⇒ Object

ord class is either SpelloutRules or OrdinalRules



152
153
154
155
156
157
158
159
# File 'lib/isodoc/i18n.rb', line 152

def inflect_ordinal(num, term, ord_class)
  if @labels["ordinal_keys"].nil? || @labels["ordinal_keys"].empty?
    num.localize(tw_cldr_lang).to_rbnf_s(ord_class, @labels[ord_class])
  else
    num.localize(tw_cldr_lang)
      .to_rbnf_s(ord_class, @labels[ord_class][ordinal_key(term)])
  end
end

#l10_zh1(text) ⇒ Object

note: we can’t differentiate comma from enumeration comma 、



113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/isodoc/i18n.rb', line 113

def l10_zh1(text)
  ["::", ",,", ".。", "))", "]】", "::", ";;", "??", "!!"].each do |m|
    text = text.gsub(/(?<=#{ZH_CHAR})#{Regexp.quote m[0]}/, m[1])
  end
  ["((", "[【"].each do |m|
    text = text.gsub(/#{Regexp.quote m[0]}(?=#{ZH_CHAR})/, m[1])
  end
  text.gsub(/(?<=#{ZH_CHAR}) (?=#{ZH_CHAR})/o, "")
    .gsub(/(?<=\d) (?=#{ZH_CHAR})/o, "")
    .gsub(/(?<=#{ZH_CHAR}) (?=\d)/o, "")
    .gsub(/(?<=#{ZH_CHAR}) (?=[A-Za-z](#{ZH_CHAR}|$))/o, "")
end

#l10n(text, lang = @lang, script = @script) ⇒ Object

TODO: move to localization file function localising spaces and punctuation. Not clear if period needs to be localised for zh



75
76
77
78
79
# File 'lib/isodoc/i18n.rb', line 75

def l10n(text, lang = @lang, script = @script)
  if lang == "zh" && script == "Hans" then l10n_zh(text)
  else bidiwrap(text, lang, script)
  end
end

#l10n_zh(text) ⇒ Object



99
100
101
102
103
104
105
106
107
# File 'lib/isodoc/i18n.rb', line 99

def l10n_zh(text)
  xml = Nokogiri::HTML::DocumentFragment.parse(text)
  xml.traverse do |n|
    next unless n.text?

    n.replace(cleanup_entities(l10_zh1(n.text), is_xml: false))
  end
  xml.to_xml.gsub(/<b>/, "").gsub("</b>", "").gsub(/<\?[^>]+>/, "")
end

#load_yaml(lang, script, i18nyaml = nil) ⇒ Object



8
9
10
11
12
13
# File 'lib/isodoc/i18n.rb', line 8

def load_yaml(lang, script, i18nyaml = nil)
  ret = load_yaml1(lang, script)
  return normalise_hash(ret.merge(YAML.load_file(i18nyaml))) if i18nyaml

  normalise_hash(ret)
end

#load_yaml1(lang, script) ⇒ Object



28
29
30
31
32
33
34
35
36
37
# File 'lib/isodoc/i18n.rb', line 28

def load_yaml1(lang, script)
  case lang
  when "zh"
    if script == "Hans" then load_yaml2("zh-Hans")
    else load_yaml2("en")
    end
  else
    load_yaml2(lang)
  end
end

#load_yaml2(lang) ⇒ Object

locally defined in calling class



40
41
42
43
44
45
46
# File 'lib/isodoc/i18n.rb', line 40

def load_yaml2(lang)
  YAML.load_file(File.join(File.dirname(__FILE__),
                           "../isodoc-yaml/i18n-#{lang}.yaml"))
rescue StandardError
  YAML.load_file(File.join(File.dirname(__FILE__),
                           "../isodoc-yaml/i18n-en.yaml"))
end

#normalise_hash(ret) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/isodoc/i18n.rb', line 15

def normalise_hash(ret)
  case ret
  when Hash
    ret.each do |k, v|
      ret[k] = normalise_hash(v)
    end
    ret
  when Array then ret.map { |n| normalise_hash(n) }
  when String then cleanup_entities(ret.unicode_normalize(:nfc))
  else ret
  end
end

#ordinal_key(term) ⇒ Object



161
162
163
164
165
166
167
168
169
# File 'lib/isodoc/i18n.rb', line 161

def ordinal_key(term)
  @labels["ordinal_keys"].each_with_object([]) do |k, m|
    m << case k
         when "gender" then term["gender"]
         when "number" then term["number"] || "sg"
         when "case" then term["case"] || "nom"
         end
  end.join(".")
end

#set(key, val) ⇒ Object



52
53
54
# File 'lib/isodoc/i18n.rb', line 52

def set(key, val)
  @labels[key] = val
end

#tw_cldr_langObject



171
172
173
174
175
176
# File 'lib/isodoc/i18n.rb', line 171

def tw_cldr_lang
  if @lang == "zh" && @script == "Hans" then :"zh-cn"
  elsif @lang == "zh" && @script == "Hant" then :"zh-tw"
  else @lang.to_sym
  end
end