lib/csl/locale.rb in csl-1.0.2 vs lib/csl/locale.rb in csl-1.1.0

- old
+ new

@@ -18,14 +18,13 @@ @tag_pattern = /^[a-z]{2}(-[A-Z]{2})?|-[A-Z]{2}$/ # Default languages/regions. # Auto-detection is based on these lists. @regions = Hash[*%w{ - af ZA ar AR bg BG ca AD cs CZ da DK de DE el GR en US es ES et EE fa IR - fr FR he IL hu HU is IS it IT ja JP km KH ko KR mn MN nb NO nl NL nn NO - pl PL pt PT ro RO ru RU sk SK sl SI sr RS sv SE th TH tr TR uk UA vi VN - zh CN + af ZA bg BG ca AD cs CZ da DK de DE el GR en US es ES et EE fa IR fr FR + he IL hu HU is IS it IT ja JP km KH ko KR mn MN nb NO nl NL nn NO pl PL + pt PT ro RO ru RU sk SK sl SI sr RS sv SE th TH tr TR uk UA vi VN zh CN }.map(&:to_sym)].freeze @languages = @regions.invert.merge(Hash[*%w{ AT de BR pt CA en CH de GB en TW zh }.map(&:to_sym)]).freeze @@ -35,13 +34,14 @@ include Loader attr_accessor :default attr_reader :languages, :regions - def load(input = Locale.default) - input = normalize input if input.to_s =~ tag_pattern - super + def load(input = nil) + input ||= Locale.default + input = normalize input if input.to_s =~ @tag_pattern + super(input) end # Normalizes an IETF tag; adds a language's default region or a # region's default language. # @@ -55,23 +55,19 @@ # @return [String] the normalized IETF tag def normalize(tag) tag = tag.to_s.strip raise ArgumentError, "not a valid IETF tag: #{tag.inspect}" unless - tag =~ tag_pattern + tag =~ @tag_pattern language, region = tag.split(/-/) return [language, regions[language.to_sym]].compact.join('-') if region.nil? return [languages[region.to_sym], region].join('-') if language.empty? tag end - - private - - attr_reader :tag_pattern end attr_defaults :version => Schema.major_version, :xmlns => Schema.namespace @@ -132,16 +128,11 @@ end yield self if block_given? end - def initialize_copy(other) - super - @language, @region = other.language, other.region - end - def added_to(node) raise ValidationError, "not allowed to add locale to #{node.nodename}" unless node.nodename == 'style' end @@ -198,15 +189,29 @@ self end # @return [String, nil] the term's translation def translate(name, options = {}) + return unless has_terms? + term = terms.lookup name, options term && term.to_s(options) end alias t translate + # Stores a translation in the locale's term registry. + # @see Terms#store + def store(*arguments) + unless has_terms? + self << CSL::Locale::Terms.new + end + + terms.store(*arguments) + self + end + alias learn store + # Ordinalizes the passed-in number using either the ordinal or # long-ordinal forms defined by the locale. If a long-ordinal form is # requested but not available, the regular ordinal will be returned # instead. # @@ -248,10 +253,76 @@ return ordinal.to_s(options) if ordinal.long_ordinal? [number, ordinal.to_s(options)].join end + # @return [Boolean] true when the option limit-day-ordinals-to-day-1 is true + def limit_day_ordinals? + return false unless has_options? && options.attribute?(:'limit-day-ordinals-to-day-1') + !!(options[:'limit-day-ordinals-to-day-1'].to_s =~ /^true$/i) + end + + def limit_day_ordinals! + unless has_options? + children[:'style-options'] = StyleOptions.new + end + + options[:'limit-day-ordinals-to-day-1'] = true + end + + # @return [Boolean] true when the option punctuation-in-quote is true + def punctuation_in_quote? + return false unless has_options? && options.attribute?(:'punctuation-in-quote') + !!(options[:'punctuation-in-quote'].to_s =~ /^true$/i) + end + alias punctuation_in_quotes? punctuation_in_quote? + + def punctuation_in_quote! + unless has_options? + children[:'style-options'] = StyleOptions.new + end + + options[:'punctuation-in-quote'] = true + end + alias punctuation_in_quotes! punctuation_in_quote! + + # Puts localized quotes around the passed-in string. + # @return [String] the quoted string + def quote(string, escape = false) + oq, cq = t('open-quote'), t('close-quote') + + return string if oq.nil? || cq.nil? || (oq.empty? && cq.empty?) + + if escape + oq = CSL.encode_xml_text(oq) + cq = CSL.encode_xml_text(cq) + end + + string = replace_with_inner_quotes(string, oq, cq, escape) + + if punctuation_in_quotes? + "#{oq}#{string}#{cq}" + else + string, punctuation = string.split(/([\.,])$/, 2) + + "#{oq}#{string}#{cq}#{punctuation}" + end + end + + def replace_with_inner_quotes(string, open, close, escape = false) + oq, cq = t('open-inner-quote'), t('close-inner-quote') + + return string if oq.nil? || cq.nil? || (oq.empty? && cq.empty?) + + if escape + oq = CSL.encode_xml_text(oq) + cq = CSL.encode_xml_text(cq) + end + + string.gsub(/(#{open}|"\b)/, oq).gsub(/(#{close}|\b")/, cq) + end + # @example # locale.each_term { |term| block } #-> locale # locale.each_term #-> enumerator # # Calls block once for each term defined by the locale. If no block is @@ -362,13 +433,15 @@ "#<#{self.class.name} #{to_s}>" end private + alias original_locale_attribute_assignments attribute_assignments + def attribute_assignments if root? - super.push('xml:lang="%s"' % to_s) + original_locale_attribute_assignments else 'xml:lang="%s"' % to_s end end @@ -408,6 +481,6 @@ self end end -end \ No newline at end of file +end