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