Jump to content




Modifying A Word Wrapping Function

help

8 replies to this topic

#1 InputUsername

  • Members
  • 231 posts
  • LocationThe Netherlands

Posted 31 October 2013 - 03:35 PM

Hello everyone, I haven't asked anything in quite a while, but while programming yesterday, I ran into a (small) problem.

I need to modify the following function (found on http://lua-users.org...i/StringRecipes):
function wrap(str, limit)
  limit = limit or 72
  local here = 1

  -- the "".. is there because :gsub returns multiple values
  return ""..str:gsub("(%s+)()(%S+)()",
  function(sp, st, word, fi)
	if fi-here > limit then
	  here = st
	  return "\n"..word
	end
  end)
end

Currently all the function does is it returns a string with words wrapped at a given margin. But what I'm trying to achieve is that every line is put into a table (ie lines with the words wrapped).

Spoiler

I have already tried the following but it doesn't work:
Lines = { }

function wrap(str, limit)
  limit = limit or 72
  local here = 1
  return ""..str:gsub("(%s+)()(%S+)()",
  function(sp, st, word, fi)
	if fi-here > limit then
	  here = st
	  Lines[#Lines+1] = "\n"..word -- this does not work
	  return "\n"..word
	end
  end)
end
Doing this gives the following result: http://repl.it/MDj

Any help/tips would be greatly appreciated.

Thanks.

#2 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 31 October 2013 - 05:54 PM

The original code creates a new string, appending one word from the original at a time along with the occasional line break. This then gets returned.

Your code puts the occasional word into your table (where the line breaks would be), while building the same string the original code made. You then return that new string instead of your table.

I'm not sure if it's the most efficient way to do it (and would be interested it seeing improved if possible), but the below should give the output you're after.

Spoiler


#3 sens

  • Members
  • 49 posts
  • LocationFrance

Posted 31 October 2013 - 06:20 PM

Edit: BombBloke beat me to it (well done mate!)... here was my solution anyhow:

function wrap(str, limit)
  limit = limit or 72
  local here = 1
  local buf = ""
  local t = {}
  str:gsub("(%s*)()(%S+)()",
  function(sp, st, word, fi)
	if fi-here > limit then
	   --# Break the line
	   here = st
	   table.insert(t, buf)
	   buf = word
	else
	   buf = buf..sp..word  --# Append
	end
  end)
  --# Tack on any leftovers
  if(buf ~= "") then
	table.insert(t, buf)
  end
  return t
end

By the way, repl.it seems very handy for collaboration, I wonder if the forum could integrate with it somehow.

#4 InputUsername

  • Members
  • 231 posts
  • LocationThe Netherlands

Posted 01 November 2013 - 10:34 AM

View PostBomb Bloke, on 31 October 2013 - 05:54 PM, said:

The original code creates a new string, appending one word from the original at a time along with the occasional line break. This then gets returned.

Your code puts the occasional word into your table (where the line breaks would be), while building the same string the original code made. You then return that new string instead of your table.

I'm not sure if it's the most efficient way to do it (and would be interested it seeing improved if possible), but the below should give the output you're after.

Spoiler

View Postsens, on 31 October 2013 - 06:20 PM, said:

Edit: BombBloke beat me to it (well done mate!)... here was my solution anyhow:

(code)

By the way, repl.it seems very handy for collaboration, I wonder if the forum could integrate with it somehow.

Thanks for the quick response, both of you.

And yes, repl.it seems very useful. If only it had Git integration of some kind.

#5 Goof

  • Members
  • 751 posts

Posted 30 October 2014 - 11:28 AM

Sorry for bump, but i've thought about if you make the "certain" margin fx. 5, and type a 10 letter large word, then it would crash..
Whats going to be a solution for that?

is it just going to need to check twice? ( one for length, and one for every word )

Thanks in Advance

EDIT: This is based on Bomb Bloke's example

Edited by Mikk809h, 30 October 2014 - 11:30 AM.


#6 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 30 October 2014 - 11:55 AM

It won't crash if a word is longer than the line limit, but it isn't rigged to cut such words in half, either. Instead you'd end up with one of the lines in the table being longer than the specified limit (though it'd only contain one word).

So yeah, to fix that put a loop in place that, when starting a new line, checks to see if the first word on that line is oversized then loops through distributing it over however many lines it needs.

I suppose it could also use a check to see if the string passed to it completely lacks spaces.


#7 Goof

  • Members
  • 751 posts

Posted 30 October 2014 - 02:54 PM

View PostBomb Bloke, on 30 October 2014 - 11:55 AM, said:

It won't crash if a word is longer than the line limit, but it isn't rigged to cut such words in half, either. Instead you'd end up with one of the lines in the table being longer than the specified limit (though it'd only contain one word).
Well.. i wont agree.. ( Using this string as the example:
local myText = "ThisTextIsVeryLong(LongerThan20Characters)"
)
Posted Image
Since it searches through the string for Spaces, it encounters that problem, i guess.

View PostBomb Bloke, on 30 October 2014 - 11:55 AM, said:

So yeah, to fix that put a loop in place that, when starting a new line, checks to see if the first word on that line is oversized then loops through distributing it over however many lines it needs.

I suppose it could also use a check to see if the string passed to it completely lacks spaces.
Well.. im not that familar with string:gsub, so I dont know where to start.
Is an example possible? :rolleyes:

Thanks in Advance ^_^

Edited by Mikk809h, 30 October 2014 - 02:57 PM.


#8 Bomb Bloke

    Hobbyist Coder

  • Moderators
  • 7,099 posts
  • LocationTasmania (AU)

Posted 30 October 2014 - 07:41 PM

Again, it's not complaining about the length of the word. In the case of that string, the problem is triggered by the lack of spaces.

Here's a version which implements the two fixes I mentioned:

Spoiler


#9 Goof

  • Members
  • 751 posts

Posted 30 October 2014 - 09:19 PM

View PostBomb Bloke, on 30 October 2014 - 07:41 PM, said:

Again, it's not complaining about the length of the word. In the case of that string, the problem is triggered by the lack of spaces.

Here's a version which implements the two fixes I mentioned:

Spoiler

Oah.. Thank you so much :)

Its working like a charm :D





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users