/tools/Ruby/lib/ruby/1.8/rdoc/markup/simple_markup/lines.rb

http://github.com/agross/netopenspace · Ruby · 151 lines · 89 code · 34 blank · 28 comment · 9 complexity · 1508687b984a8bd1791d01680708d3e6 MD5 · raw file

  1. ##########################################################################
  2. #
  3. # We store the lines we're working on as objects of class Line.
  4. # These contain the text of the line, along with a flag indicating the
  5. # line type, and an indentation level
  6. module SM
  7. class Line
  8. INFINITY = 9999
  9. BLANK = :BLANK
  10. HEADING = :HEADING
  11. LIST = :LIST
  12. RULE = :RULE
  13. PARAGRAPH = :PARAGRAPH
  14. VERBATIM = :VERBATIM
  15. # line type
  16. attr_accessor :type
  17. # The indentation nesting level
  18. attr_accessor :level
  19. # The contents
  20. attr_accessor :text
  21. # A prefix or parameter. For LIST lines, this is
  22. # the text that introduced the list item (the label)
  23. attr_accessor :param
  24. # A flag. For list lines, this is the type of the list
  25. attr_accessor :flag
  26. # the number of leading spaces
  27. attr_accessor :leading_spaces
  28. # true if this line has been deleted from the list of lines
  29. attr_accessor :deleted
  30. def initialize(text)
  31. @text = text.dup
  32. @deleted = false
  33. # expand tabs
  34. 1 while @text.gsub!(/\t+/) { ' ' * (8*$&.length - $`.length % 8)} && $~ #`
  35. # Strip trailing whitespace
  36. @text.sub!(/\s+$/, '')
  37. # and look for leading whitespace
  38. if @text.length > 0
  39. @text =~ /^(\s*)/
  40. @leading_spaces = $1.length
  41. else
  42. @leading_spaces = INFINITY
  43. end
  44. end
  45. # Return true if this line is blank
  46. def isBlank?
  47. @text.length.zero?
  48. end
  49. # stamp a line with a type, a level, a prefix, and a flag
  50. def stamp(type, level, param="", flag=nil)
  51. @type, @level, @param, @flag = type, level, param, flag
  52. end
  53. ##
  54. # Strip off the leading margin
  55. #
  56. def strip_leading(size)
  57. if @text.size > size
  58. @text[0,size] = ""
  59. else
  60. @text = ""
  61. end
  62. end
  63. def to_s
  64. "#@type#@level: #@text"
  65. end
  66. end
  67. ###############################################################################
  68. #
  69. # A container for all the lines
  70. #
  71. class Lines
  72. include Enumerable
  73. attr_reader :lines # for debugging
  74. def initialize(lines)
  75. @lines = lines
  76. rewind
  77. end
  78. def empty?
  79. @lines.size.zero?
  80. end
  81. def each
  82. @lines.each do |line|
  83. yield line unless line.deleted
  84. end
  85. end
  86. # def [](index)
  87. # @lines[index]
  88. # end
  89. def rewind
  90. @nextline = 0
  91. end
  92. def next
  93. begin
  94. res = @lines[@nextline]
  95. @nextline += 1 if @nextline < @lines.size
  96. end while res and res.deleted and @nextline < @lines.size
  97. res
  98. end
  99. def unget
  100. @nextline -= 1
  101. end
  102. def delete(a_line)
  103. a_line.deleted = true
  104. end
  105. def normalize
  106. margin = @lines.collect{|l| l.leading_spaces}.min
  107. margin = 0 if margin == Line::INFINITY
  108. @lines.each {|line| line.strip_leading(margin) } if margin > 0
  109. end
  110. def as_text
  111. @lines.map {|l| l.text}.join("\n")
  112. end
  113. def line_types
  114. @lines.map {|l| l.type }
  115. end
  116. end
  117. end