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, context) ⇒ Object
delim = punct.biblio-field-terminator must not be i18n’ised: .</esc>.
- #template_components_prep(delim) ⇒ Object
- #template_components_split(str, delimre) ⇒ 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.
212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/relaton/render/template/template.rb', line 212 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
196 197 198 199 200 201 |
# File 'lib/relaton/render/template/template.rb', line 196 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 123 124 |
# 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) i18nsettings = { "labels" => i.get, "lang" => i.lang, "script" => i.script, "locale" => i.locale } ret = template_clean(t.render(liquid_hash(hash.merge(i18nsettings)))) bib_delim = i.get.dig("punct", "biblio-field-delimiter") || ". " template_components(ret, bib_delim, context) end |
#strip_empty_variables(str) ⇒ Object
get rid of all empty variables, and any text around them, including component delimiters: [{}]$$$ => “”
- {}
-
$$$ => “ $$$”
163 164 165 166 |
# File 'lib/relaton/render/template/template.rb', line 163 def strip_empty_variables(str) str.gsub(/\S*#{VARIABLE_DELIM}#{VARIABLE_DELIM}\S*/o, "") .gsub(/#{VARIABLE_DELIM}/o, "") end |
#template_clean(str) ⇒ Object
130 131 132 133 134 135 136 137 |
# File 'lib/relaton/render/template/template.rb', line 130 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
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/relaton/render/template/template.rb', line 139 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, context) ⇒ 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.)
177 178 179 180 181 182 183 184 185 186 |
# File 'lib/relaton/render/template/template.rb', line 177 def template_components(str, delim, context) str or return str delimrstrip, delimre, delimrstripre = template_components_prep(delim) ret = template_components_split(str, delimre) delim != delimrstrip and # "." in field followed by ". " in delim ret = remove_double_period(ret, delimrstripre) context[:citestyle] == "short" and ret[0] += "<span class='fmt-first-biblio-delim'/>" ret.join(delim).gsub(/#{delim}\|/, delimrstrip) end |
#template_components_prep(delim) ⇒ Object
203 204 205 206 207 |
# File 'lib/relaton/render/template/template.rb', line 203 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_components_split(str, delimre) ⇒ Object
188 189 190 191 192 193 194 |
# File 'lib/relaton/render/template/template.rb', line 188 def template_components_split(str, delimre) ret = str.gsub(NON_SPACING_DELIM, "|").split(/#{COMPONENT_DELIM}/o) .map(&:strip).reject(&:empty?) ret[0...-1].map do |s| s.sub(/#{delimre}$/, "").sub(%r[#{delimre}(</[^>]+>)$], "\\1") end + [ret.last] 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
126 127 128 |
# File 'lib/relaton/render/template/template.rb', line 126 def template_select(_hash) @template[:default] end |