summaryrefslogtreecommitdiff
path: root/lib/rdoc/markup/inline.rb
blob: 932ed536b7f71382b31919b4cbec7c255d360ed8 (plain)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
require 'rdoc'
class RDoc::Markup

  ##
  # We manage a set of attributes. Each attribute has a symbol name and a bit
  # value.

  class Attribute

    ##
    # Special attribute type.  See RDoc::Markup#add_special

    SPECIAL = 1

    @@name_to_bitmap = { :_SPECIAL_ => SPECIAL }
    @@next_bitmap = 2

    ##
    # Returns a unique bit for +name+

    def self.bitmap_for(name)
      bitmap = @@name_to_bitmap[name]
      unless bitmap then
        bitmap = @@next_bitmap
        @@next_bitmap <<= 1
        @@name_to_bitmap[name] = bitmap
      end
      bitmap
    end

    ##
    # Returns a string representation of +bitmap+

    def self.as_string(bitmap)
      return "none" if bitmap.zero?
      res = []
      @@name_to_bitmap.each do |name, bit|
        res << name if (bitmap & bit) != 0
      end
      res.join(",")
    end

    ##
    # yields each attribute name in +bitmap+

    def self.each_name_of(bitmap)
      @@name_to_bitmap.each do |name, bit|
        next if bit == SPECIAL
        yield name.to_s if (bitmap & bit) != 0
      end
    end

  end

  AttrChanger = Struct.new :turn_on, :turn_off # :nodoc:

  ##
  # An AttrChanger records a change in attributes. It contains a bitmap of the
  # attributes to turn on, and a bitmap of those to turn off.

  class AttrChanger
    def to_s # :nodoc:
      "Attr: +#{Attribute.as_string turn_on}/-#{Attribute.as_string turn_on}"
    end
  end

  ##
  # An array of attributes which parallels the characters in a string.

  class AttrSpan

    ##
    # Creates a new AttrSpan for +length+ characters

    def initialize(length)
      @attrs = Array.new(length, 0)
    end

    ##
    # Toggles +bits+ from +start+ to +length+
    def set_attrs(start, length, bits)
      for i in start ... (start+length)
        @attrs[i] |= bits
      end
    end

    ##
    # Accesses flags for character +n+

    def [](n)
      @attrs[n]
    end

  end

  ##
  # Hold details of a special sequence

  class Special

    ##
    # Special type

    attr_reader   :type

    ##
    # Special text

    attr_accessor :text

    ##
    # Creates a new special sequence of +type+ with +text+

    def initialize(type, text)
      @type, @text = type, text
    end

    ##
    # Specials are equal when the have the same text and type

    def ==(o)
      self.text == o.text && self.type == o.type
    end

    def inspect # :nodoc:
      "#<RDoc::Markup::Special:0x%x @type=%p, name=%p @text=%p>" % [
        object_id, @type, RDoc::Markup::Attribute.as_string(type), text.dump]
    end

    def to_s # :nodoc:
      "Special: type=#{type}, name=#{RDoc::Markup::Attribute.as_string type}, text=#{text.dump}"
    end

  end

end