Module: CDK::Converters

Included in:
CDKOBJS
Defined in:
lib/cdk/mixins/converters.rb

Instance Method Summary collapse

Instance Method Details

#char2Chtype(string, to, align) ⇒ Object

This function takes a string, full of format markers and translates them into a chtype array. This is better suited to curses because curses uses chtype almost exclusively



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/cdk/mixins/converters.rb', line 120

def char2Chtype (string, to, align)
  to << 0
  align << LEFT
  result = []

  if string.size > 0
    used = 0

    # The original code makes two passes since it has to pre-allocate space but
    # we should be able to make do with one since we can dynamically size it
    adjust = 0
    attrib = Ncurses::A_NORMAL
    last_char = 0
    start = 0
    used = 0
    x = 3

    # Look for an alignment marker.
    if string[0] == L_MARKER
      if string[1] == 'C' && string[2] == R_MARKER
        align[0] = CENTER
        start = 3
      elsif string[1] == 'R' && string[2] == R_MARKER
        align[0] = RIGHT
        start = 3
      elsif string[1] == 'L' && string[2] == R_MARKER
        start = 3
      elsif string[1] == 'B' && string[2] == '='
        # Set the item index value in the string.
        result = [' '.ord, ' '.ord, ' '.ord]

        # Pull out the bullet marker.
        while x < string.size and string[x] != R_MARKER
          result << (string[x].ord | Ncurses::A_BOLD)
          x += 1
        end
        adjust = 1

        # Set the alignment variables
        start = x
        used = x
      elsif string[1] == 'I' && string[2] == '='
        from = 3
        x = 0

        while from < string.size && string[from] != Ncurses.R_MARKER
          if CDK.digit?(string[from])
            adjust = adjust * 10 + string[from].to_i
            x += 1
          end
          from += 1
        end

        start = x + 4
      end
    end

    while adjust > 0
      adjust -= 1
      result << ' '
      used += 1
    end

    # Set the format marker boolean to false
    inside_marker = false

    # Start parsing the character string.
    from = start
    while from < string.size
      # Are we inside a format marker?
      if !inside_marker
        if string[from] == L_MARKER &&
            ['/', '!', '#'].include?(string[from + 1])
          inside_marker = true
        elsif string[from] == "\\" && string[from + 1] == L_MARKER
          from += 1
          result << (string[from].ord | attrib)
          used += 1
          from += 1
        elsif string[from] == "\t"
          begin
            result << ' '
            used += 1
          end while (used & 7).nonzero?
        else
          result << (string[from].ord | attrib)
          used += 1
        end
      else
        case string[from]
        when R_MARKER
          inside_marker = false
        when '#'
          last_char = 0
          case string[from + 2]
          when 'L'
            case string[from + 1]
            when 'L'
              last_char = Ncurses::ACS_LLCORNER
            when 'U'
              last_char = Ncurses::ACS_ULCORNER
            when 'H'
              last_char = Ncurses::ACS_HLINE
            when 'V'
              last_char = Ncurses::ACS_VLINE
            when 'P'
              last_char = Ncurses::ACS_PLUS
            end
          when 'R'
            case string[from + 1]
            when 'L'
              last_char = Ncurses::ACS_LRCORNER
            when 'U'
              last_char = Ncurses::ACS_URCORNER
            end
          when 'T'
            case string[from + 1]
            when 'T'
              last_char = Ncurses::ACS_TTEE
            when 'R'
              last_char = Ncurses::ACS_RTEE
            when 'L'
              last_char = Ncurses::ACS_LTEE
            when 'B'
              last_char = Ncurses::ACS_BTEE
            end
          when 'A'
            case string[from + 1]
            when 'L'
              last_char = Ncurses::ACS_LARROW
            when 'R'
              last_char = Ncurses::ACS_RARROW
            when 'U'
              last_char = Ncurses::ACS_UARROW
            when 'D'
              last_char = Ncurses::ACS_DARROW
            end
          else
            case [string[from + 1], string[from + 2]]
            when ['D', 'I']
              last_char = Ncurses::ACS_DIAMOND
            when ['C', 'B']
              last_char = Ncurses::ACS_CKBOARD
            when ['D', 'G']
              last_char = Ncurses::ACS_DEGREE
            when ['P', 'M']
              last_char = Ncurses::ACS_PLMINUS
            when ['B', 'U']
              last_char = Ncurses::ACS_BULLET
            when ['S', '1']
              last_char = Ncurses::ACS_S1
            when ['S', '9']
              last_char = Ncurses::ACS_S9
            end
          end

          if last_char.nonzero?
            adjust = 1
            from += 2

            if string[from + 1] == '('
              # check for a possible numeric modifier
              from += 2
              adjust = 0

              while from < string.size && string[from] != ')'
                if CDK.digit?(string[from])
                  adjust = (adjust * 10) + string[from].to_i
                end
                from += 1
              end
            end
          end
          (0...adjust).each do |x|
            result << (last_char | attrib)
            used += 1
          end
        when '/'
          mask = []
          from = encode_attribute(string, from, mask)
          attrib |= mask[0]
        when '!'
          mask = []
          from = encode_attribute(string, from, mask)
          attrib &= ~(mask[0])
        end
      end
      from += 1
    end

    if result.size == 0
      result << attrib
    end
    to[0] = used
  else
    result = []
  end
  return result
