Class: Relaton::Render::Template::General
- Inherits:
-
Object
- Object
- Relaton::Render::Template::General
- Defined in:
- lib/relaton/render/template/template.rb
Constant Summary collapse
- VARIABLE_DELIM =
denote start and end of variable, so that we can detect empty variables in postprocessing
"%%".freeze
- COMPONENT_DELIM =
denote citation components which get delimited by period conventionally
Regexp.quote("$$$").freeze
- LT_DELIM =
escape < >
"\u0019".freeze
- GT_DELIM =
"\u001a".freeze
- NON_SPACING_DELIM =
use tab internally for non-spacing delimiter
"\t".freeze
Instance Attribute Summary collapse
-
#template_raw ⇒ Object
readonly
Returns the value of attribute template_raw.
Instance Method Summary collapse
- #add_field_delim_to_template(template) ⇒ Object
- #create_liquid_environment ⇒ Object
-
#initialize(opt = {}) ⇒ General
constructor
A new instance of General.
-
#liquid_hash(hash) ⇒ Object
need non-breaking spaces in fields: “Updated:_nil” — we want the “Updated:” deleted, even if it’s multiple words, as in French Mise_à_jour.
- #parse_options(opt) ⇒ Object
- #punct_field?(name) ⇒ Boolean
- #remove_double_period(ret, delimrstripre) ⇒ Object
-
#render(hash, context) ⇒ Object
hash is what to render, which can be entire bib entry, or a subset of it like names context is information for selecting i18n, which is entire bib entry, potentially enhanced.
-
#strip_empty_variables(str) ⇒ Object
get rid of all empty variables, and any text around them, including component delimiters: [{}]$$$ => “” [{}] $$$ => “ $$$”.
- #template_clean(str) ⇒ Object
- #template_clean1(str) ⇒ Object
-
#template_components(str, delim) ⇒ Object
delim = punct.biblio-field-terminator must not be i18n’ised: .</esc>.
- #template_components_prep(delim) ⇒ Object
- #template_process(template) ⇒ Object
- #template_select(_hash) ⇒ Object
Constructor Details
#initialize(opt = {}) ⇒ General
Returns a new instance of General.
38 39 40 41 42 43 |
# File 'lib/relaton/render/template/template.rb', line 38 def initialize(opt = {}) @htmlentities = HTMLEntities.new @templatecache = CacheManager.instance @liquid_env = create_liquid_environment (opt) end |
Instance Attribute Details
#template_raw ⇒ Object (readonly)
Returns the value of attribute template_raw.
36 37 38 |
# File 'lib/relaton/render/template/template.rb', line 36 def template_raw @template_raw end |
Instance Method Details
#add_field_delim_to_template(template) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/relaton/render/template/template.rb', line 100 def add_field_delim_to_template(template) t = template.split(/(\{\{|\}\})/).each_slice(4).map do |a| unless !a[2] || punct_field?(a[2]&.strip) a[1] = "#{VARIABLE_DELIM}{{" a[3] = "}}#{VARIABLE_DELIM}" end a.join end.join.tr("\t", " ") t.gsub(/\}\}#{VARIABLE_DELIM}\|/o, "}}#{VARIABLE_DELIM}#{NON_SPACING_DELIM}") .gsub(/\|#{VARIABLE_DELIM}\{\{/o, "#{NON_SPACING_DELIM}#{VARIABLE_DELIM}{{") end |
#create_liquid_environment ⇒ Object
59 60 61 62 63 |
# File 'lib/relaton/render/template/template.rb', line 59 def create_liquid_environment env = ::Liquid::Environment.new env.register_filter(::Relaton::Render::Template::CustomFilters) env end |
#liquid_hash(hash) ⇒ Object
need non-breaking spaces in fields: “Updated:_nil” — we want the “Updated:” deleted, even if it’s multiple words, as in French Mise_à_jour.
204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/relaton/render/template/template.rb', line 204 def liquid_hash(hash) case hash when Hash hash.map { |k, v| [k.to_s, liquid_hash(v)] }.to_h when Array hash.map { |v| liquid_hash(v) } when String hash.empty? ? nil : hash.gsub("_", "\\_").tr(" ", "_") else hash end end |
#parse_options(opt) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/relaton/render/template/template.rb', line 45 def (opt) # opt = Utils::sym_keys(opt) opt = opt.symbolize_all_keys @i18n = opt[:i18n] @template_raw = opt[:template].dup @template = case opt[:template] when Hash opt[:template].transform_values { |x| template_process(x) } when Array then opt[:template].map { |x| template_process(x) } else { default: template_process(opt[:template]) } end end |
#punct_field?(name) ⇒ Boolean
79 80 81 82 83 84 85 |
# File 'lib/relaton/render/template/template.rb', line 79 def punct_field?(name) name or return false name = name.tr("'", '"') %w(labels["punct"]["open-title"] labels["punct"]["close-title"] labels["punct"]["open-secondary-title"] labels["punct"]["close-secondary-title"]).include?(name) end |
#remove_double_period(ret, delimrstripre) ⇒ Object
188 189 190 191 192 193 |
# File 'lib/relaton/render/template/template.rb', line 188 def remove_double_period(ret, delimrstripre) ret[0...-1].map do |s| s.sub(/#{delimrstripre}$/, "") .sub(%r[#{delimrstripre}(</[^>]+>)$], "\\1") end + [ret.last] end |
#render(hash, context) ⇒ Object
hash is what to render, which can be entire bib entry, or a subset of it like names context is information for selecting i18n, which is entire bib entry, potentially enhanced
116 117 118 119 120 121 122 |
# File 'lib/relaton/render/template/template.rb', line 116 def render(hash, context) t = template_select(hash) or return nil # TODO select on context? i = @i18n.select(context).get ret = template_clean(t.render(liquid_hash(hash.merge("labels" => i)))) template_components(ret, i.dig("punct", "biblio-field-delimiter") || ". ") end |
#strip_empty_variables(str) ⇒ Object
get rid of all empty variables, and any text around them, including component delimiters: [{}]$$$ => “”
- {}
-
$$$ => “ $$$”
161 162 163 164 |
# File 'lib/relaton/render/template/template.rb', line 161 def strip_empty_variables(str) str.gsub(/\S*#{VARIABLE_DELIM}#{VARIABLE_DELIM}\S*/o, "") .gsub(/#{VARIABLE_DELIM}/o, "") end |
#template_clean(str) ⇒ Object
128 129 130 131 132 133 134 135 |
# File 'lib/relaton/render/template/template.rb', line 128 def template_clean(str) str = str.gsub(/</i, LT_DELIM).gsub(/>/i, GT_DELIM) str = template_clean1(@htmlentities.decode(str)) /[[:alnum:]]/.match?(str) or return nil str.strip.gsub(/#{LT_DELIM}/o, "<") .gsub(/#{GT_DELIM}/o, ">") .gsub(/&(?!#\S+?;)/, "&") end |
#template_clean1(str) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/relaton/render/template/template.rb', line 137 def template_clean1(str) str = strip_empty_variables(str) str.gsub(/([,:;]\s*)+<\/esc>([,:;])(\s|_|$)/, "\\2</esc>\\3") .gsub(/([,:;]\s*)+([,:;](\s|_|$))/, "\\2") .gsub(/([,.:;]\s*)+<\/esc>([.])(\s|_|$)/, "\\2</esc>\\3") # move outside .gsub(/([,.:;]\s*)+([.](\s|_|$))/, "\\2") # move outside .gsub(/([,:;]\s*)+<\/esc>(,)(\s|_|$)/, "\\2</esc>\\3") .gsub(/([,:;]\s*)+(,(\s|_|$))/, "\\2") .gsub(/([,:;]\s*)+(#{COMPONENT_DELIM})/o, "\\2") .gsub(/(:\s+)(&\s)/, "\\2") .gsub(/\s+([,.:;)])/, "\\1") # trim around $$$ .sub(/^\s*[,.:;]\s*/, "") # no init $$$ .sub(/[,:;]\s*$/, "") .gsub(/(?<!\\)_/, " ") .gsub("\\_", "_") .gsub(/(?<!#{COMPONENT_DELIM})#{NON_SPACING_DELIM}(?!#{COMPONENT_DELIM})/o, "") # preserve NON_SPACING_DELIM near $$$ .gsub(/[\n\r ]+/, " ") .gsub(/<(\/)?esc>/i, "<\\1esc>") end |
#template_components(str, delim) ⇒ Object
delim = punct.biblio-field-terminator must not be i18n’ised: .</esc>. deletes first . .</esc>。does not delete first . So we do not want to pass delim in as ., and then have it i18n to 。after we are done parsing
Do not strip any delimiters from final field in string
if delim = “. ” , then: (series }$$$|) => (series1.)
175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/relaton/render/template/template.rb', line 175 def template_components(str, delim) str or return str delimrstrip, delimre, delimrstripre = template_components_prep(delim) ret = str.gsub(NON_SPACING_DELIM, "|").split(/#{COMPONENT_DELIM}/o) .map(&:strip).reject(&:empty?) ret = ret[0...-1].map do |s| s.sub(/#{delimre}$/, "").sub(%r[#{delimre}(</[^>]+>)$], "\\1") end + [ret.last] delim != delimrstrip and # "." in field followed by ". " in delim ret = remove_double_period(ret, delimrstripre) ret.join(delim).gsub(/#{delim}\|/, delimrstrip) end |
#template_components_prep(delim) ⇒ Object
195 196 197 198 199 |
# File 'lib/relaton/render/template/template.rb', line 195 def template_components_prep(delim) [delim.rstrip, Regexp.quote(delim), # if delim is esc'd, ignore the escs in the preceding span Regexp.quote(delim.rstrip.gsub(%r{</?esc>}, ""))] end |
#template_process(template) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/relaton/render/template/template.rb', line 87 def template_process(template) template.is_a?(String) or return template t = nil @templatecache.mutex.synchronize do unless t = @templatecache.retrieve(template) t = ::Liquid::Template .parse(add_field_delim_to_template(template), environment: @liquid_env) @templatecache.store(template, t) end end t end |
#template_select(_hash) ⇒ Object
124 125 126 |
# File 'lib/relaton/render/template/template.rb', line 124 def template_select(_hash) @template[:default] end |