/lib/shada/shada_app/templator.rb

https://github.com/bairdb/shada · Ruby · 252 lines · 208 code · 36 blank · 8 comment · 17 complexity · 0e3e57116181fde2aafe653b9a8e6e36 MD5 · raw file

  1. #!/usr/bin/env ruby -wKU
  2. #require "iconv"
  3. require 'shada/shada_logger'
  4. require 'shada/shada_utils'
  5. module Shada
  6. class Templator
  7. include Shada::Logger
  8. attr_accessor :registry, :html
  9. def initialize
  10. #@ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
  11. @pattern = /\{\$([^\r\n]*?)\}/m
  12. @alt_pattern = /\[\$(.*?)\]/m
  13. @include_pattern = /\{\include file\=\"(.*?)\"\}/
  14. @result_pattern = /\{results for \$(.*?)}(?:(.*?))\{\/results\}/m
  15. @result_var_pattern = /\[\$(.*)\]/
  16. @function_pattern = /\{\$(.*?)\->(.*?)\}/
  17. @array_pattern = /\{\$(.*?)\>(.*?)\}/
  18. @file_pattern = /\{file\=\"(.*)\"\}/
  19. @block_pattern = /\{block\=\"(.*)\"\}/
  20. @param_pattern = /\[\$(.*?)\]/
  21. @tag_arr = []
  22. @rep_arr = []
  23. @html = ''
  24. @tags = []
  25. @flow = {:include => 'includes', :file => 'files', :value => 'values', :image => 'images', :array => 'arrays'}
  26. @flow2 = {:result => 'results', :function => 'functions'}
  27. @parse_arr = {:result => '->', :function => '->', :array => '>'}
  28. @content_arr = []
  29. @result_arr = []
  30. @registry = {}
  31. register 'exclude', ''
  32. end
  33. #register
  34. def register key, val, type="value"
  35. @registry[key] = {:value => val, :type => type}
  36. end
  37. def unregister key
  38. @registry.delete key
  39. end
  40. def open_template file
  41. unless File.directory?(file)
  42. File.read file
  43. else
  44. ''
  45. end
  46. end
  47. def init template
  48. @html = open_template template
  49. @html = @html.encode('utf-8')
  50. includes
  51. preprocess_results
  52. parse 1
  53. parse 2
  54. render
  55. results
  56. parse 1
  57. parse 2
  58. #files
  59. #block
  60. cleanup
  61. end
  62. def gettags
  63. @html = @html.encode('utf-8')
  64. @tags = @html.scan @pattern
  65. end
  66. def parse pass
  67. gettags
  68. @registry.each do |key, val|
  69. type = val[:type]
  70. parse_val = @parse_arr[type]
  71. @tags.each do |tag|
  72. tag_parse = parse_val ? tag[0].split(parse_val) : ''
  73. tag_clean = parse_val ? tag_parse[0] : tag[0]
  74. if tag_clean == key.to_s
  75. arr = pass == 1 ? @flow : @flow2
  76. if arr.has_key? type.to_sym
  77. value = val[:value]
  78. self.send arr[type.to_sym], {:value => value, :key => key, :tag => tag[0], :parse_val => parse_val}
  79. end
  80. end
  81. end
  82. end
  83. end
  84. def values hash
  85. @tag_arr.push /\{\$#{hash[:key].to_s}\}/
  86. if hash[:value].is_a?(String)
  87. @rep_arr.push hash[:value].encode('utf-8')
  88. else
  89. @rep_arr.push hash[:value]
  90. end
  91. @html = @html.force_encoding('UTF-8')
  92. @tag_arr.zip(@rep_arr).each do |key, val|
  93. begin
  94. @html.gsub! key, val.force_encoding('UTF-8')
  95. rescue => e
  96. @html.gsub! key, ''
  97. end
  98. end
  99. end
  100. def includes
  101. @html = @html.encode('utf-8')
  102. inc = @html.scan @include_pattern
  103. tag_arr = []
  104. rep_arr = []
  105. inc.each do |val|
  106. pattern = /{include file="#{Regexp.quote(val[0])}"}/
  107. begin
  108. html = open_template val[0]
  109. @html.gsub! pattern, html
  110. rescue => e
  111. #puts e.message
  112. @html.gsub! pattern, ''
  113. end
  114. end
  115. inc2 = @html.scan @include_pattern
  116. unless inc2.empty?
  117. includes
  118. end
  119. end
  120. def arrays hash
  121. tag = hash[:tag].split hash[:parse_val]
  122. hash[:value].each do |key, val|
  123. arr_val = key == tag[1].to_sym ? val : ''
  124. unless arr_val.nil?
  125. @tag_arr.push /\{\$#{Regexp.quote(hash[:tag])}\}/
  126. @rep_arr.push arr_val
  127. end
  128. end
  129. end
  130. def functions hash, result=false
  131. value = hash[:tag].split hash[:parse_val]
  132. val = @registry[value[0]]
  133. klass = val[:value].class == String ? Object.const_get(val[:value]).new : val[:value]
  134. klass_name = val[:value].class == String ? val[:value].to_s : val[:value].class.to_s
  135. function = value[1]
  136. function_pieces = function.scan /(.*)\((.*)\)/ || function
  137. function_name = function.gsub /\((.*)\)/, ''
  138. oparam_arr = function_pieces[0][1].split(',').map do |val|
  139. m = val.strip.scan(@param_pattern)
  140. if m.count > 0
  141. begin
  142. @registry[(m[0][0]).to_sym][:value]
  143. rescue => e
  144. ""
  145. end
  146. else
  147. val.strip
  148. end
  149. end
  150. res = klass.send function_name.to_sym, *oparam_arr
  151. unless result
  152. reg_str = Regexp.quote "{$#{value[0]}->#{function}}"
  153. begin
  154. @html.gsub! /#{reg_str}/, res
  155. rescue => e
  156. ''
  157. end
  158. else
  159. res
  160. end
  161. end
  162. def preprocess_results
  163. @html = @html.encode('utf-8')
  164. @html.scan(@result_pattern).inject(0) do |i, result|
  165. @content_arr.push result[1]
  166. @html = @html.gsub /\{results for \$#{Regexp.quote(result[0])}\}(.*?)\{\/results\}/m, "{results for $#{result[0]}}%%replacement_#{i}%%{/results}"
  167. i + 1
  168. end
  169. end
  170. def results
  171. tags = []
  172. rep = []
  173. @html = @html.encode('utf-8')
  174. @html.scan(@result_pattern).inject(0) do |i, result|
  175. @rep_pattern = @content_arr[i].to_s.strip
  176. @tmp = ""
  177. begin
  178. @html = @html.gsub "%%replacement_#{i}%%", @content_arr[i]
  179. #@content_arr.delete_at(i)
  180. rescue => e
  181. end
  182. hash = {:tag => result[0], :parse_val => @parse_arr[:function]}
  183. arr = functions hash, true
  184. if arr.class == Array
  185. arr.each do |row|
  186. lrep = @rep_pattern
  187. if row.class == Hash
  188. row.each do |k,v|
  189. puts "#{k} - #{v}"
  190. lrep = lrep.gsub /\{\$#{k.to_s}\}/, v
  191. lrep = lrep.gsub /\[\$#{k.to_s}\]/, v
  192. end
  193. @tmp.insert -1, lrep
  194. lrep = ""
  195. else
  196. row.fields.each do |f|
  197. lrep = lrep.gsub /\{\$#{f.to_s}\}/, "#{row.instance_variable_get("@#{f.to_s}")}"
  198. lrep = lrep.gsub /\[\$#{f.to_s}\]/, "#{row.instance_variable_get("@#{f.to_s}")}"
  199. end
  200. @tmp.insert -1, lrep
  201. lrep = ""
  202. end
  203. end
  204. end
  205. preprocess_results
  206. @html.gsub! /\{results for \$#{Regexp.quote(result[0])}\}(.*?)\{\/results\}/m, @tmp
  207. i + 1
  208. end
  209. end
  210. def cleanup
  211. @html.gsub! @pattern, ''
  212. end
  213. def render
  214. end
  215. end
  216. end