e51e2e5dfc53cf65efec889a018ca9ca0b3b6a11
[project/luci.git] / contrib / luadoc / lua / luadoc / util.lua
1 -------------------------------------------------------------------------------
2 -- General utilities.
3 -- @release $Id: util.lua,v 1.16 2008/02/17 06:42:51 jasonsantos Exp $
4 -------------------------------------------------------------------------------
5
6 local lfs = require "lfs"
7 local type, table, string, io, assert, tostring, setmetatable, pcall = type, table, string, io, assert, tostring, setmetatable, pcall
8
9 -------------------------------------------------------------------------------
10 -- Module with several utilities that could not fit in a specific module
11
12 module "luadoc.util"
13
14 -------------------------------------------------------------------------------
15 -- Removes spaces from the begining and end of a given string
16 -- @param s string to be trimmed
17 -- @return trimmed string
18
19 function trim (s)
20         return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
21 end
22
23 -------------------------------------------------------------------------------
24 -- Removes spaces from the begining and end of a given string, considering the
25 -- string is inside a lua comment.
26 -- @param s string to be trimmed
27 -- @return trimmed string
28 -- @see trim
29 -- @see string.gsub
30
31 function trim_comment (s)
32         s = string.gsub(s, "%-%-+(.*)$", "%1")
33         return trim(s)
34 end
35
36 -------------------------------------------------------------------------------
37 -- Checks if a given line is empty
38 -- @param line string with a line
39 -- @return true if line is empty, false otherwise
40
41 function line_empty (line)
42         return (string.len(trim(line)) == 0)
43 end
44
45 -------------------------------------------------------------------------------
46 -- Appends two string, but if the first one is nil, use to second one
47 -- @param str1 first string, can be nil
48 -- @param str2 second string
49 -- @return str1 .. " " .. str2, or str2 if str1 is nil
50
51 function concat (str1, str2)
52         if str1 == nil or string.len(str1) == 0 then
53                 return str2
54         else
55                 return str1 .. " " .. str2
56         end
57 end
58
59 -------------------------------------------------------------------------------
60 -- Split text into a list consisting of the strings in text,
61 -- separated by strings matching delim (which may be a pattern). 
62 -- @param delim if delim is "" then action is the same as %s+ except that 
63 -- field 1 may be preceeded by leading whitespace
64 -- @usage split(",%s*", "Anna, Bob, Charlie,Dolores")
65 -- @usage split(""," x y") gives {"x","y"}
66 -- @usage split("%s+"," x y") gives {"", "x","y"}
67 -- @return array with strings
68 -- @see table.concat
69
70 function split(delim, text)
71         local list = {}
72         if string.len(text) > 0 then
73                 delim = delim or ""
74                 local pos = 1
75                 -- if delim matches empty string then it would give an endless loop
76                 if string.find("", delim, 1) and delim ~= "" then 
77                         error("delim matches empty string!")
78                 end
79                 local first, last
80                 while 1 do
81                         if delim ~= "" then 
82                                 first, last = string.find(text, delim, pos)
83                         else
84                                 first, last = string.find(text, "%s+", pos)
85                                 if first == 1 then
86                                         pos = last+1
87                                         first, last = string.find(text, "%s+", pos)
88                                 end
89                         end
90                         if first then -- found?
91                                 table.insert(list, string.sub(text, pos, first-1))
92                                 pos = last+1
93                         else
94                                 table.insert(list, string.sub(text, pos))
95                                 break
96                         end
97                 end
98         end
99         return list
100 end
101
102 -------------------------------------------------------------------------------
103 -- Comments a paragraph.
104 -- @param text text to comment with "--", may contain several lines
105 -- @return commented text
106
107 function comment (text)
108         text = string.gsub(text, "\n", "\n-- ")
109         return "-- " .. text
110 end
111
112 -------------------------------------------------------------------------------
113 -- Wrap a string into a paragraph.
114 -- @param s string to wrap
115 -- @param w width to wrap to [80]
116 -- @param i1 indent of first line [0]
117 -- @param i2 indent of subsequent lines [0]
118 -- @return wrapped paragraph
119
120 function wrap(s, w, i1, i2)
121         w = w or 80
122         i1 = i1 or 0
123         i2 = i2 or 0
124         assert(i1 < w and i2 < w, "the indents must be less than the line width")
125         s = string.rep(" ", i1) .. s
126         local lstart, len = 1, string.len(s)
127         while len - lstart > w do
128                 local i = lstart + w
129                 while i > lstart and string.sub(s, i, i) ~= " " do i = i - 1 end
130                 local j = i
131                 while j > lstart and string.sub(s, j, j) == " " do j = j - 1 end
132                 s = string.sub(s, 1, j) .. "\n" .. string.rep(" ", i2) ..
133                         string.sub(s, i + 1, -1)
134                 local change = i2 + 1 - (i - j)
135                 lstart = j + change
136                 len = len + change
137         end
138         return s
139 end
140
141 -------------------------------------------------------------------------------
142 -- Opens a file, creating the directories if necessary
143 -- @param filename full path of the file to open (or create)
144 -- @param mode mode of opening
145 -- @return file handle
146
147 function lfs.open (filename, mode)
148         local f = io.open(filename, mode)
149         if f == nil then
150                 filename = string.gsub(filename, "\\", "/")
151                 local dir = ""
152                 for d in string.gfind(filename, ".-/") do
153                         dir = dir .. d
154                         lfs.mkdir(dir)
155                 end
156                 f = io.open(filename, mode)
157         end
158         return f
159 end
160
161
162 ----------------------------------------------------------------------------------
163 -- Creates a Logger with LuaLogging, if present. Otherwise, creates a mock logger.
164 -- @param options a table with options for the logging mechanism
165 -- @return logger object that will implement log methods
166
167 function loadlogengine(options)
168         local logenabled = pcall(function()
169                 require "logging"
170                 require "logging.console"
171         end)
172         
173         local logging = logenabled and logging
174         
175         if logenabled then
176                 if options.filelog then
177                         logger = logging.file("luadoc.log") -- use this to get a file log
178                 else
179                         logger = logging.console("[%level] %message\n")
180                 end
181         
182                 if options.verbose then
183                         logger:setLevel(logging.INFO)
184                 else
185                         logger:setLevel(logging.WARN)
186                 end
187                 
188         else
189                 noop = {__index=function(...)
190                         return function(...)
191                                 -- noop
192                         end
193                 end}
194                 
195                 logger = {} 
196                 setmetatable(logger, noop)
197         end
198         
199         return logger
200 end
201