webmcp

annotate framework/env/format/string.lua @ 471:a9fea293b2d6

New function format.file_path_element(...)
author jbe
date Thu May 25 02:46:23 2017 +0200 (2017-05-25)
parents 407633fd0e84
children
rev   line source
jbe/bsw@0 1 --[[--
jbe@471 2 text = -- a string
jbe/bsw@0 3 format.string(
jbe@111 4 value, -- any value where tostring(value) gives a reasonable result
jbe/bsw@0 5 {
jbe@111 6 nil_as = nil_text, -- text to be returned for a nil value
jbe@111 7 truncate_mode = "codepoints", -- performe truncating by counting UTF-8 codepoints ("codepoints") or Unicode grapheme clusters ("graphmeclusters")
jbe@111 8 -- (currently only "codepoints" are supported and this option may be omitted)
jbe@111 9 truncate_at = truncate_at, -- truncate string after the given number of UTF-8 codepoints (or Unicode grapheme clusters)
jbe@111 10 truncate_suffix = truncate_suffix, -- string to append, if string was truncated (use boolean true for Unicode ellipsis)
jbe@112 11 truncate_count_suffix = truncate_count_suffix -- if true, then the total length (including suffix) may not exceed the given length
jbe/bsw@0 12 }
jbe/bsw@0 13 )
jbe/bsw@0 14
jbe@110 15 Formats a value as a text by calling tostring(...), unless the value is nil, in which case the text returned is chosen by the 'nil_as' option. Using the 'truncate_*' parameters, it is possible to show only the beginning of a string.
jbe/bsw@0 16
jbe/bsw@0 17 --]]--
jbe/bsw@0 18
jbe@111 19 local function codepoint_count(str)
jbe@111 20 return #string.gsub(str, '[\128-\255][\128-\191]?[\128-\191]?[\128-\191]?', 'x')
jbe@111 21 end
jbe@111 22
jbe@111 23 local function codepoint_truncate(str, length)
jbe@111 24 local byte_pos = 1
jbe@111 25 local count = 0
jbe@111 26 while count < length do
jbe@110 27 b1, b2, b3, b4 = string.byte(str, byte_pos, byte_pos+3)
jbe@111 28 if not b2 then
jbe@111 29 break
jbe@111 30 end
jbe@111 31 b3 = b3 or 0
jbe@111 32 b4 = b4 or 0
jbe@111 33 if b1 >= 128 and b2 >= 128 and b2 <= 191 then
jbe@111 34 if b3 >= 128 and b3 <= 191 then
jbe@111 35 if b4 >= 128 and b4 <= 191 then
jbe@111 36 byte_pos = byte_pos + 4
jbe@111 37 count = count + 1
jbe@111 38 elseif count + 1 < length and b4 < 128 then
jbe@111 39 byte_pos = byte_pos + 4
jbe@111 40 count = count + 2
jbe@110 41 else
jbe@111 42 byte_pos = byte_pos + 3
jbe@111 43 count = count + 1
jbe@111 44 end
jbe@111 45 elseif count + 1 < length and b3 < 128 then
jbe@111 46 if count + 2 < length and b4 < 128 then
jbe@111 47 byte_pos = byte_pos + 4
jbe@111 48 count = count + 3
jbe@111 49 else
jbe@111 50 byte_pos = byte_pos + 3
jbe@111 51 count = count + 2
jbe@110 52 end
jbe@110 53 else
jbe@111 54 byte_pos = byte_pos + 2
jbe@111 55 count = count + 1
jbe@110 56 end
jbe@111 57 elseif count + 1 < length and b2 < 128 then
jbe@111 58 if count + 2 < length and b3 < 128 then
jbe@111 59 if count + 3 < length and b4 < 128 then
jbe@111 60 byte_pos = byte_pos + 4
jbe@111 61 count = count + 4
jbe@111 62 else
jbe@111 63 byte_pos = byte_pos + 3
jbe@111 64 count = count + 3
jbe@111 65 end
jbe@111 66 else
jbe@111 67 byte_pos = byte_pos + 2
jbe@111 68 count = count + 2
jbe@111 69 end
jbe@110 70 else
jbe@111 71 byte_pos = byte_pos + 1
jbe@111 72 count = count + 1
jbe@110 73 end
jbe@110 74 end
jbe@111 75 return string.sub(str, 1, byte_pos-1)
jbe@110 76 end
jbe@110 77
jbe/bsw@0 78 function format.string(str, options)
jbe/bsw@0 79 local options = options or {}
jbe/bsw@0 80 if str == nil then
jbe/bsw@0 81 return options.nil_as or ""
jbe@111 82 elseif options.truncate_at then
jbe@111 83 str = tostring(str)
jbe@110 84 -- TODO: Unicode grapheme cluster boundary detetion is not implemented
jbe@110 85 -- (Unicode codepoints are used instead)
jbe@111 86 local truncate_suffix = options.truncate_suffix
jbe@111 87 if truncate_suffix == true then
jbe@111 88 truncate_suffix = '\226\128\166'
jbe@111 89 elseif not truncate_suffix then
jbe@111 90 truncate_suffix = ''
jbe@111 91 end
jbe@112 92 if options.truncate_count_suffix and truncate_suffix then
jbe@111 93 local suffix_length = codepoint_count(truncate_suffix)
jbe@111 94 if codepoint_count(str) > options.truncate_at then
jbe@111 95 return (
jbe@111 96 codepoint_truncate(str, options.truncate_at - suffix_length) ..
jbe@111 97 truncate_suffix
jbe@111 98 )
jbe@111 99 else
jbe@111 100 return str
jbe@111 101 end
jbe@111 102 else
jbe@111 103 if codepoint_count(str) > options.truncate_at then
jbe@111 104 return codepoint_truncate(str, options.truncate_at) .. truncate_suffix
jbe@111 105 else
jbe@111 106 return str
jbe@111 107 end
jbe@111 108 end
jbe/bsw@0 109 else
jbe/bsw@0 110 return tostring(str)
jbe/bsw@0 111 end
jbe/bsw@0 112 end

Impressum / About Us