File: reference-resolver.rb

package info (click to toggle)
rdtool 0.6.38-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 940 kB
  • sloc: ruby: 8,213; lisp: 387; sh: 33; makefile: 16
file content (114 lines) | stat: -rw-r--r-- 2,301 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
require 'rd/rbl-suite'
require 'rd/labeled-element'

require 'forwardable'

module RD
  class ReferenceResolver
    extend Forwardable
    include Enumerable
    
    attr_reader :labels
    attr_reader :label_prefix
    attr_reader :rbl_suite
    
    def initialize(tree, prefix = "label:")
      init_labels(tree)
      @label_prefix = prefix
      @rbl_suite = RBLSuite.new(tree.include_path)
    end

    def init_labels(tree)
      @labels = {}
      ary = (tree.find_all do |i|
	       i.is_a? LabeledElement
	     end)
      num = 0
      ary.each do |i|
	push_to_labels(i.to_label, [i, num])
	num += 1
      end
    end
    private :init_labels

    def push_to_labels(key, value)
      if labels[key]
	labels[key].push(value)
      else
	labels[key] = [value]
      end
    end
    private :push_to_labels

    def each_label
      tmp = []
      labels.each_value do |i|
	i.each do |j|
	  tmp.push(j)
	end
      end
      tmp.sort{|i,j| i[1] <=> j[1]}.each do |i|
	yield(i[0])
      end
    end
    alias each each_label

    def referent_of_label(label)
      label = label.label if label.is_a? Reference
      if label.filename
	refer_external_file(label)
      else
	anchor = refer(label)
	return nil unless anchor
	[nil, anchor]
      end
    end

    def refer(label)
      matched = labels[label2str(label)]
      return nil unless matched
      num2anchor(matched[0][1])
    end

    def refer_element(label)
      labels.fetch(label2str(label), []).collect{|i| i[0] }
    end

    def refer_external_file(label)
      label = label.label if label.is_a? Reference
      rbl_suite.refer(label.element_label, label.filename)
    end

    def get_label_num(element)
      entry = labels[element.to_label].find{|i| i[0] == element }
      return nil unless entry
      entry[1]
    end

    def get_anchor(element)
      if num = get_label_num(element)
	num2anchor(num)
      end
    end

    def num2anchor(num)
      label_prefix + num.to_s
    end
    private :num2anchor
    
    def label2str(label)
      case label
      when String
	label
      when Element, Reference::RDLabel
	label.to_label
      else
	raise ArgumentError, "can't extract Label from #{label}."
      end
    end

    def make_rbl_file(filename)
      RBLFile.create_rbl_file(filename, self)
    end
  end
end