File: output_handler.rb

package info (click to toggle)
ruby-rgen 0.10.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,428 kB
  • sloc: ruby: 11,344; xml: 1,368; yacc: 72; makefile: 10
file content (120 lines) | stat: -rw-r--r-- 2,950 bytes parent folder | download | duplicates (3)
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
# RGen Framework
# (c) Martin Thiede, 2006

module RGen
  
module TemplateLanguage
  
  class OutputHandler
    attr_accessor :noIndentNextLine
    
    def initialize(indent=0, indentString="   ", mode=:explicit)
      self.mode = mode
      @indentString = indentString
      @state = :wait_for_nonws
      @output = ""
      @indent_string = @indentString*indent
    end

    def indent=(i)
      @indent_string = @indentString*i
    end

    NL = "\n"
    LFNL = "\r\n"
    if RUBY_VERSION.start_with?("1.8")
      NL_CHAR = 10
      LF_CHAR = 13
    else
      NL_CHAR = "\n"
      LF_CHAR = "\r"
    end
    
    # ERB will call this method for every string s which is part of the
    # template file in between %> and <%. If s contains a newline, it will
    # call this method for every part of s which is terminated by a \n
    # 
    def concat(s)
      if @ignoreNextNL
        idx = s.index(NL)
        if idx && s[0..idx].strip.empty?
          s = s[idx+1..-1]
        end
        @ignoreNextNL = false unless s.strip.empty?
      end
      if @ignoreNextWS
        s = s.lstrip
        @ignoreNextWS = false unless s.empty?
      end
      if @mode == :direct
        @output.concat(s)
      elsif @mode == :explicit
        while s.size > 0
          if @state == :wait_for_nl
            idx = s.index(NL)
            if idx
              if s[idx-1] == LF_CHAR
                @output.concat(s[0..idx].rstrip)
                @output.concat(LFNL)
              else
                @output.concat(s[0..idx].rstrip)
                @output.concat(NL)
              end
              s = s[idx+1..-1]
              @state = :wait_for_nonws
            else
              @output.concat(s)
              break
            end
          elsif @state == :wait_for_nonws
            s = s.lstrip
            if !s.empty?
              unless @noIndentNextLine || (@output[-1] && @output[-1] != NL_CHAR)
                @output.concat(@indent_string)
              else
                @noIndentNextLine = false
              end
              @state = :wait_for_nl
            end
          end
        end
      end
    end
    alias << concat
    
    def to_str
      @output
    end
    alias to_s to_str
    
    def direct_concat(s)
      @output.concat(s)
    end
    
    def direct_concat_allow_indent(s)
      unless @noIndentNextLine || (@output[-1] && @output[-1] != NL_CHAR)
        @output.concat(@indent_string)
      else
        @noIndentNextLine = false
      end
      @state = :wait_for_nl
      @output.concat(s)
    end

    def ignoreNextNL
      @ignoreNextNL = true
    end
    
    def ignoreNextWS
      @ignoreNextWS = true
    end
    
    def mode=(m)
      raise StandardError.new("Unknown mode: #{m}") unless [:direct, :explicit].include?(m)
      @mode = m
    end
  end
  
end
  
end