summaryrefslogtreecommitdiff
path: root/lib/menubar/index_theme.lua
blob: 633964af73a83d693a7f459b725494a7f281af82 (plain)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
---------------------------------------------------------------------------
--- Class module for parsing an index.theme file
--
-- @author Kazunobu Kuriyama
-- @copyright 2015 Kazunobu Kuriyama
-- @classmod menubar.index_theme
---------------------------------------------------------------------------

-- This implementation is based on the specifications:
--  Icon Theme Specification 0.12
--  http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-0.12.html

local ipairs = ipairs
local setmetatable = setmetatable
local string = string
local table = table
local io = io

-- index.theme groups
local ICON_THEME = "Icon Theme"
-- index.theme keys
local DIRECTORIES = "Directories"
local INHERITS = "Inherits"
-- per-directory subkeys
local TYPE = "Type"
local SIZE = "Size"
local MINSIZE = "MinSize"
local MAXSIZE = "MaxSize"
local THRESHOLD = "Threshold"

local index_theme = { mt = {} }

--- Class constructor of `index_theme`
-- @tparam table cls Metatable that will be used. Should always be `index_theme.mt`.
-- @tparam string icon_theme_name Internal name of icon theme
-- @tparam table base_directories Paths used for lookup
-- @treturn table An instance of the class `index_theme`
index_theme.new = function(cls, icon_theme_name, base_directories)
    local self = {}
    setmetatable(self, { __index = cls })

    -- Initialize the fields
    self.icon_theme_name = icon_theme_name
    self.base_directory = nil
    self[DIRECTORIES] = {}
    self[INHERITS] = {}
    self.per_directory_keys = {}

    -- base_directory
    local basedir = nil
    local handler = nil
    for _, dir in ipairs(base_directories) do
        basedir = dir .. "/" .. self.icon_theme_name
        handler = io.open(basedir .. "/index.theme", "r")
        if handler then
            -- Use the index.theme which is found first.
            break
        end
    end
    if not handler then
        return self
    end
    self.base_directory = basedir

    -- Parse index.theme.
    while true do
        local line = handler:read()
        if not line then
            break
        end

        local group_header = "^%[(.+)%]$"
        local group = line:match(group_header)
        if group then
            if group == ICON_THEME then
                while true do
                    local item = handler:read()
                    if not item then
                        break
                    end
                    if item:match(group_header) then
                        handler:seek("cur", -string.len(item) - 1)
                        break
                    end

                    local k, v = item:match("^(%w+)=(.*)$")
                    if k == DIRECTORIES or k == INHERITS then
                        string.gsub(v, "([^,]+),?", function(match)
                            table.insert(self[k], match)
                        end)
                    end
                end
            else
                -- This must be a 'per-directory keys' group
                local keys = {}

                while true do
                    local item = handler:read()
                    if not item then
                        break
                    end
                    if item:match(group_header) then
                        handler:seek("cur", -string.len(item) - 1)
                        break
                    end

                    local k, v = item:match("^(%w+)=(%w+)$")
                    if k == SIZE or k == MINSIZE or k == MAXSIZE or k == THRESHOLD then
                        keys[k] = tonumber(v)
                    elseif k == TYPE then
                        keys[k] = v
                    end
                end

                -- Size is a must.  Other keys are optional.
                if keys[SIZE] then
                    -- Set unset keys to the default values.
                    if not keys[TYPE] then keys[TYPE] = THRESHOLD end
                    if not keys[MINSIZE] then keys[MINSIZE] = keys[SIZE] end
                    if not keys[MAXSIZE] then keys[MAXSIZE] = keys[SIZE] end
                    if not keys[THRESHOLD] then keys[THRESHOLD] = 2 end

                    self.per_directory_keys[group] = keys
                end
            end
        end
    end

    handler:close()

    return self
end

--- Table of the values of the `Directories` key
-- @treturn table Values of the `Directories` key
index_theme.get_subdirectories = function(self)
    return self[DIRECTORIES]
end

--- Table of the values of the `Inherits` key
-- @treturn table Values of the `Inherits` key
index_theme.get_inherits = function(self)
    return self[INHERITS]
end

--- Query (part of) per-directory keys of a given subdirectory name.
-- @tparam table subdirectory Icon theme's subdirectory
-- @treturn[1] string Value of the `Type` key
-- @treturn[2] number Value of the `Size` key
-- @treturn[3] number VAlue of the `MinSize` key
-- @treturn[4] number Value of the `MaxSize` key
-- @treturn[5] number Value of the `Threshold` key
function index_theme:get_per_directory_keys(subdirectory)
    local keys = self.per_directory_keys[subdirectory]
    return keys[TYPE], keys[SIZE], keys[MINSIZE], keys[MAXSIZE], keys[THRESHOLD]
end

index_theme.mt.__call = function(cls, icon_theme_name, base_directories)
    return index_theme.new(cls, icon_theme_name, base_directories)
end

return setmetatable(index_theme, index_theme.mt)

-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80