summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOpportunity <[email protected]>2020-01-16 17:03:20 +0800
committerOpportunity <[email protected]>2020-01-16 17:03:20 +0800
commitd5f108398a0b638f60aaab8089831bb9e67023c4 (patch)
tree4756301fbfd20abfb6373f913a060d6290a21a6e
parentd72f0495c5a8b860e7abed729f0d874542653066 (diff)
add table
-rw-r--r--xmake/core/base/cli.lua72
-rw-r--r--xmake/core/base/colors.lua77
-rw-r--r--xmake/core/base/option.lua204
-rw-r--r--xmake/core/base/text.lua370
-rw-r--r--xmake/core/sandbox/modules/import/core/base/text.lua38
5 files changed, 462 insertions, 299 deletions
diff --git a/xmake/core/base/cli.lua b/xmake/core/base/cli.lua
index 9ce43500b..310335fd4 100644
--- a/xmake/core/base/cli.lua
+++ b/xmake/core/base/cli.lua
@@ -117,78 +117,6 @@ function cli.parsev(argv, flags)
return parsed
end
--- @see https://unicode.org/reports/tr14/
-function cli._lastwbr(str, width, wordbreak)
-
- -- check
- assert(#str >= width)
-
- if wordbreak == "breakall" then
- -- To prevent overflow, word may be broken at any character
- return width
- else
-
- if str:sub(width + 1, width + 1):find("[%s]") then
- -- exact break
- return width
- end
-
- local range = str:sub(1, width)
- local poss = range:reverse():find("[%s-]")
- if poss then
- return #range - poss + 1
- end
-
- -- not found in range, try afterwards
- poss = str:find("[%s-]", width + 1)
- if poss then
- return poss
- end
-
- -- not found in all str
- return #str
- end
-end
-
--- break lines
-function cli.wordwrap(str, width, opt)
-
- opt = opt or {}
-
- -- split to lines
- if type(str) == 'table' then
- str = table.concat(str, '\n')
- end
- local lines = tostring(str):split('\n', {plain = true, strict = true})
-
- local result = {}
- -- handle lines
- for _, v in ipairs(lines) do
-
- -- remove tailing spaces, include '\r', which will be produced by `('l1\r\nl2'):split(...)`
- v = v:rtrim()
- while #v > width do
-
- -- find word break chance
- local wbr = cli._lastwbr(v, width, opt.wordbreak)
-
- -- break line
- local line = v:sub(1, wbr):rtrim()
- table.insert(result, line)
- v = v:sub(wbr + 1):ltrim()
-
- -- prevent empty line
- if #v == 0 then v = nil end
- end
-
- -- put remaining parts
- table.insert(result, v)
- end
-
- -- ok
- return result
-end
-
cli._segment = segment
-- return module
return cli
diff --git a/xmake/core/base/colors.lua b/xmake/core/base/colors.lua
index de66a9414..c49191cd1 100644
--- a/xmake/core/base/colors.lua
+++ b/xmake/core/base/colors.lua
@@ -442,83 +442,6 @@ function colors.ignore(str)
return colors.translate(str, {plain = true})
end
--- make a table with colors
---
--- @param data table data, array of array of strings with colors, eg: {{"1", "2", "3"}, {"4", "5", "6"}}
--- @param opt options
--- plain: false
--- sep: table colunm sepertor, default is ' | '
--- colunms: colunm attributes, eg: {{align = 'left', min_width = 80}, {align = 'center'}, {align = 'right', min_width = 120}}
-function colors.table(data, opt)
-
- assert(data)
-
- -- init options
- opt = opt or {}
- if opt.sep == nil then opt.sep = ' | ' end
- opt.patch_reset = true
- opt.ignore_unknown = true
- local sep = colors.translate(opt.sep, opt)
-
- -- formartted cells
- local tab = {}
- local col_width = {}
- -- 'l' 'r' 'c'
- local col_align = {}
-
- -- load column options
- if opt.colunms then
- for i = 1, table.maxn(opt.colunms or {}) do
- local v = opt.colunms[i] or {}
- col_width[i] = v.min_width or 0
- col_align[i] = (v.align or 'l'):sub(1, 1):lower()
- end
- end
-
- -- format cells
- for i, row in ipairs(data) do
- tab[i] = {}
- for j, cell in ipairs(row) do
- local str = tostring(cell)
- local value = colors.translate(str, opt)
- local len = opt.plain and #value or #colors.ignore(str)
- tab[i][j] = { str = value, len = len }
- col_width[j] = math.max(len, col_width[j] or 0)
- end
- end
-
- -- render cells
- local empty_cell = { str = "", len = 0 }
- local rows = {}
- for i, row in ipairs(tab) do
- local cells = {}
- for j = 1, #col_width do
-
- -- use empty cell if not defined
- local cell = row[j] or empty_cell
-
- if col_align[j] == 'r' then
- -- right align
- cells[j] = string.rep(' ', col_width[j] - cell.len) .. cell.str
- elseif col_align[j] == 'c' then
- -- centered
- local padding = col_width[j] - cell.len
- local lp = math.floor(padding / 2)
- local rp = math.ceil(padding / 2)
- cells[j] = string.rep(' ', lp) .. cell.str .. string.rep(' ', rp)
- else
- --left align, emit tailing spaces for last colunm
- cells[j] = cell.str .. ((j == #col_width) and "" or string.rep(' ', col_width[j] - cell.len))
- end
- end
- rows[i] = table.concat(cells, sep)
- end
-
- -- concat rendered rows
- rows[#rows + 1] = ""
- return table.concat(rows, '\n')
-end
-
-- get theme
function colors.theme()
return colors._THEME
diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua
index a862a2d40..b9721edec 100644
--- a/xmake/core/base/option.lua
+++ b/xmake/core/base/option.lua
@@ -25,6 +25,7 @@ local option = option or {}
local cli = require("base/cli")
local table = require("base/table")
local colors = require("base/colors")
+local text = require("base/text")
-- ifelse, a? b : c
function option._ifelse(a, b, c)
@@ -69,51 +70,6 @@ function option._context()
end
end
--- get line length
-function option._get_linelen(st)
- local poss = st:reverse():find("\n")
- if not poss then return (#st) end
- local start_pos, _ = poss
- return start_pos - 1
-end
-
--- get last space
-function option._get_lastspace(st)
- local poss = st:reverse():find("[%s-]")
- if not poss then return (#st) end
- local start_pos, _ = poss
- return (#st) - start_pos + 1
-end
-
--- append spaces in width
-function option._inwidth_append(dst, st, padding, width, remain_width)
-
- if padding >= width then
- return dst .. st
- end
-
- local white_padding = string.rep(" ", padding)
- if remain_width == nil then
- -- TODO because of colored string, it's wrong sometimes
- remain_width = width - option._get_linelen(dst)
- end
-
- if remain_width <= 0 then
- return option._inwidth_append(dst .. "\n" .. white_padding, st, padding, width, width - padding)
- end
-
- if (#st) <= remain_width then
- return dst .. st
- end
-
- local lastspace = option._get_lastspace(st:sub(1, remain_width))
- if lastspace + 1 > (#st) then
- return dst .. st
- else
- return option._inwidth_append(dst .. st:sub(1, lastspace) .. "\n" .. white_padding, st:sub(lastspace + 1):ltrim(), padding, width, width - padding)
- end
-end
-
-- save context
function option.save(taskname)
@@ -633,7 +589,7 @@ function option.show_menu(task)
if taskmenu.options then
option.show_options(taskmenu.options, task)
end
-end
+end
-- show the main menu
function option.show_main()
@@ -710,30 +666,26 @@ function option.show_main()
-- print category name
table.insert(tablecontent, {})
- table.insert(tablecontent, {string.format("${bright}%s%ss: ", string.sub(category.name, 1, 1):upper(), string.sub(category.name, 2))})
-
- -- the padding spaces
- local padding = 42
-
- -- get width of right colunm
- local right_width = math.max(os.getwinsize().width, 60) - 41
+ table.insert(tablecontent, {{string.format("%s%ss: ", string.sub(category.name, 1, 1):upper(), string.sub(category.name, 2)), style="${reset bright}"}})
-- print tasks
for taskname, taskinfo in pairs(category.tasks) do
-- init the task line
- local taskline = string.format("${color.menu.main.task.name} %s%s",
+ local taskline = string.format(" %s%s",
taskinfo.shortname and (taskinfo.shortname .. ", ") or " ",
taskname)
-
- local taskdesc = cli.wordwrap(taskinfo.description or "", right_width)
- table.insert(tablecontent, {taskline, taskdesc[1]})
- for i = 2, #taskdesc do
- table.insert(tablecontent, {"", taskdesc[i]})
- end
+ table.insert(tablecontent, {taskline, taskinfo.description or ""})
end
end
- io.write(colors.table(tablecontent, {sep = " ", colunms = {{min_width=40}, {}}}))
+
+ -- set table styles
+ tablecontent.style = {"${color.menu.main.task.name}"}
+ tablecontent.width = {nil, "auto"}
+ tablecontent.sep = " "
+
+ -- print table
+ io.write(text.table(tablecontent))
end
-- print options
@@ -748,9 +700,6 @@ function option.show_options(options, taskname)
-- check
assert(options)
- -- the padding spaces
- local padding = 42
-
-- remove repeat empty lines
local is_action = false
local emptyline_count = 0
@@ -769,27 +718,28 @@ function option.show_options(options, taskname)
end
end
+ local tablecontent = {}
+
-- print header
- io.print("")
+ table.insert(tablecontent, {})
if is_action then
- io.print(colors.translate("${bright}Common options: "))
+ table.insert(tablecontent, {{"Common options:", style="${reset bright}"}})
else
- io.print(colors.translate("${bright}Options: "))
+ table.insert(tablecontent, {{"Options:", style="${reset bright}"}})
end
-- print options
- options = printed_options
- for _, opt in ipairs(options) do
+ for _, opt in ipairs(printed_options) do
-- the following options are belong action? show command section
--
-- @see core/base/task.lua: translate menu
--
if opt.category and opt.category == "action" then
- io.print("")
- io.print(colors.translate("${bright}Command options (" .. taskname .. "): "))
+ table.insert(tablecontent, {})
+ table.insert(tablecontent, {{"Command options(" .. taskname .. "):", style="${reset bright}"}})
end
-
+
-- init the option info
local option_info = ""
@@ -821,104 +771,58 @@ function option.show_options(options, taskname)
option_info = option_info .. " ..."
end
- -- append spaces
- for i = (#option_info), padding do
- option_info = option_info .. " "
+ -- get description
+ local description = table.move(opt, 5, table.maxn(opt), 1, {})
+ if #description == 0 then
+ description[1] = ""
end
- -- append color
- option_info = colors.translate("${color.menu.option.name}" .. option_info .. "${clear}")
-
- -- get width of console
- local console_width = math.max(os.getwinsize().width, 80)
-
- -- append the option description
- local description = opt[5]
- if description then
- option_info = option._inwidth_append(option_info, description, padding + 1, console_width, console_width - padding - 1)
+ -- transform description
+ local desp_strs = {}
+ for _, v in ipairs(description) do
+ if type(v) == "function" then
+ v = v()
+ end
+ if type(v) == "string" then
+ table.insert(desp_strs, v)
+ elseif type(v) == "table" then
+ table.move(v, 1, #v, #desp_strs + 1, desp_strs)
+ end
end
-- append the default value
if default then
local defaultval = tostring(default)
if type(default) == "boolean" then
- defaultval = option._ifelse(default, "y", "n")
+ defaultval = default and "y" or "n"
end
- option_info = option._inwidth_append(option_info, " (default: ", padding + 1, console_width)
- local origin_width = option._get_linelen(option_info)
- option_info = option_info .. "${bright}"
- option_info = option._inwidth_append(option_info, defaultval, padding + 1, console_width, console_width - origin_width)
- origin_width = option._ifelse(origin_width + #defaultval > console_width, option._get_linelen(option_info), origin_width + (#(tostring(default))))
- option_info = option_info .. "${clear}"
- option_info = option._inwidth_append(option_info, ")", padding + 1, console_width, console_width - origin_width)
+ local def_desp = colors.translate(string.format(" (default: ${bright}%s${clear})", defaultval))
+ desp_strs[1] = desp_strs[1] .. def_desp
end
- -- print option info
- io.print(colors.translate(option_info))
-
- -- print more description if exists
- for i = 6, 64 do
-
- -- the description, @note some option may be nil
- local description = opt[i]
- if not description then break end
-
- -- is function? get results
- if type(description) == "function" then
- description = description()
- end
-
- -- the description is string?
- if type(description) == "string" then
-
- -- make spaces
- local spaces = ""
- for i = 0, padding do
- spaces = spaces .. " "
- end
-
- -- print this description
- io.print(option._inwidth_append(spaces, description, padding + 1, console_width))
-
- -- the description is table?
- elseif type(description) == "table" then
-
- -- print all descriptions
- for _, v in pairs(description) do
-
- -- make spaces
- local spaces = ""
- for i = 0, padding do
- spaces = spaces .. " "
- end
-
- -- print this description
- io.print(option._inwidth_append(spaces, v, padding + 1, console_width))
- end
- end
- end
-
- -- print values
+ -- append values
local values = opt.values
if type(values) == "function" then
values = values()
end
if values then
-
for _, value in ipairs(table.wrap(values)) do
-
- -- make spaces
- local spaces = ""
- for i = 0, padding do
- spaces = spaces .. " "
- end
-
- -- print this value
- io.print(option._inwidth_append(spaces, " - " .. tostring(value), padding + 1, console_width))
+ table.insert(desp_strs, " - " .. tostring(value))
end
end
+
+ -- insert row
+ table.insert(tablecontent, {option_info, desp_strs})
end
-end
+
+ -- set table styles
+ tablecontent.style = {"${color.menu.option.name}"}
+ tablecontent.width = {nil, "auto"}
+ tablecontent.sep = " "
+
+ -- print table
+ io.write(text.table(tablecontent))
+end
-- return module: option
return option
diff --git a/xmake/core/base/text.lua b/xmake/core/base/text.lua
new file mode 100644
index 000000000..462c757a1
--- /dev/null
+++ b/xmake/core/base/text.lua
@@ -0,0 +1,370 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-2020, TBOOX Open Source Group.
+--
+-- @author OpportunityLiu
+-- @file text.lua
+--
+
+-- define module
+local text = text or {}
+
+-- load modules
+local string = require("base/string")
+local colors = require("base/colors")
+local math = require("base/math")
+local dump = require("base/dump")
+
+-- @see https://unicode.org/reports/tr14/
+function text._lastwbr(str, width, wordbreak)
+
+ -- check
+ assert(#str >= width)
+
+ if wordbreak == "breakall" then
+ -- To prevent overflow, word may be broken at any character
+ return width
+ else
+
+ if str:sub(width + 1, width + 1):find("[%s]") then
+ -- exact break
+ return width
+ end
+
+ local range = str:sub(1, width)
+ local poss = range:reverse():find("[%s-]")
+ if poss then
+ return #range - poss + 1
+ end
+
+ -- not found in range, try afterwards
+ poss = str:find("[%s-]", width + 1)
+ if poss then
+ return poss
+ end
+
+ -- not found in all str
+ return #str
+ end
+end
+
+-- break lines
+function text.wordwrap(str, width, opt)
+
+ opt = opt or {}
+
+ -- split to lines
+ if type(str) == 'table' then
+ str = table.concat(str, '\n')
+ end
+ local lines = tostring(str):split('\n', {plain = true, strict = true})
+
+ local result = {}
+ local actual_width = 0
+
+ -- handle lines
+ for _, v in ipairs(lines) do
+
+ -- remove tailing spaces, include '\r', which will be produced by `('l1\r\nl2'):split(...)`
+ v = v:rtrim()
+
+ while #v > width do
+
+ -- find word break chance
+ local wbr = text._lastwbr(v, width, opt.wordbreak)
+
+ -- break line
+ local line = v:sub(1, wbr):rtrim()
+ actual_width = math.max(#line, actual_width)
+ table.insert(result, line)
+ v = v:sub(wbr + 1):ltrim()
+
+ -- prevent empty line
+ if #v == 0 then
+ v = nil
+ break
+ end
+ end
+
+ -- put remaining parts
+ if v then
+ actual_width = math.max(#v, actual_width)
+ table.insert(result, v)
+ end
+ end
+
+ -- ok
+ return result, actual_width
+end
+
+function text._format_cell(cell, width, opt)
+ local result = {}
+ local max_width = 0
+ for _, v in ipairs(cell) do
+ local lines, aw = text.wordwrap(tostring(v), width[2], opt)
+ table.move(lines, 1, #lines, #result + 1, result)
+ max_width = math.max(max_width, aw)
+ end
+ cell.formatted = result
+ cell.width = max_width
+end
+
+function text._format_col(col, width, opt)
+ local max_width = 0
+ for i = 1, table.maxn(col) do
+ local v = col[i]
+ -- skip span cells
+ if v and not v.span then
+ text._format_cell(v, width, opt)
+ max_width = math.max(max_width, v.width)
+ end
+ end
+ col.width = max_width
+end
+
+
+-- make a table with colors
+--
+-- @param data table data, array of array of cells with optional styles
+-- eg: {
+-- {"1", nil, "3"}, -- use nil to make previous cell to span next column
+-- {"4", "5", {"line1", "line2", style="${yellow}", align = 'r'}}, -- multi-line content & set style or align for cell
+-- {"7", "8", {"9", style="${reset}${red}"}, style="${bright}", align = 'c'}, -- set style or align for row
+-- style = {"${underline}"}, -- set style for columns
+-- -- or use "${underline}" for all columns
+-- width = { 20, {10, 50}, "auto"},
+-- -- 2 numbers - min and max width (nil for not set, eg: {nil, 50});
+-- -- a number - width, num is equivalent to {num, num};
+-- -- nil - no limit, equivalent to {nil, nil}
+-- -- "auto" - use remain space of console, only one 'auto' colunm is allowed
+-- align = {'l', 'r', 'c'} -- align mode for each column, 'left', 'center' or 'right'
+-- sep = "${dim} | ", -- table colunm sepertor, default is ' | ', use '' to hide
+-- }
+-- priority of style and align: cell > row > col
+-- @param opt options for color rendering and word warpping
+function text.table(data, opt)
+
+ assert(data)
+
+ -- init options
+ opt = opt or { patch_reset = false, ignore_unknown = true }
+ opt.patch_reset = false
+ local sep = colors.translate(data.sep or ' | ', opt)
+ local sep_len = #colors.ignore(data.sep or ' | ', opt)
+
+ -- col ordered cells
+ local cols = {}
+ local n_row = table.maxn(data)
+ local n_col = 1
+
+ -- count cols
+ for i = 1, n_row do
+ local row = data[i]
+ if row == nil then
+ data[i] = {{""}}
+ else
+ n_col = math.max(n_col, table.maxn(row))
+ end
+ end
+
+ -- reorder
+ for i = 1, n_row do
+ local row = data[i]
+ local p_cell = nil
+ for j = 1, n_col do
+ local cell = row[j]
+ if cell ~= nil and type(cell) ~= "table" then
+ -- wrap cells if needed
+ cell = {tostring(cell)}
+ elseif cell == nil and j == 1 then
+ cell = {""}
+ end
+ local col = cols[j]
+ if not col then
+ col = {}
+ cols[j] = col
+ end
+ if cell then
+ col[i] = cell
+ p_cell = cell
+ else
+ p_cell.span = (p_cell.span or 1) + 1
+ end
+ end
+ end
+
+ -- load column options
+ data.width = data.width or {}
+ data.align = data.align or {}
+ data.style = data.style or {}
+
+ local style = ""
+ if type(data.style) == "string" then
+ style = data.style
+ data.style = {}
+ end
+
+ -- index of auto col
+ local auto_col = nil
+ for i = 1, n_col do
+
+ -- load width
+ local w = data.width[i]
+ if w ~= "auto" then
+ local wl, wu
+ if w == nil then
+ wl, wu = 0, math.huge
+ elseif type(w) == 'number' then
+ if math.isnan(w) or math.isinf(w) then
+ wl, wu = 0, math.huge
+ else
+ wl, wu = w, w
+ end
+ else
+ wl, wu = w[1], w[2]
+ end
+ wl = wl or 0
+ wu = wu or math.huge
+ data.width[i] = {wl, wu}
+ else
+ assert(not auto_col, 'Only one "auto" colunm is allowed.')
+ auto_col = i
+ end
+
+ -- load align
+ cols[i].align = (data.align[i] or 'l'):sub(1, 1):lower()
+ -- load style
+ cols[i].style = data.style[i] or style
+ end
+
+ -- format table
+
+ -- 1. format non-auto cols
+ for i, col in ipairs(cols) do
+ if i ~= auto_col then
+ text._format_col(col, data.width[i], opt)
+ end
+ end
+
+ if auto_col then
+
+ -- 2. caculate auto col width
+ local auto_width = os.getwinsize().width
+ for i = 1, n_col do
+ if i ~= auto_col then
+ auto_width = auto_width - cols[i].width
+ end
+ end
+ auto_width = math.max(0, auto_width - sep_len * (n_col - 1))
+ data.width[auto_col] = {0,auto_width}
+
+ -- 3. format auto col
+ text._format_col(cols[auto_col], data.width[auto_col], opt)
+ end
+
+ -- 4. format span cell
+ for i, col in ipairs(cols) do
+
+ for j = 1, n_row do
+ local cell = col[j]
+ if cell and cell.span then
+ local w, wl = 0, 0
+ for ci = 0, (cell.span - 1) do
+ -- actual width of spanned cols
+ w = w + cols[i + ci].width
+ -- min width of spanned cols
+ wl = wl + data.width[i + ci][1]
+ end
+ text._format_cell(cell, {0, math.max(w, wl) + sep_len * (cell.span - 1)}, opt)
+ end
+ end
+ end
+
+ -- render cells
+
+ -- row ordered cells
+ local rows = {}
+
+ -- reorder
+ for i = 1, n_row do
+ local row = {}
+ local line = 1
+ for j = 1, n_col do
+ local cell = cols[j][i]
+ if cell then
+ assert(cell.formatted)
+ line = math.max(#cell.formatted, line)
+ end
+ row[j] = cell
+ end
+ row.line = line
+ rows[i] = row
+ end
+
+ local results = {}
+ local reset = colors.translate("${reset}", opt)
+ for i, row in ipairs(rows) do
+ for l = 1, row.line do
+ local cells = {}
+ local j = 1
+ while j <= n_col do
+
+ local cell = row[j]
+ assert(cell)
+ local col = cols[j]
+
+ if l == 1 then
+ cell.align = cell.align or row.align or col.align
+ cell.style = colors.translate((col.style or "") .. (row.style or "") .. (cell.style or ""), opt)
+ end
+
+ local str = cell.formatted[l] or ""
+ local width = col.width
+ local span = cell.span or 1
+ if cell.span then
+ for ci = (j + 1), (j + span - 1) do
+ width = width + cols[ci].width
+ end
+ width = width + sep_len * (span - 1)
+ end
+
+ local padded
+ if cell.align == 'r' then
+ -- right align
+ padded = string.rep(' ', width - #str) .. str
+ elseif cell.align == 'c' then
+ -- centered
+ local padding = width - #str
+ local lp = math.floor(padding / 2)
+ local rp = math.ceil(padding / 2)
+ padded = string.rep(' ', lp) .. str .. string.rep(' ', rp)
+ else
+ --left align, emit tailing spaces for last colunm
+ padded = str .. ((j + span == n_col + 1) and "" or string.rep(' ', width - #str))
+ end
+ table.insert(cells, cell.style .. padded .. reset)
+ j = j + span
+ end
+ table.insert(results, table.concat(cells, sep))
+ end
+ end
+
+ -- concat rendered rows
+ results[#results + 1] = ""
+ return table.concat(results, '\n')
+end
+
+-- return module
+return text
diff --git a/xmake/core/sandbox/modules/import/core/base/text.lua b/xmake/core/sandbox/modules/import/core/base/text.lua
new file mode 100644
index 000000000..dbbc9eccc
--- /dev/null
+++ b/xmake/core/sandbox/modules/import/core/base/text.lua
@@ -0,0 +1,38 @@
+--!A cross-platform build utility based on Lua
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-- Copyright (C) 2015-2020, TBOOX Open Source Group.
+--
+-- @author OpportunityLiu
+-- @file text.lua
+--
+
+-- load modules
+local text = require("base/text")
+
+
+-- define module
+local sandbox_text = sandbox_text or {}
+
+-- inherit some builtin interfaces
+for key, value in pairs(text) do
+ if not key:startswith("_") then
+ sandbox_text[key] = value
+ end
+end
+
+-- return module
+return sandbox_text
+
+