end

#charOf(chtype) ⇒ Object

… def self.char2Chtype (string, to, align) end



324
325
326
# File 'lib/cdk/mixins/converters.rb', line 324

def charOf(chtype)
  (chtype.ord & 255).chr
end

#chtype2Char(string) ⇒ Object

This returns a string from a chtype array Formatting codes are omitted.



330
331
332
333
334
335
336
337
338
339
340
# File 'lib/cdk/mixins/converters.rb', line 330

def chtype2Char(string)
  newstring = ''

  unless string.nil?
    string.each do |char|
      newstring << charOf(char)
    end
  end

  return newstring
end

#chtype2String(string) ⇒ Object

This returns a string from a chtype array Formatting codes are embedded



344
345
346
347
348
349
350
351
352
353
354
355
356
# File 'lib/cdk/mixins/converters.rb', line 344

def chtype2String(string)
  newstring = ''
  unless string.nil?
    need = 0
    (0...string.size).each do |x|
      need = decode_attribute(newstring, need,
                                 x > 0 ? string[x - 1] : 0, string[x])
      newstring << string[x]
    end
  end

  return newstring
end

#decode_attribute(string, from, oldattr, newattr) ⇒ Object

The reverse of encode_attribute Well, almost. If attributes such as bold and underline are combined in the same string, we do not necessarily reconstruct them in the same order. Also, alignment markers and tabs are lost.



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
# File 'lib/cdk/mixins/converters.rb', line 52

def decode_attribute (string, from, oldattr, newattr)
  table = {
    'B' => Ncurses::A_BOLD,
    'D' => Ncurses::A_DIM,
    'K' => Ncurses::A_BLINK,
    'R' => Ncurses::A_REVERSE,
    'S' => Ncurses::A_STANDOUT,
    'U' => Ncurses::A_UNDERLINE
  }

  result = if string.nil? then '' else string end
  base_len = result.size
  tmpattr = oldattr & Ncurses::A_ATTRIBUTES

  newattr &= Ncurses::A_ATTRIBUTES
  if tmpattr != newattr
    while tmpattr != newattr
      found = false
      table.keys.each do |key|
        if (table[key] & tmpattr) != (table[key] & newattr)
          found = true
          result << CDK::L_MARKER
          if (table[key] & tmpattr).nonzero?
            result << '!'
            tmpattr &= ~(table[key])
          else
            result << '/'
            tmpattr |= table[key]
          end
          result << key
          break
        end
      end
      # XXX: Only checks if terminal has colours not if colours are started
      if Ncurses.has_colors?
        if (tmpattr & Ncurses::A_COLOR) != (newattr & Ncurses::A_COLOR)
          oldpair = Ncurses.PAIR_NUMBER(tmpattr)
          newpair = Ncurses.PAIR_NUMBER(newattr)
          if !found
            found = true
            result << CDK::L_MARKER
          end
          if newpair.zero?
            result << '!'
            result << oldpair.to_s
          else
            result << '/'
            result << newpair.to_s
          end
          tmpattr &= ~(Ncurses::A_COLOR)
          newattr &= ~(Ncurses::A_COLOR)
        end
      end

      if found
        result << CDK::R_MARKER
      else
        break
      end
    end
  end

  return from + result.size - base_len
end

#encode_attribute(string, from, mask) ⇒ Object



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
# File 'lib/cdk/mixins/converters.rb', line 3

def encode_attribute (string, from, mask)
  mask << 0
  case string[from + 1]
  when 'B'
    mask[0] = Ncurses::A_BOLD
  when 'D'
    mask[0] = Ncurses::A_DIM
  when 'K'
    mask[0] = Ncurses::A_BLINK
  when 'R'
    mask[0] = Ncurses::A_REVERSE
  when 'S'
    mask[0] = Ncurses::A_STANDOUT
  when 'U'
    mask[0] = Ncurses::A_UNDERLINE
  end

  if mask[0] != 0
    from += 1
  elsif CDK.digit?(string[from+1]) and CDK.digit?(string[from + 2])
    if Ncurses.has_colors?
      # XXX: Only checks if terminal has colours not if colours are started
      pair = string[from + 1..from + 2].to_i
      mask[0] = Ncurses.COLOR_PAIR(pair)
    else
      mask[0] = Ncurses.A_BOLD
    end

    from += 2
  elsif CDK.digit?(string[from + 1])
    if Ncurses.has_colors?
      # XXX: Only checks if terminal has colours not if colours are started
      pair = string[from + 1].to_i
      mask[0] = Ncurses.COLOR_PAIR(pair)
    else
      mask[0] = Ncurses.A_BOLD
    end

    from += 1
  end

  return from
end