From 538a825eff9e2fbe5f00caf6a6d1c7734f9a455b Mon Sep 17 00:00:00 2001 From: pomyk Date: Wed, 7 Feb 2007 21:07:03 +0000 Subject: [PATCH] some useless Ruby scripts Originally committed to SVN as r932. --- automation/demos/k-replacer.rb | 69 +++++++++++++++++++++++++ automation/include/karaoke.rb | 68 +++++++++++++++++++++++++ automation/include/utils.rb | 92 ++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 automation/demos/k-replacer.rb create mode 100644 automation/include/karaoke.rb create mode 100644 automation/include/utils.rb diff --git a/automation/demos/k-replacer.rb b/automation/demos/k-replacer.rb new file mode 100644 index 000000000..de13e563c --- /dev/null +++ b/automation/demos/k-replacer.rb @@ -0,0 +1,69 @@ +load 'karaoke.rb' +load 'utils.rb' + +include Aegisub + +$script_name = "k-replacer test" +$script_description = "k-replacer test" +$script_author = "Pomyk" +$script_version = "1" + +register_macro("Simple k-replacer", "k-replacer macro", :k_replace_macro, nil) +register_filter("Simple k-replacer", "k-replacer filter", 100, :k_replace_filter, :k_replace_cfg) + + +def k_replace_macro(subs, sel, act) + + cfg = k_replace_cfg(subs, nil) + ok, opt = display_dialog(cfg, nil) + return if not ok # cancelled +# write_options(subs, $script_name, opt) + i = 0 + subs.each do |l| + i += 1 + k_replace(l, opt[:templ], opt[:strip]) if l[:class] == :dialogue && # replace if its dialogue + (opt[:style] =="" || l[:style] == opt[:style]) # and has the right style + end + return subs +rescue Exception + debug_out($!.inspect << "\n" << caller.join("\n")) + return nil +end + +def k_replace_filter(subs, opt) + subs.each do |l| + k_replace(l, opt[:templ], opt[:strip]) if l[:class] == :dialogue && # replace if its dialogue + opt[:style] =="" || l[:style] == opt[:style] # and has the right style + end + return subs +rescue Exception + debug_out($!.inspect << "\n" << caller.join("\n")) + return nil +end + +def k_replace_cfg(subs, store) + styles = [] + subs.each { |l| # read style names + styles << l[:name] if l[:class] == :style + break if l[:class] == :dialogue + } + header_text = <<-head +Expressions are enclosed in % pairs. +Variables: + $start = Start-time of syllable (ms) + $end = End-time of syllable (ms) + $mid = Time midways through the syllable (ms) + $dur = Duration of syllable (cs) +Calculation example: + \\t($start,%$start+$dur*2%,\\fscx110) + \\t(%$start+$dur*2%,$end,\\fscx90) +head + opt = read_options(subs, $script_name) + cfg = ScriptCfg.new # helper class for building dialogs + cfg.header header_text, :x => 1, :width => 1 + cfg.edit :templ, "template", :text => opt[:templ] + cfg.dropdown :style, "Style", :items => styles, :value => opt[:style] + cfg.checkbox :strip, "", :label => "Strip tags?", :value => (opt[:strip] == "true" ? true : false) + cfg.to_ary # convert to array +end + diff --git a/automation/include/karaoke.rb b/automation/include/karaoke.rb new file mode 100644 index 000000000..1840f9907 --- /dev/null +++ b/automation/include/karaoke.rb @@ -0,0 +1,68 @@ +module Aegisub + + + # parsing karaoke line + # should work more or less like the lua version + # input: dialogue line with karaoke tags + # output: number of syllables in karaoke + def parse_karaoke(line) + return 0 if line[:class] != :dialogue + return line[:karaoke].size if line[:karaoke].class == Array + karaoke = [] + time = 0 + line[:text].scan(/(?:{.*?\\(K|k[fto]?)(\d+).*?}([^{]*))|({.*?})([^{]*)/) do |k| + if $1 # karaoke tag + ktag = $1 + kdur = $2.to_i + syl = Hash.new + syl[:start_time] = time + if ktag == 'kt' + time = kdur*10 + syl[:duration] = 0 + else + time += kdur*10 + syl[:duration] = kdur + end + syl[:end_time] = time + syl[:tag] = ktag + syl[:text] = $& + syl[:text_stripped] = $3 + karaoke << syl + else # no karaoke - append to the last syllable + tag = $4 + text = $5 + if not karaoke.empty? + karaoke.last[:text] << tag << text + karaoke.last[:text_stripped] << text if text and tag !~ /\\p\d/ # no drawings + end + end + end + line[:karaoke] = karaoke + return karaoke.size + end + + # replaces matched pattern in the line with an evaluated template + # input: line, template (string), strip (bool), pattern (regexp or string) + # output: line with karaoke effect + def k_replace(line, template, strip, pattern = /\\(:?K|k[fo]?\d+)/) # default pattern = any karaoke tag + return if parse_karaoke(line) == 0 + + res = "" + t = template.gsub(/\$(start|end|dur|mid|text|i|kind)/, '_\1') + _i = 0 + line[:karaoke].each do |s| + _start = s[:start_time] + _end = s[:end_time] + _dur = s[:duration] + _mid = _start + _dur*5 + _text = s[:text_stripped] + _kind = s[:tag] + ev = t.gsub(/(_(:?start|end|dur|mid|text|i|kind))/) { |m| eval($1).to_s } # evalute variables + ev.gsub!(/\%([^%]+)\%/) { |m| eval($1).to_s } # evaluate expressions + res << (strip ? "{" << ev << "}" << s[:text_stripped] : s[:text].gsub!(pattern, ev) ) + _i += 1 + end + line[:text] = res + end + +end diff --git a/automation/include/utils.rb b/automation/include/utils.rb new file mode 100644 index 000000000..da39d5206 --- /dev/null +++ b/automation/include/utils.rb @@ -0,0 +1,92 @@ +include Aegisub + +class Object + def deep_clone + Marshal.load(Marshal.dump(self)) + end +end + + + +module Aegisub + + class ScriptCfg + def initialize # constructor + @opt = [] + @x = 0 + @y = 0 + @labels = true + @width = 1 # TODO + @height = 1 + end + + private + def control(type, name, opt = {}) + @opt << {:class => type, :name => name, :x => @x, :y => @y, + :width => 1, :height => 1}.merge!(opt) + end + + # some meta-programming :] + def self.create_functions(*arr) + arr.each do |a| + class_eval(%Q[ + def #{a.to_s}(name, text, opt = {}) + if @labels; label text, opt; @x += 1; end + control "#{a.to_s}", name, opt + @y += 1 + @x = 0 + end + ]) + end + end + + public + create_functions *[:edit, :intedit, :floatedit, :textbox, + :dropdown, :checkbox, :color, :coloralpha, :alpha ] + + def no_labels; @labels = false; end + + def label(text, opt = {}) + control :label, text, opt.merge({:label => text}) + end + + def header(text, opt = {}) + label text, opt.merge!({:width => 2}) + @y += 1 + end + + def to_ary # conversion to array + @opt + end + + end + + # inserts line with options into the file + def write_options(subs, name, opt, sep = "~~") + i = 0 + while subs[i][:class] != :info do + i += 1 + end + while subs[i][:class] == :info do + i += 1 + end + l = {:class => :info, :key => name, :value => opt.to_a.flatten!.join(sep), :section => "[Script Info]"} + subs = subs.insert(i, l) + end + + # returns hash with options loaded from the subs + def read_options(subs, name, sep = "~~") + i = 0 + i += 1 while subs[i][:class] != :info + i += 1 while subs[i][:class] == :info && subs[i][:key] != name + return {} if subs[i][:class] != :info + a = subs[i][:value].split(sep) + h = {} + (a.size/2).times do |j| + h[a[2*j].to_sym] = a[2*j+1] + end + return h + end + +end +