Created
March 26, 2010 12:37
-
-
Save metaspatial/344838 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function string.wrap(text,cols) | |
-- takes one or more lines of text and wraps them at punctuation, whilst preserving the (tab or space) indentation | |
cols = cols or tonumber(string.match(io.popen("stty size"):read()," (%d*)")) -- sh doesn't seem to export $COLUMNS | |
local output = {} -- more memory efficient than constantly concatenating | |
local offset,char,indent,indents,wrapped | |
local function IndexString (text) local temp = {} for i=1,#text do temp[string.sub(text,i,i)]=true end return temp end -- this just makes it easier to write the values as a string on the next line | |
local punctuation = IndexString [[ ,.;:!?"[]{}()]] | |
-- iterate over each line | |
for line in string.gmatch(text.."\n","(.-)\n") do | |
-- determine indentation | |
indent = "" | |
indents = 0 | |
for char,position in string.gmatch(line,"(%s)()") do | |
if position > (#indent + 2) then break end | |
indent = indent .. char | |
if char == "\t" then indents = indents + 8 -- assuming the terminal displays tabs as 8 spaces | |
else indents = indents + 1 end | |
end | |
-- check each line | |
if #line + indents - #indent < cols then | |
-- doesn't need to be wrapped, so output unchanged | |
table.insert(output,line) | |
else | |
-- does need to be wrapped | |
-- work backwards from the wrap point to find punctuation | |
offset = cols - indents | |
while offset > 0 do | |
char = string.sub(line,offset,offset) | |
if punctuation[char] then break end | |
offset = offset - 1 | |
end | |
-- output the trimmed line | |
table.insert(output,string.sub(line,1,offset)) | |
table.insert(output,"\n") | |
-- determine if the wrapped line also needs wrapping | |
wrapped = indent..string.sub(line,offset+1) | |
if #wrapped + indents - #indent > cols then | |
-- does need wrapping as well, so call self with new value | |
table.insert(output,string.wrap(wrapped,cols)) | |
else | |
-- output the wrapped line | |
table.insert(output,wrapped) | |
end | |
end | |
table.insert(output,"\n") | |
end | |
table.remove(output,#output) -- removes the final linebreak we added initially | |
return table.concat(output) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment