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
|