module DR class Formatter module Helpers def localize(msg, lang: :en, **_opts) case msg when Hash Array(lang).each do |l| if msg.key?(l) yield(msg[l]) if block_given? return msg[l] end end else msg end end def wrap(content, pre:nil, post:nil) return content if content.nil? or content.empty? pre.to_s+content.to_s+post.to_s end def join(*args, pre: "", post: "", pre_item: "", post_item: "", join: :auto, **_opts) args=Array(args) list=args.compact.map {|i| wrap(i, pre: pre_item, post: post_item)}.delete_if {|i| i.empty?} r=list.shift list.each do |s| if join==:auto if r[-1]=="\n" or s[1]=="\n" r+=s else r+=" "+s end else r+=join+s end end r=pre+r+post unless r.nil? or r.empty? r end end extend Helpers attr_accessor :opts, :meta def initialize(meta={}, **opts) @meta=meta @opts=opts end def localize(msg, **opts) self.class.localize(msg, **@opts.merge(opts)) end def join(*args, **opts) opts=@opts.merge(opts) args=Array(args).map {|i| try_expand_symbol(i,**opts)} self.class.localize(*args, **opts) end private def metainfo_from_symbol(sym, meta: @meta, **opts) return sym if opts[:meta_symbol]==:never content=case meta when Hash warn "#{sym} not found in #{meta}" unless meta.key?(sym) meta[sym] when Proc meta.call(sym, **opts) else sym end if block_given? yield content, **opts else content end end private def get_symbol(sym) case sym when Symbol return sym when String return sym[1...sym.length].to_sym if sym[0] == ':' end nil end private def try_get_symbol(sym,**opts) if (key=get_symbol(sym)) expand_symbol(key,**opts) else sym end end def expand(msg, **opts) recursive=opts[:recursive] #if recursive is :first, then we only expand once ore if recursive.is_a?(Integer) opts[:recursive]=recursive-1 recursive=false if recursive <= 0 end case msg when Hash Array(opts[:merge]).each do |key| if msg.key?(key) msg=msg.merge(msg[key]) msg.delete(key) end end # we localize after merging potential out types localize(msg, **opts) do |lmsg| # localization do not count as a recursive step return expand(lmsg, **opts) end if recursive msg_exp={} msg.each do |k,v| msg_exp[k]=expand(v,**opts) end #expand may have introduced nil values clean_nil=opts.fetch(:clean_nil,true) msg_exp.delete_if {|_k,v| v==nil} if clean_nil msg_exp else msg end when Symbol opts[:symbol]||=:never msg=metainfo_from_symbol(msg,**opts) recursive ? expand(msg, **opts) : msg when Array msg=msg.map {|i| expand(i,**opts)} if recursive opts[:join] ? join(msg, **opts) : msg when String (nmsg=try_get_symbol(msg,**opts)) and return nmsg if block_given? yield(msg, **opts) else msg end when nil nil else if block_given? yield(msg, **opts) else #expand(msg.to_s,**opts) msg end end end end end