-
Notifications
You must be signed in to change notification settings - Fork 0
/
ob_rmenu.rb
executable file
·121 lines (98 loc) · 2.73 KB
/
ob_rmenu.rb
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
121
#!/usr/bin/ruby
require 'pathname'
$menu_id = 0
def main(menu_file, icon_folder)
puts '<openbox_pipe_menu>'
print_menu(RMenu::get_menu(menu_file), get_icons(icon_folder))
puts '</openbox_pipe_menu>'
end
def print_menu(menu, icons)
menu.entries.each do |e|
$menu_id += 1
if e.instance_of? RMenu::Menu
puts '<menu%s id="%d" label="%s">' % [get_icon_string(e.name, icons), $menu_id, e.name.strip]
print_menu(e, icons)
puts '</menu>'
elsif e.instance_of? RMenu::Entry
name = e.value[/.*?(?=(?<!\\)=)/]
exec = e.value[/(?<=(?<!\\)=).*/]
exec.gsub!('$menu_folder', File.dirname(__FILE__)) unless exec.nil?
action = 'Execute'
if e.value.start_with? 'exec:'
name = name.gsub('exec:', '')
puts '<menu%s id="%d" label="%s" execute="%s"/>' % [get_icon_string(name, icons), $menu_id, name, exec]
else
if e.value.start_with? 'action:'
action = e.value.gsub(/^action:/, '')
name = action
end
puts '<item%s label="%s"><action name="%s">%s</action></item>' % [get_icon_string(name, icons), name, action, (exec.nil? ? "" : "<execute>#{to_xml(exec)}</execute>")]
end
elsif e.instance_of? RMenu::Separator
puts '<separator%s/>' % [e.name.nil? ? "" : ' label="%s"' % e.name]
end
end
end
def get_icons(icon_folder)
if not icon_folder.nil? and Pathname.new(icon_folder).directory?
return Pathname.new(icon_folder).children.collect do |file| [file, file.basename.to_s.downcase[/.*(?=\.[^\.]+)/]] end
else
return []
end
end
def get_icon_string(line, icons)
icons.each do |file, name|
if line.downcase.start_with? name or (line.start_with?('/', '~') and name == 'places')
return ' icon="%s"' % file
end
end
return ''
end
def to_xml(string)
return string.gsub('&', '&').gsub('"', '"')
end
module RMenu
class Separator
attr_reader :name
def initialize(name = nil)
@name = name
end
end
class Entry
attr_reader :value
def initialize(value)
@value = value
end
end
class Menu
attr_reader :name, :entries
def initialize(name)
@name, @entries = name, []
end
def add(entry)
@entries << entry
end
end
def self.get_menu(menu_file)
menus = Array.new
root = Menu.new('root')
menus[0] = root
File.open(menu_file).each_line.reject do |line| line.lstrip.start_with?('#') end.each do |line|
level = line.index(/[^\t ]/)
line.lstrip!
line.gsub!("\n", '')
if line.empty?
menus[level].add(Separator.new)
elsif line.start_with?('label:')
menus[level].add(Separator.new(line.sub(/^label:/, '')))
elsif line.start_with?('menu:')
menus[level + 1] = Menu.new(line.sub(/^menu:/, ''))
menus[level].add(menus[level + 1])
else
menus[level].add(Entry.new(line))
end
end
return root
end
end
main(ARGV[0], ARGV[1])