Class | RDoc::Markup::AttributeManager |
In: |
markup/inline.rb
|
Parent: | Object |
# File markup/inline.rb, line 226 226: def initialize 227: add_word_pair("*", "*", :BOLD) 228: add_word_pair("_", "_", :EM) 229: add_word_pair("+", "+", :TT) 230: 231: add_html("em", :EM) 232: add_html("i", :EM) 233: add_html("b", :BOLD) 234: add_html("tt", :TT) 235: add_html("code", :TT) 236: 237: add_special(/<!--(.*?)-->/, :COMMENT) 238: end
# File markup/inline.rb, line 256 256: def add_html(tag, name) 257: HTML_TAGS[tag.downcase] = Attribute.bitmap_for(name) 258: end
# File markup/inline.rb, line 260 260: def add_special(pattern, name) 261: SPECIAL[pattern] = Attribute.bitmap_for(name) 262: end
# File markup/inline.rb, line 240 240: def add_word_pair(start, stop, name) 241: raise "Word flags may not start '<'" if start[0] == ?< 242: bitmap = Attribute.bitmap_for(name) 243: if start == stop 244: MATCHING_WORD_PAIRS[start] = bitmap 245: else 246: pattern = Regexp.new("(" + Regexp.escape(start) + ")" + 247: # "([A-Za-z]+)" + 248: "(\\S+)" + 249: "(" + Regexp.escape(stop) +")") 250: WORD_PAIR_MAP[pattern] = bitmap 251: end 252: PROTECTABLE << start[0,1] 253: PROTECTABLE.uniq! 254: end
# File markup/inline.rb, line 143 143: def change_attribute(current, new) 144: diff = current ^ new 145: attribute(new & diff, current & diff) 146: end
# File markup/inline.rb, line 148 148: def changed_attribute_by_name(current_set, new_set) 149: current = new = 0 150: current_set.each {|name| current |= Attribute.bitmap_for(name) } 151: new_set.each {|name| new |= Attribute.bitmap_for(name) } 152: change_attribute(current, new) 153: end
Map attributes like textto the sequence 001\002<char>001\003<char>, where <char> is a per-attribute specific character
# File markup/inline.rb, line 166 166: def convert_attrs(str, attrs) 167: # first do matching ones 168: tags = MATCHING_WORD_PAIRS.keys.join("") 169: 170: re = /(^|\W)([#{tags}])([#\\]?[\w.\/]+?\S?)\2(\W|$)/ 171: 172: 1 while str.gsub!(re) do 173: attr = MATCHING_WORD_PAIRS[$2] 174: attrs.set_attrs($`.length + $1.length + $2.length, $3.length, attr) 175: $1 + NULL * $2.length + $3 + NULL * $2.length + $4 176: end 177: 178: # then non-matching 179: unless WORD_PAIR_MAP.empty? then 180: WORD_PAIR_MAP.each do |regexp, attr| 181: str.gsub!(regexp) { 182: attrs.set_attrs($`.length + $1.length, $2.length, attr) 183: NULL * $1.length + $2 + NULL * $3.length 184: } 185: end 186: end 187: end
# File markup/inline.rb, line 189 189: def convert_html(str, attrs) 190: tags = HTML_TAGS.keys.join '|' 191: 192: 1 while str.gsub!(/<(#{tags})>(.*?)<\/\1>/i) { 193: attr = HTML_TAGS[$1.downcase] 194: html_length = $1.length + 2 195: seq = NULL * html_length 196: attrs.set_attrs($`.length + html_length, $2.length, attr) 197: seq + $2 + seq + NULL 198: } 199: end
# File markup/inline.rb, line 201 201: def convert_specials(str, attrs) 202: unless SPECIAL.empty? 203: SPECIAL.each do |regexp, attr| 204: str.scan(regexp) do 205: attrs.set_attrs($`.length, $&.length, attr | Attribute::SPECIAL) 206: end 207: end 208: end 209: end
# File markup/inline.rb, line 155 155: def copy_string(start_pos, end_pos) 156: res = @str[start_pos...end_pos] 157: res.gsub!(/\000/, '') 158: res 159: end
# File markup/inline.rb, line 285 285: def display_attributes 286: puts 287: puts @str.tr(NULL, "!") 288: bit = 1 289: 16.times do |bno| 290: line = "" 291: @str.length.times do |i| 292: if (@attrs[i] & bit) == 0 293: line << " " 294: else 295: if bno.zero? 296: line << "S" 297: else 298: line << ("%d" % (bno+1)) 299: end 300: end 301: end 302: puts(line) unless line =~ /^ *$/ 303: bit <<= 1 304: end 305: end
# File markup/inline.rb, line 264 264: def flow(str) 265: @str = str 266: 267: puts("Before flow, str='#{@str.dump}'") if $DEBUG_RDOC 268: mask_protected_sequences 269: 270: @attrs = AttrSpan.new(@str.length) 271: 272: puts("After protecting, str='#{@str.dump}'") if $DEBUG_RDOC 273: 274: convert_attrs(@str, @attrs) 275: convert_html(@str, @attrs) 276: convert_specials(str, @attrs) 277: 278: unmask_protected_sequences 279: 280: puts("After flow, str='#{@str.dump}'") if $DEBUG_RDOC 281: 282: return split_into_flow 283: end
# File markup/inline.rb, line 217 217: def mask_protected_sequences 218: protect_pattern = Regexp.new("\\\\([#{Regexp.escape(PROTECTABLE.join(''))}])") 219: @str.gsub!(protect_pattern, "\\1#{PROTECT_ATTR}") 220: end
# File markup/inline.rb, line 307 307: def split_into_flow 308: display_attributes if $DEBUG_RDOC 309: 310: res = [] 311: current_attr = 0 312: str = "" 313: 314: str_len = @str.length 315: 316: # skip leading invisible text 317: i = 0 318: i += 1 while i < str_len and @str[i] == "\0" 319: start_pos = i 320: 321: # then scan the string, chunking it on attribute changes 322: while i < str_len 323: new_attr = @attrs[i] 324: if new_attr != current_attr 325: if i > start_pos 326: res << copy_string(start_pos, i) 327: start_pos = i 328: end 329: 330: res << change_attribute(current_attr, new_attr) 331: current_attr = new_attr 332: 333: if (current_attr & Attribute::SPECIAL) != 0 334: i += 1 while i < str_len and (@attrs[i] & Attribute::SPECIAL) != 0 335: res << Special.new(current_attr, copy_string(start_pos, i)) 336: start_pos = i 337: next 338: end 339: end 340: 341: # move on, skipping any invisible characters 342: begin 343: i += 1 344: end while i < str_len and @str[i] == "\0" 345: end 346: 347: # tidy up trailing text 348: if start_pos < str_len 349: res << copy_string(start_pos, str_len) 350: end 351: 352: # and reset to all attributes off 353: res << change_attribute(current_attr, 0) if current_attr != 0 354: 355: return res 356: end