Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stevedonovan/Penlight.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThijs Schreijer <thijs@thijsschreijer.nl>2021-12-31 17:15:44 +0300
committerThijs Schreijer <thijs@thijsschreijer.nl>2022-01-01 00:58:10 +0300
commit7bb357f36e15252ea9f5615b731c7fc4370c598f (patch)
treec3ad0ac93581efb0b9fca5625f8726b17de7f5b9
parent62d737a332af5976503b499d8c65bf48298bf7ed (diff)
chore(docs) update docs of the 'text' module
-rw-r--r--lua/pl/text.lua206
1 files changed, 114 insertions, 92 deletions
diff --git a/lua/pl/text.lua b/lua/pl/text.lua
index e626e86..1ebdd29 100644
--- a/lua/pl/text.lua
+++ b/lua/pl/text.lua
@@ -6,15 +6,6 @@
--
-- See @{03-strings.md.String_Templates|the Guide}.
--
--- Calling `text.format_operator()` overloads the % operator for strings to give Python/Ruby style formated output.
--- This is extended to also do template-like substitution for map-like data.
---
--- > require 'pl.text'.format_operator()
--- > = '%s = %5.3f' % {'PI',math.pi}
--- PI = 3.142
--- > = '$name = $value' % {name='dog',value='Pluto'}
--- dog = Pluto
---
-- Dependencies: `pl.utils`, `pl.types`
-- @module pl.text
@@ -24,6 +15,7 @@ local utils = require 'pl.utils'
local bind1,usplit,assert_arg = utils.bind1,utils.split,utils.assert_arg
local is_callable = require 'pl.types'.is_callable
local unpack = utils.unpack
+local pack = utils.pack
local text = {}
@@ -48,9 +40,9 @@ local function _indent (s,sp)
end
--- indent a multiline string.
--- @param s the string
--- @param n the size of the indent
--- @param ch the character to use when indenting (default ' ')
+-- @tparam string s the (multiline) string
+-- @tparam integer n the size of the indent
+-- @tparam[opt=' '] string ch the character to use when indenting
-- @return indented string
function text.indent (s,n,ch)
assert_arg(1,s,'string')
@@ -60,7 +52,7 @@ end
--- dedent a multiline string by removing any initial indent.
-- useful when working with [[..]] strings.
--- @param s the string
+-- @tparam string s the (multiline) string
-- @return a string with initial indent zero.
function text.dedent (s)
assert_arg(1,s,'string')
@@ -73,10 +65,11 @@ end
--- format a paragraph into lines so that they fit into a line width.
-- It will not break long words, so lines can be over the length
-- to that extent.
--- @param s the string
--- @param width the margin width, default 70
--- @return a list of lines (List object)
+-- @tparam string s the string to format
+-- @tparam[opt=70] integer width the margin width
+-- @return a list of lines (List object), use `fill` to return a string instead of a `List`.
-- @see pl.List
+-- @see fill
function text.wrap (s,width)
assert_arg(1,s,'string')
width = width or 70
@@ -96,14 +89,103 @@ function text.wrap (s,width)
end
--- format a paragraph so that it fits into a line width.
--- @param s the string
--- @param width the margin width, default 70
--- @return a string
+-- @tparam string s the string to format
+-- @tparam[opt=70] integer width the margin width
+-- @return a string, use `wrap` to return a list of lines instead of a string.
-- @see wrap
function text.fill (s,width)
return concat(text.wrap(s,width),'\n') .. '\n'
end
+
+local function _substitute(s,tbl,safe)
+ local subst
+ if is_callable(tbl) then
+ subst = tbl
+ else
+ function subst(f)
+ local s = tbl[f]
+ if not s then
+ if safe then
+ return f
+ else
+ error("not present in table "..f)
+ end
+ else
+ return s
+ end
+ end
+ end
+ local res = gsub(s,'%${([%w_]+)}',subst)
+ return (gsub(res,'%$([%w_]+)',subst))
+end
+
+--- Python-style formatting operator.
+-- Calling `text.format_operator()` overloads the % operator for strings to give
+-- Python/Ruby style formated output.
+-- This is extended to also do template-like substitution for map-like data.
+--
+-- Note this goes further than the original, and will allow these cases:
+--
+-- 1. a single value
+-- 2. a list of values
+-- 3. a map of var=value pairs
+-- 4. a function, as in gsub
+--
+-- For the second two cases, it uses $-variable substituion.
+--
+-- When called, this function will monkey-patch the global `string` metatable by
+-- adding a `__mod` method.
+--
+-- See <a href="http://lua-users.org/wiki/StringInterpolation">the lua-users wiki</a>
+--
+-- @usage
+-- require 'pl.text'.format_operator()
+-- local out1 = '%s = %5.3f' % {'PI',math.pi} --> 'PI = 3.142'
+-- local out2 = '$name = $value' % {name='dog',value='Pluto'} --> 'dog = Pluto'
+function text.format_operator()
+
+ local format = string.format
+
+ -- a more forgiving version of string.format, which applies
+ -- tostring() to any value with a %s format.
+ local function formatx (fmt,...)
+ local args = pack(...)
+ local i = 1
+ for p in fmt:gmatch('%%.') do
+ if p == '%s' and type(args[i]) ~= 'string' then
+ args[i] = tostring(args[i])
+ end
+ i = i + 1
+ end
+ return format(fmt,unpack(args))
+ end
+
+ local function basic_subst(s,t)
+ return (s:gsub('%$([%w_]+)',t))
+ end
+
+ getmetatable("").__mod = function(a, b)
+ if b == nil then
+ return a
+ elseif type(b) == "table" and getmetatable(b) == nil then
+ if #b == 0 then -- assume a map-like table
+ return _substitute(a,b,true)
+ else
+ return formatx(a,unpack(b))
+ end
+ elseif type(b) == 'function' then
+ return basic_subst(a,b)
+ else
+ return formatx(a,b)
+ end
+ end
+end
+
+
+--- @section Template
+
+
local Template = {}
text.Template = Template
Template.__index = Template
@@ -112,6 +194,11 @@ setmetatable(Template, {
return Template.new(tmpl)
end})
+--- Creates a new Template class.
+-- This is a shortcut to `Template.new(tmpl)`.
+-- @tparam string tmpl the template string
+-- @function Template
+-- @treturn Template
function Template.new(tmpl)
assert_arg(1,tmpl,'string')
local res = {}
@@ -120,31 +207,10 @@ function Template.new(tmpl)
return res
end
-local function _substitute(s,tbl,safe)
- local subst
- if is_callable(tbl) then
- subst = tbl
- else
- function subst(f)
- local s = tbl[f]
- if not s then
- if safe then
- return f
- else
- error("not present in table "..f)
- end
- else
- return s
- end
- end
- end
- local res = gsub(s,'%${([%w_]+)}',subst)
- return (gsub(res,'%$([%w_]+)',subst))
-end
-
--- substitute values into a template, throwing an error.
-- This will throw an error if no name is found.
--- @param tbl a table of name-value pairs.
+-- @tparam table tbl a table of name-value pairs.
+-- @return string with place holders substituted
function Template:substitute(tbl)
assert_arg(1,tbl,'table')
return _substitute(self.tmpl,tbl,false)
@@ -152,7 +218,8 @@ end
--- substitute values into a template.
-- This version just passes unknown names through.
--- @param tbl a table of name-value pairs.
+-- @tparam table tbl a table of name-value pairs.
+-- @return string with place holders substituted
function Template:safe_substitute(tbl)
assert_arg(1,tbl,'table')
return _substitute(self.tmpl,tbl,true)
@@ -161,9 +228,10 @@ end
--- substitute values into a template, preserving indentation. <br>
-- If the value is a multiline string _or_ a template, it will insert
-- the lines at the correct indentation. <br>
--- Furthermore, if a template, then that template will be subsituted
+-- Furthermore, if a template, then that template will be substituted
-- using the same table.
--- @param tbl a table of name-value pairs.
+-- @tparam table tbl a table of name-value pairs.
+-- @return string with place holders substituted
function Template:indent_substitute(tbl)
assert_arg(1,tbl,'table')
if not self.strings then
@@ -191,56 +259,10 @@ function Template:indent_substitute(tbl)
end
end)
end
+
local lines = imap(subst,self.strings)
return concat(lines,'\n')..'\n'
end
-------- Python-style formatting operator ------
--- (see <a href="http://lua-users.org/wiki/StringInterpolation">the lua-users wiki</a>) --
-
-function text.format_operator()
-
- local format = string.format
-
- -- a more forgiving version of string.format, which applies
- -- tostring() to any value with a %s format.
- local function formatx (fmt,...)
- local args = {...}
- local i = 1
- for p in fmt:gmatch('%%.') do
- if p == '%s' and type(args[i]) ~= 'string' then
- args[i] = tostring(args[i])
- end
- i = i + 1
- end
- return format(fmt,unpack(args))
- end
-
- local function basic_subst(s,t)
- return (s:gsub('%$([%w_]+)',t))
- end
-
- -- Note this goes further than the original, and will allow these cases:
- -- 1. a single value
- -- 2. a list of values
- -- 3. a map of var=value pairs
- -- 4. a function, as in gsub
- -- For the second two cases, it uses $-variable substituion.
- getmetatable("").__mod = function(a, b)
- if b == nil then
- return a
- elseif type(b) == "table" and getmetatable(b) == nil then
- if #b == 0 then -- assume a map-like table
- return _substitute(a,b,true)
- else
- return formatx(a,unpack(b))
- end
- elseif type(b) == 'function' then
- return basic_subst(a,b)
- else
- return formatx(a,b)
- end
- end
-end
return text