lib/trac-wiki/parser.rb in trac-wiki-0.3.29 vs lib/trac-wiki/parser.rb in trac-wiki-0.3.30

- old
+ new

@@ -1,9 +1,11 @@ # encoding: utf-8 require 'cgi' require 'uri' require 'yaml' +require 'base64' +require 'digest/sha2' require 'unicode_utils/compatibility_decomposition' # :main: TracWiki # The TracWiki parses and translates Trac formatted text into @@ -129,14 +131,14 @@ # at_callback.call(env, key) -> computed value attr_accessor :at_callback # macro {{$var}} | {{#comment}} | {{!cmd}} | {{template}} | {{/template}} # string begins with macro - MACRO_BEG_REX = /\A\{\{ ( \$[\$\.\w]+ | [\#!\/]\w* |\w+ ) /x - MACRO_BEG_INSIDE_REX = /\A(.*?) (?<!\{|!|!\{) \{\{ ( \$[\$\.\w]+ | [\#!\/]\w* | \w+ ) /xm + MACRO_BEG_REX = /\A\{\{ ( \$[#\$\.\w]+ | [\#!\/]\w* |\w+ ) /x + MACRO_BEG_INSIDE_REX = /\A(.*?) (?<!\{|!|!\{) \{\{ ( \$[#\$\.\w]+ | [\#!\/]\w* | \w+ ) /xm # find end of marcro or begin of inner macro - MACRO_END_REX = /\A(.*?) ( \}\} | \{\{ ( \$[\$\.\w]+ | [\#!\/]\w* | \w+) )/mx + MACRO_END_REX = /\A(.*?) ( \}\} | \{\{ ( \$[#\$\.\w]+ | [\#!\/]\w* | \w+) )/mx # Create a new Parser instance. def initialize(options = {}) init_macros @at_callback = nil @@ -225,32 +227,86 @@ '!yset' => proc { |env| env[env.expand_arg(0)] = YAML.load(env.arg(1)); '' }, '!sub' => proc { |env| pat = env.expand_arg(1) pat = Regexp.new(pat[1..-2]) if pat =~ /\A\/.*\/\Z/ env.expand_arg(0).gsub(pat, env.expand_arg(2)) }, - '!macpos' => proc { |env| "#{env.at('lineno')}.#{env.at('offset')}-#{env.at('elineno')}.#{env.at('eoffset')}" }, + '!macpos'=> proc { |env| "#{env.at('lineno')}.#{env.at('offset')}-#{env.at('elineno')}.#{env.at('eoffset')}" }, + # in macro {{arg {{$i}}} -> i=4 => ctyry + '!arg' => proc { |env| + #print "arg: #{env.arg(0)}, #{env} }" + "#{env.at(env.expand(env.arg(0)))}" + }, + + # {{!forargs i|3|i:{$$i}}}} -> 0,1,2 + # {{!forargs i||i:{$$i}}}} -> 0,1,2 + '!sprintf' => proc { |env| + fmt = env.arg(0) + args = (1 .. env.arg_count ).map{ |i| env.expand_arg(i)} + begin + sprintf fmt, *args + rescue Exception => e + "(sprintf error:`#{e}`)" + end + }, + '!digest' => proc { |env| Base64.urlsafe_encode64(Digest::SHA256.digest(env.expand_arg(0))) }, + '!base64' => proc { |env| Base64.urlsafe_encode64(env.expand_arg(0)) }, + '!tt' => proc { |env| "`#{env.expand_arg(0)}`" }, + '!forargs' => proc { |env| i_name = env.arg(0) + i_name = env.arg(0) + start = env.arg(1).to_i # side efect '' => 0 + start = 1 if start < 1 + template = env.arg(2) + argcount = + (start .. env.arg_count ).map do |i| + env.atput(i_name, i.to_s) + env.expand(template) + end.join('') + }, + # {{!for i|1,3|i:{$$i}}}} -> 0,1,2 + # {{!for i|1,3,data|i:{$$i}}}} -> data[1,2,3] + # {{!for i|data|i:{$$i}}}} -> vsechny data + # {{!for i|1|i:{$$i}}}} -> vsechny data '!for' => proc { |env| i_name = env.arg(0) - top = env.arg(1) - tmpl = env.arg(2) - #print "top#{top}\n" - if top =~ /^\d+/ - set = (0..(top.to_i-1)) + + raise "!for takes exactly 3 argumentsif not #{env.arg_count}" if env.arg_count != 3 + + i_name = env.arg(0) + range = env.expand_arg(1) + templ = env.arg(2) + + arange = range.split(/,/) + arange = [ nil, nil, arange[0]] if arange.size == 1 + + bot = arange[0] + top = arange[1] + var = arange[2] + + if var.nil? + set = (bot.to_i||1 .. top.to_i) else - set = env.at(top, nil, false) - if set.is_a?(Hash) - set = set.keys.sort - elsif set.is_a?(Array) - set = (0 .. set.size-1) - elsif set.nil? + obj = env.at(var, nil, false) + + if obj.is_a?(Hash) + set = obj.keys.sort + elsif obj.is_a?(Array) + #print "ble:#{bot} #{bot}, #{obj.size}\n" + set = (bot||0 .. obj.size-1) + elsif obj.nil? set = [] else - print "error top(#{top}), set#{set} #{set.class}\n" - raise "Error in {{!for #{i_name}|#{top}|#{tmpl}}} $#{top}.class=#{set.class}(#{set.to_s})" + raise "Error: wrong arg #{obj} class='#{obj.class}'" end end + #set.select! { |x| x >= bot } if bot + #set.select! { |x| x <= top } if top + + #print "for set#{set} tmpl#{templ||"nic"}\n" + set.map do |i| + #print "for#{i} #{templ}\n" env[i_name] = i.to_s - env.expand(tmpl) + env.atput(i_name, i.to_s) + env.expand(templ) end.join('') }, } end