class ROF::Filters::Label
Class Label
locates in-place labels of the form “$(label_name)” in the ROF
file, assigns each label a pid, then replaces the label with that pid.
Public Class Methods
@param options [Hash] @option options [String, nil] :prefix - if truthy, prepend “<prefix>:” to each identifier @option options [Array, nil] :id_list - circumvent using the :noids configuration and instead use these for next_ids @option options [Hash] :noids - A Hash with keys :noid_server and :pool_name; Responsible for minting next_ids @raise NoPool
if we don't have a means of determining the next_id
# File lib/rof/filters/label.rb, line 27 def initialize(options = {}) prefix = options.fetch(:prefix, nil) @id_list = case when options[:id_list] options[:id_list] when options[:noids] NoidsPool.new(options[:noids].fetch(:noid_server), options[:noids].fetch(:pool_name)) else raise NoPool end @prefix = "#{prefix}:" if prefix # The first match group in the RE provides the label name @label_re = /\$\(([^)]+)\)/ end
Public Instance Methods
assign pids, recording any labels we find. obj is mutated
# File lib/rof/filters/label.rb, line 78 def assign_pid(obj, labels) return if obj['type'] != 'fobject' label = nil unless obj['pid'].nil? label = find_label(obj['pid']) # skip if the "pid" is not a label return if label.nil? end pid = "#{@prefix}#{next_id}" obj['pid'] = pid labels[label] = pid unless label.nil? end
# File lib/rof/filters/label.rb, line 130 def find_label(s) s[@label_re, 1] end
# File lib/rof/filters/label.rb, line 134 def next_id raise OutOfIdentifiers if @id_list.empty? @id_list.shift end
mutate obj_list by assigning labels and resolving labels where needed Every fobject will be assigned an pid and a bendo_item
# File lib/rof/filters/label.rb, line 44 def process(obj_list) labels = {} # Use two passes. First assign ids, and then resolve labels # Do this since labels can be referenced before being defined # Assign pids to each fobject. If we find any labels in the pid field, then # record a mapping of label => pid into the labels hash. obj_list.each do |obj| assign_pid(obj, labels) end # now replace any reference labels with the pids we've assigned them obj_list.each do |obj| replace_labels_in_obj(obj, labels) end # now assign bendo ids bendo_item = nil obj_list.each do |obj| # for now we just use the first item's pid stripped of any namespaces as the bendo item id if bendo_item.nil? bendo_item = obj['pid'].gsub(/^.*:/, '') unless obj['pid'].nil? next if bendo_item.nil? end # don't touch if a bendo item has already been assigned obj['bendo-item'] = bendo_item if obj['bendo-item'].nil? || obj['bendo-item'] == '' end obj_list end
recurse through obj replacing any labels in strings with the id in labels, which is a hash. The relacement is done in place. Hash keys are not touched (only hash values). if force is true, labels which don't resolve will raise a MissingLabel
error.
# File lib/rof/filters/label.rb, line 108 def replace_labels(obj, labels, force = false) if obj.is_a?(Array) obj.map! { |x| replace_labels(x, labels, force) } elsif obj.is_a?(Hash) obj.each { |k, v| obj[k] = replace_labels(v, labels, force) } obj elsif obj.is_a?(String) replace_match(obj, labels, force) else obj end end
replace any label references we find in obj. obj is mutated
# File lib/rof/filters/label.rb, line 94 def replace_labels_in_obj(obj, labels) return if obj['type'] != 'fobject' obj.each do |k, v| # only force labels to exist if we are looking in the rels-ext obj[k] = replace_labels(v, labels, k == 'rels-ext') end end
small matching function- uses regular expression
# File lib/rof/filters/label.rb, line 122 def replace_match(obj, labels, force) obj.gsub(@label_re) do |match| pid = labels[Regexp.last_match(1)] raise MissingLabel if pid.nil? && force pid.nil? ? match : pid end end