function to easily align text for display (actually, 4 now)

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

function to easily align text for display (actually, 4 now)

Post by demonnic »

PLEASE SEE viewtopic.php?f=6&t=22763 for the most up to date version of this. I won't be updating the code this post points to any more.


Thanks to hempa for the initial idea. I cleaned it up a bit and made it for more than just centering.
EDIT: this is turned into a full fledged project for me.

EDIT: Newest version. This has now spread into four functions, so that it will format specifically for echo, cecho, decho, and hecho (align, calign, dalign, and halign respectiveiy)

EDIT: Very quick and easy update to fix [c|h|d]align() functions which were erroneously counting the color codes in the string length.

EDIT: Code will be kept up to date at https://github.com/demonnic/mudletalign

EDIT: New code pushed, fixed issues with color_names rather than colorNames being used. Previously forgot about the _ option.



For you, a screenshot:
align.jpeg
For usage (refer to screenshot):
calign("some string", {table containing options})

your options are as follows (order doesn't matter):
width: How many chars across the total line should be. Defaults to 80. set as width = #
alignment: How you want it aligned. Defaults to "centered", right/light also options. set as alignment = "center"
cap: What you want to use to encapsule the message. Defaults to "", set as cap = "[Blah]"
mirror: Reverse the right cap from the left cap when center? IE turns <{[[ into ]]}> when using the center alignment. Defaults to true, and is ignored when aligning left or right. Set as mirror = false
spacer: The thing you want to fill the extra space for formatting. Defaults to " ", set as spacer = "="
inside: Whether you want the spacer inside the caps, or outside the caps. Defaults to true which produces things like "[Blah]======= some text ========[Blah]" , set as inside = false
*capColor: What color you want the caps to be. Defaults to white, set as capColor = "<green>"
*spacerColor: What color you want your spacer to be. Defaults to whatever white, set as spacerColor = "<purple>"
*textColor: What color you want the text you're formatting to be. Defaults to white, set as textColor = "<red>"

*Note:
I have now included seperate functions. align() now is completely unformatted for colors. calign() is color formatting for the cecho function, dalign() and halign() are similarly biased. The example usage above is entirely correct, just be sure to use the align() function which matches the echo() function you plan to pass it through

For you, an example using all of the options:
calign("some text", {width = "35", alignment = "center", cap = "[Bal]", mirror = false, spacer = "-", inside = false, capColor = "<yellow:red>", spacerColor = "<green:purple>", textColor = "<dark_green:blue>"})

Which would produce something similar (though more eye searing) in concept to the fourth color demo in the screenshot above.

For you, a minimal example:
align("some text")

which will center "some text" minus "" in the middle of an 80 length line using spaces.


To create the screenshot above, create an alias which contains this
Code: [show] | [select all] lua
cecho("Centered, mirror caps, spacer inside")
cecho(calign("some text", {alignment = "center", width = 30, cap = "{[[", spacer = "=", inside = true, mirror = true}))
cecho("\nCentered, mirror caps, spacer outside")
cecho(calign("some text", {alignment = "center", width = 30, cap ="{[[", spacer = "=", inside = false, mirror = true}))
cecho("\nCentered, no mirroring, spacer inside")
cecho(calign("some text", {alignment = "center", width = 30, cap = "[Bal]", spacer = "=", inside = true, mirror = false}))
cecho("\nCentered, no mirroring, spacer outside")
cecho(calign("some text", {alignment = "center", width = 30, cap = "[Bal]", spacer = "=", inside = false, mirror = false}))
cecho("\nLeft aligned, spacer inside")
cecho(calign("some text", {alignment = "left", width = 30, cap = "|", spacer = ".", inside = true}))
cecho("\nLeft aligned, spacer outside")
cecho(calign("some text", {alignment = "left", width = 30, cap = "|", spacer = "=", inside = false}))
cecho("\nRight aligned, spacer inside")
cecho(calign("some text", {alignment = "right", width = 30, cap = "|", spacer = ".", inside = true}))
cecho("\nRight aligned, spacer outside")
cecho(calign("some text", {alignment = "right", width = 30, cap = "|", spacer = "=", inside = false}))
cecho("\n\nNow with colors!!")
cecho("\nCentered, mirror caps, spacer inside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "center", width = 30, cap = "{[[", spacer = "=", inside = true, mirror = true, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nCentered, mirror caps, spacer outside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "center", width = 30, cap = "{[[", spacer = "=", inside = false, mirror = true, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nCentered, no mirroring, spacer inside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "center", width = 30, cap = "[Bal]", spacer = "=", inside = true, mirror = false, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nCentered, no mirroring, spacer outside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "center", width = 30, cap = "[Bal]", spacer = "=", inside = false, mirror = false, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nLeft Aligned, spacer inside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "left", width = 30, cap = "|", spacer = ".", inside = true, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nLeft Aligned, spacer outside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "left", width = 30, cap = "|", spacer = "=", inside = false, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nRight Aligned, spacer inside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "right", width = 30, cap = "|", spacer = ".", inside = true, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
cecho("\nRight Aligned, spacer outside, <green>capColor <white>, <purple>spacerColor <white>, <red>textColor<white>")
cecho(calign("some text", {alignment = "right", width = 30, cap = "|", spacer = "=", inside = false, capColor = "<green>", spacerColor = "<purple>", textColor = "<red>"}))
Once the below lua code is in your profile, if you run the above code it will produce the screenshot.
Code: [show] | [select all] lua

function align(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful
info. But if they didn't send a second argument then that's ok, the defaults
will be enough to get by and just center the txt
]]--
  if (type(options) ~= "table") and (options ~= nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

 
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
   
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
   
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing.
 
  if options.inside then
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap====="
  --"=====endcap some text pacdne====="
  --"=================endcap some text"
  --"some text endcap================="
    return leftCap .. string.rep(options.spacer, (leftPadLen - capLen)) .. str ..string.rep(options.spacer, (rightPadLen - capLen)).. rightCap
  else
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne"
  -- "endcap================= some text"
  -- "some text =================endcap"
    return string.rep(options.spacer, (leftPadLen - capLen)) .. leftCap .. str .. rightCap .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end


function calign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "<white>"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "<white>"
  options.textColor = options.textColor or "<white>"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strippedString = str:gsub("<%w*_?%w*:?%w*_?%w*>","")
  local strLen = string.len(strippedString)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

function dalign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "<255,255,255>"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "<255,255,255>" 
  options.textColor = options.textColor or "<255,255,255>"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strippedString = str:gsub("<%w*_?%w*:?%w*_?%w*>","")
  local strLen = string.len(strippedString)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

function halign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "|cFFFFFF"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "|cFFFFFF" 
  options.textColor = options.textColor or "|cFFFFFF"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strippedString = str:gsub("<%w*_?%w*:?%w*_?%w*>","")
  local strLen = string.len(strippedString)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end
 

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

Re: function to easily align text for display

Post by demonnic »

so I got frisky. I expanded it to be able to handle pads greater than 1 char in length. Specifically for centering, if you want to encapsulate it

example of newness:

align("This is some text", "center", 40, "---===||")

will return

Code: Select all

---===||  This is some text   ||===---
while the original functionality from the post above is preserved. However, left/right aligned will still chomp it to just the first letter.

It will also adjust your padding string down to the proper length if the length of the txt and all the padding is greater than the width set.


ETA: requested functionality, final argument is true or false (no quotes) and defaults to false. if false, it'll add the spaces when centering using pads of more than 1 char in length to the beginning and end of the total string. if true, it'll add it between the text and the pad strings.

ETA: will now swap <[ and { for their counterparts >] and } on the right side.

and, finally, the code (now with comments!)
Code: [show] | [select all] lua
-- function to align left, right, center with specific padding. 
function align( str, alignment, width, pad, inside )
  width = width or 80 --most muds use screen width 80 by default
  pad = pad or " " --just use spaces if they don't care to specify
  alignment = alignment or "center" --center if they don't care to specify, most common usecase
  inside = inside or false --seems most people want the extra spaces on the outside
  local strLen = string.len(str) 
  if alignment == "center" then --center it!
    local leftPadLen = math.floor((width - strLen)/2,1)  --get the padding needed on the left
    local rightPadLen = leftPadLen + ((width - strLen)%2) --and on the right
    if pad ~= " " then --if we're not just using spaces to pad
      if string.len(pad) > 1 then --then check if we're using encapsulating chars, and not just one padder. If we are
        if ( ( string.len(pad) * 2 ) + strLen  > width ) then   --check and make sure the padding on both sides -and- the txt fit. if not, make it!
          local maxPad = width - strLen - 2
          pad = pad:sub(1, maxPad)
        end
        if inside then --if they want spaces inside the encapsulation
          local leftPad = pad .. string.rep(" ", (leftPadLen - 1 - string.len(pad)))
          pad = string.gsub(pad, "<", ">")  --these three lines reverse <. [, and { for you for the right side encapsulation
          pad = string.gsub(pad, "%[", "%]")
          pad = string.gsub(pad, "{", "}")
          local rightPad = string.rep(" ", (rightPadLen - 1 - string.len(pad))) .. string.reverse(pad)
          return leftPad .. string.format(" %s ",str) .. rightPad
        else --if they don't!
          local leftPad = string.rep(" ", (leftPadLen - 1 - string.len(pad))) .. pad
          pad = string.gsub(pad, "<", ">")
          pad = string.gsub(pad, "%[", "%]")
          pad = string.gsub(pad, "{", "}")
          local rightPad = string.reverse(pad) .. string.rep(" ", (rightPadLen - 1 - string.len(pad)))
          return leftPad .. string.format(" %s ",str) .. rightPad
        end
      else --for if they've only got one char in their pad string
        return (string.rep(pad,(leftPadLen - 1)) .. string.format(" %s ",str) .. string.rep(pad,(rightPadLen-1)))
      end
    else --ok, we're using spaces here.. this one was easy!
      return (string.rep(pad, leftPadLen) .. str .. string.rep(pad, rightPadLen))
    end
  elseif alignment == "right" then  --ok, so they want it hard-right aligned. No fanciness here. 
    pad = pad:sub(1,1)
    local leftPadLen = width - strLen
    return (string.rep(pad,leftPadLen) .. str)
  else --anything but center or right will give you hard left aligned. Deal.
    pad = pad:sub(1,1)
    local rightPadLen = width - strLen
    return (str .. str.rep(pad, rightPadLen))
  end
end
 

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

Re: function to easily align text for display

Post by demonnic »

Because Jules is a freak, and knows I can't leave well enough alone... now with the ability to use multi-char padding for left and right aligned. align("text", "left", 20, "-]]", false) will produce the following now:

text--------------]]

similarly

align("text", "right", 20, "[[-", false) will produce:

[[--------------text


and, the code
Code: [show] | [select all] lua
-- function to align left, right, center with specific padding. 
function align( str, alignment, width, pad, inside )
  width = width or 80 --most muds use screen width 80 by default
  pad = pad or " " --just use spaces if they don't care to specify
  alignment = alignment or "center" --center if they don't care to specify, most common usecase
  inside = inside or false --seems most people want the extra spaces on the outside
  local strLen = string.len(str) 
  if alignment == "center" then --center it!
    local leftPadLen = math.floor((width - strLen)/2,1)  --get the padding needed on the left
    local rightPadLen = leftPadLen + ((width - strLen)%2) --and on the right
    if pad ~= " " then --if we're not just using spaces to pad
      if string.len(pad) > 1 then --then check if we're using encapsulating chars, and not just one padder. If we are
        if ( ( string.len(pad) * 2 ) + strLen  > width ) then   --check and make sure the padding on both sides -and- the txt fit. if not, make it!
          local maxPad = width - strLen - 2
          pad = pad:sub(1, maxPad)
        end
        if inside then --if they want spaces inside the encapsulation
          local leftPad = pad .. string.rep(" ", (leftPadLen - 1 - string.len(pad)))
          pad = string.gsub(pad, "<", ">")  --these three lines reverse <. [, and { for you for the right side encapsulation
          pad = string.gsub(pad, "%[", "%]")
          pad = string.gsub(pad, "{", "}")
          local rightPad = string.rep(" ", (rightPadLen - 1 - string.len(pad))) .. string.reverse(pad)
          return leftPad .. string.format(" %s ",str) .. rightPad
        else --if they don't!
          local leftPad = string.rep(" ", (leftPadLen - 1 - string.len(pad))) .. pad
          pad = string.gsub(pad, "<", ">")
          pad = string.gsub(pad, "%[", "%]")
          pad = string.gsub(pad, "{", "}")
          local rightPad = string.reverse(pad) .. string.rep(" ", (rightPadLen - 1 - string.len(pad)))
          return leftPad .. string.format(" %s ",str) .. rightPad
        end
      else --for if they've only got one char in their pad string
        return (string.rep(pad,(leftPadLen - 1)) .. string.format(" %s ",str) .. string.rep(pad,(rightPadLen-1)))
      end
    else --ok, we're using spaces here.. this one was easy!
      return (string.rep(pad, leftPadLen) .. str .. string.rep(pad, rightPadLen))
    end
  elseif alignment == "right" then  --ok, so they want it hard-right aligned. No fanciness here. 
    if string.len(pad) > 1 then 
      if (string.len(pad) + strLen) > width then 
        local maxPad = width - strLen
        local repstring = pad:sub(-1)
        pad = pad:sub(1, (maxPad - 1))
        pad = pad .. repstring
      end
      local repstring = pad:sub(-1)
      pad = pad:sub(1,-2)
      local leftPadLen = width - strLen
      return (pad .. string.rep(repstring,leftPadLen - string.len(pad)) .. str)
    else 
      local leftPadLen = width - strlen
      return (string.rep(pad, leftPadLen) .. str)
    end
  else --anything but center or right will give you hard left aligned. Deal.
    if string.len(pad) > 1 then
      if (string.len(pad) + strLen) > width then
        local maxPad = width - strLen
        pad = pad:sub(1, maxPad)
      end
      local repstring = pad:sub(1,1)
      pad = pad:sub(2)
      local rightPadLen = width - strLen
      return (str .. string.rep(repstring, rightPadLen - string.len(pad)) .. pad)
    else
      local rightPadLen = width - strLen
      return (str .. string.rep(pad, rightPadLen))
    end
  end
end

User avatar
Jules
Posts: 118
Joined: Sun Oct 11, 2009 5:41 pm
Location: Plymouth State University - Sophomore

Re: function to easily align text for display

Post by Jules »

What about Center alligned?
:lol:

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

Re: function to easily align text for display

Post by demonnic »

I'll get you for this!


ok, now for "center" if you say true to the last argument, you get the follow


align("some text", "center", 40, "<<-", true)

produces:

<<------------ some text ------------->>

whereas

align("some text", "center", 40, "<<-", false)

still produces:

Code: Select all

           <<- some text ->>            
go on, highlight it, it'll have the right number of spaces...

*grumble*

hopefully, finally, for the last time... the code
Code: [show] | [select all] lua
-- function to align left, right, center with specific padding. 
function align( str, alignment, width, pad, inside )
  width = width or 80 --most muds use screen width 80 by default
  pad = pad or " " --just use spaces if they don't care to specify
  alignment = alignment or "center" --center if they don't care to specify, most common usecase
  inside = inside or false --seems most people want the extra spaces on the outside
  local strLen = string.len(str) 
  if alignment == "center" then --center it!
    local leftPadLen = math.floor((width - strLen)/2,1)  --get the padding needed on the left
    local rightPadLen = leftPadLen + ((width - strLen)%2) --and on the right
    if pad ~= " " then --if we're not just using spaces to pad
      if string.len(pad) > 1 then --then check if we're using encapsulating chars, and not just one padder. If we are
        if ( ( string.len(pad) * 2 ) + strLen  > width ) then   --check and make sure the padding on both sides -and- the txt fit. if not, make it!
          local maxPad = width - strLen - 2
          pad = pad:sub(1, maxPad)
        end
        if inside then --if they want spaces inside the encapsulation we'll do something similar to left/right aligned
          local repstring = pad:sub(-1)
          pad = pad:sub(1,-2)
          leftPad = pad .. string.rep(repstring,leftPadLen - 1 - string.len(pad))
          local rightPad = string.gsub(leftPad, "<", ">")  --these three lines reverse <. [, and { for you for the right side encapsulation
          rightPad = string.gsub(rightPad, "%[", "%]")
          rightPad = string.gsub(rightPad, "{", "}")
          rightPad = string.rep(repstring, (rightPadLen - leftPadLen)) .. string.reverse(rightPad)
          return leftPad .. string.format(" %s ",str) .. rightPad
        else --if they don't
          local leftPad = string.rep(" ", (leftPadLen - 1 - string.len(pad))) .. pad
          pad = string.gsub(pad, "<", ">")
          pad = string.gsub(pad, "%[", "%]")
          pad = string.gsub(pad, "{", "}")
          local rightPad = string.reverse(pad) .. string.rep(" ", (rightPadLen - 1 - string.len(pad)))
          return leftPad .. string.format(" %s ",str) .. rightPad
        end
      else --for if they've only got one char in their pad string
        return (string.rep(pad,(leftPadLen - 1)) .. string.format(" %s ",str) .. string.rep(pad,(rightPadLen-1)))
      end
    else --ok, we're using spaces here.. this one was easy!
      return (string.rep(pad, leftPadLen) .. str .. string.rep(pad, rightPadLen))
    end
  elseif alignment == "right" then  --ok, so they want it hard-right aligned. 
    if string.len(pad) > 1 then  --if they're using a fancy schmancy pad with more than 1 char, we want to repeat just 1, and keep the rest intact
      if (string.len(pad) + strLen) > width then 
        local maxPad = width - strLen
        local repstring = pad:sub(-1)
        pad = pad:sub(1, (maxPad - 1))
        pad = pad .. repstring
      end
      local repstring = pad:sub(-1)
      pad = pad:sub(1,-2)
      local leftPadLen = width - strLen
      return (pad .. string.rep(repstring,leftPadLen - string.len(pad)) .. str)
    else 
      local leftPadLen = width - strlen
      return (string.rep(pad, leftPadLen) .. str)
    end
  else --anything but center or right will give you hard left aligned. Deal. Same as right-aligned for char preservation
    if string.len(pad) > 1 then
      if (string.len(pad) + strLen) > width then
        local maxPad = width - strLen
        pad = pad:sub(1, maxPad)
      end
      local repstring = pad:sub(1,1)
      pad = pad:sub(2)
      local rightPadLen = width - strLen
      return (str .. string.rep(repstring, rightPadLen - string.len(pad)) .. pad)
    else
      local rightPadLen = width - strLen
      return (str .. string.rep(pad, rightPadLen))
    end
  end
end

User avatar
Jules
Posts: 118
Joined: Sun Oct 11, 2009 5:41 pm
Location: Plymouth State University - Sophomore

Re: function to easily align text for display

Post by Jules »

But wait! I see a mis... no wait, that's correct...

Oh! I thought of some way you could make it be... Nope, it's perfect there too...

Damn, as much as I wanna be like a little kid and point out flaws, I see none.

Very well done, Demonnic! I'm stealing! MINE!

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

Re: function to easily align text for display

Post by demonnic »

Ok, so now it'll let you do colors!

align("some text", "center", 40, "<<-", true, "<red:blue>", "<green:purple>")

will produce:

<red:blue><<------------<green:purple> some text <red:blue>------------->>

suitable, for, say... parsing through cecho. Cap color, then text color, as shown above. They are optional arguments (really, all but the "some text" argument are optional, align("some text") will center "some text" using <space> for the pad and the default width of 80) so the previous functionality is preserved as is.


enjoy some code:
Code: [show] | [select all] lua
-- function to align left, right, center with specific padding. Now with colors!
function align( str, alignment, width, pad, inside , capcolor, textcolor)
  width = width or 80 --most muds use screen width 80 by default
  pad = pad or " " --just use spaces if they don't care to specify
  alignment = alignment or "center" --center if they don't care to specify, most common usecase
  inside = inside or false --seems most people want the extra spaces on the outside
  capcolor = capcolor or ""
  textcolor = textcolor or ""
  local strLen = string.len(str) 
  if alignment == "center" then --center it!
    local leftPadLen = math.floor((width - strLen)/2,1)  --get the padding needed on the left
    local rightPadLen = leftPadLen + ((width - strLen)%2) --and on the right
    if pad ~= " " then --if we're not just using spaces to pad
      if string.len(pad) > 1 then --then check if we're using encapsulating chars, and not just one padder. If we are
        if ( ( string.len(pad) * 2 ) + strLen  > width ) then   --check and make sure the padding on both sides -and- the txt fit. if not, make it!
          local maxPad = width - strLen - 2
          pad = pad:sub(1, maxPad)
        end
        if inside then --if they want spaces inside the encapsulation we'll do something similar to left/right aligned
          local repstring = pad:sub(-1)
          pad = pad:sub(1,-2)
          leftPad = pad .. string.rep(repstring,leftPadLen - 1 - string.len(pad))
          local rightPad = string.gsub(leftPad, "<", ">")  --these three lines reverse <. [, and { for you for the right side encapsulation
          rightPad = string.gsub(rightPad, "%[", "%]")
          rightPad = string.gsub(rightPad, "{", "}")
          rightPad = string.rep(repstring, (rightPadLen - leftPadLen)) .. string.reverse(rightPad)
          return capcolor .. leftPad .. textcolor .. string.format(" %s ",str) .. capcolor .. rightPad
        else --if they don't
          local leftPad = string.rep(" ", (leftPadLen - 1 - string.len(pad))) .. pad
          pad = string.gsub(pad, "<", ">")
          pad = string.gsub(pad, "%[", "%]")
          pad = string.gsub(pad, "{", "}")
          local rightPad = string.reverse(pad) .. string.rep(" ", (rightPadLen - 1 - string.len(pad)))
          return capcolor .. leftPad .. textcolor .. string.format(" %s ",str) .. capcolor .. rightPad
        end
      else --for if they've only got one char in their pad string
        return capcolor .. string.rep(pad,(leftPadLen - 1)) .. textcolor .. string.format(" %s ",str) .. capcolor .. string.rep(pad,(rightPadLen-1))
      end
    else --ok, we're using spaces here.. this one was easy!
      return capcolor .. (string.rep(pad, leftPadLen) .. textcolor .. str .. capcolor .. string.rep(pad, rightPadLen))
    end
  elseif alignment == "right" then  --ok, so they want it hard-right aligned. 
    if string.len(pad) > 1 then  --if they're using a fancy schmancy pad with more than 1 char, we want to repeat just 1, and keep the rest intact
      if (string.len(pad) + strLen) > width then 
        local maxPad = width - strLen
        local repstring = pad:sub(-1)
        pad = pad:sub(1, (maxPad - 1))
        pad = pad .. repstring
      end
      local repstring = pad:sub(-1)
      pad = pad:sub(1,-2)
      local leftPadLen = width - strLen
      return capcolor .. pad .. string.rep(repstring,leftPadLen - string.len(pad)) .. textcolor .. str
    else 
      local leftPadLen = width - strlen
      return capcolor .. string.rep(pad, leftPadLen) .. textcolor .. str
    end
  else --anything but center or right will give you hard left aligned. Deal. Same as right-aligned for char preservation
    if string.len(pad) > 1 then
      if (string.len(pad) + strLen) > width then
        local maxPad = width - strLen
        pad = pad:sub(1, maxPad)
      end
      local repstring = pad:sub(1,1)
      pad = pad:sub(2)
      local rightPadLen = width - strLen
      return textcolor .. str .. capcolor .. string.rep(repstring, rightPadLen - string.len(pad)) .. pad
    else
      local rightPadLen = width - strLen
      return textcolor .. str .. capcolor .. string.rep(pad, rightPadLen)
    end
  end
end

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

Redesigned, more flexible, final version no really

Post by demonnic »

OK... Refer back to the first post for the all new align() function, and it's options. I did a full rewrite.

User avatar
demonnic
Posts: 884
Joined: Sat Dec 05, 2009 3:19 pm

Re: function to easily align text for display (actually, 4 now)

Post by demonnic »

EDIT: Newest version. This has now spread into four functions, so that it will format specifically for echo, cecho, decho, and hecho (align, calign, dalign, and halign respectiveiy)

Code: [show] | [select all] lua
function align(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful
info. But if they didn't send a second argument then that's ok, the defaults
will be enough to get by and just center the txt
]]--
  if (type(options) ~= "table") and (options ~= nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

 
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
   
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
   
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing.
 
  if options.inside then
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap====="
  --"=====endcap some text pacdne====="
  --"=================endcap some text"
  --"some text endcap================="
    return leftCap .. string.rep(options.spacer, (leftPadLen - capLen)) .. str ..string.rep(options.spacer, (rightPadLen - capLen)).. rightCap
  else
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne"
  -- "endcap================= some text"
  -- "some text =================endcap"
    return string.rep(options.spacer, (leftPadLen - capLen)) .. leftCap .. str .. rightCap .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end


function calign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "<white>"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "<white>"
  options.textColor = options.textColor or "<white>"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

function dalign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "<255,255,255>"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "<255,255,255>" 
  options.textColor = options.textColor or "<255,255,255>"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

function halign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "|cFFFFFF"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "|cFFFFFF" 
  options.textColor = options.textColor or "|cFFFFFF"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: function to easily align text for display (actually, 4 n

Post by Vadi »

For some reason the forums decided to mess with what's there and insert random tags. Fixed version:
Code: [show] | [select all] lua
function align(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful
info. But if they didn't send a second argument then that's ok, the defaults
will be enough to get by and just center the txt
]]--
  if (type(options) ~= "table") and (options ~= nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

 
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
   
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
   
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing.
 
  if options.inside then
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap====="
  --"=====endcap some text pacdne====="
  --"=================endcap some text"
  --"some text endcap================="
    return leftCap .. string.rep(options.spacer, (leftPadLen - capLen)) .. str ..string.rep(options.spacer, (rightPadLen - capLen)).. rightCap
  else
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne"
  -- "endcap================= some text"
  -- "some text =================endcap"
    return string.rep(options.spacer, (leftPadLen - capLen)) .. leftCap .. str .. rightCap .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end


function calign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "<white>"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "<white>"
  options.textColor = options.textColor or "<white>"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

function dalign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "<255,255,255>"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "<255,255,255>" 
  options.textColor = options.textColor or "<255,255,255>"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end

function halign(str,options) --str is a string, options is a table
--[[ If they sent anything but a table as the second argument, return useful 
info. But if they didn't send a second argument then that's ok, the defaults 
will be enough to get by and just center the txt
]]--
  if (not type(options) == "table") and (not options == nil) then return "You call this with align(\"some text to format\", <table of options>. Pls check comments for what options and usage information" end 
  options = options or {} --if they sent options, don't overwrite them
  options.width = options.width or 80 --default line length of 80
  options.alignment = options.alignment or "center" --if we don't specify, it's centered
  options.cap = options.cap or "" --default endcap of nothing (an empty string, technically)
  options.spacer = options.spacer or " " --default spacer is.. well.. space
  options.inside = options.inside or false --by default, when centering, formation as spacers|cap|text|cap|spacers
  options.capColor = options.capColor or "|cFFFFFF"--by default, don't change the color of the caps
  options.spacerColor = options.spacerColor or "|cFFFFFF" 
  options.textColor = options.textColor or "|cFFFFFF"--or the text
  if not options.mirror == false then options.mirror = options.mirror or true end--by default, we do want to use mirroring for the caps
  local strLen = string.len(str)
  local leftCap = options.cap
  local rightCap = options.cap
  local leftPadLen = math.floor((options.width - strLen)/2,1) - 1
  local rightPadLen = leftPadLen + ((options.width - strLen)%2)
  local maxPad = 0
  local capLen = string.len(options.cap)
  if capLen > leftPadLen then --if the cap is bigger than the left total padding
    options.cap = options.cap:sub(1, leftPadLen) -- trim it up right!
    capLen = string.len(options.cap)
  end --otherwise, don't mess with it

  
  if options.alignment == "center" then --we're going to center something
    leftPadLen = math.floor((options.width - strLen)/2,1) - 1 --get the padding needed on the left
    rightPadLen = leftPadLen + ((options.width - strLen)%2) --and on the right
    if options.mirror then --if we're reversing the left cap and the right cap (IE {{[[ turns into ]]}} )
      rightCap = string.gsub(rightCap, "<", ">")
      rightCap = string.gsub(rightCap, "%[", "%]")
      rightCap = string.gsub(rightCap, "{", "}")
      rightCap = string.gsub(rightCap, "%(", "%)")
      rightCap = string.reverse(rightCap)
    end --otherwise, they'll be the same, so don't do anything
    str = string.format(" %s ", str)
    
  elseif options.alignment == "right" then --we'll right-align the text
    leftPadLen = options.width - strLen - 1
    rightPadLen = 0
    rightCap = ""
    str = string.format(" %s", str)
    
  else --Ok, so if it's not center or right, we assume it's left. We don't do justified. Sorry.
    leftPadLen = 0
    rightPadLen = options.width - strLen -1
    leftCap = ""
    str = string.format("%s ", str)
  end--that's it, took care of both left, right, and center formattings, now to output the durn thing. 
  
  if options.inside then 
  --if we're placing the repated spacer inside
  --"=====endcap some text endcap=====" 
  --"=====endcap some text pacdne====="
  --"=================endcap some text" 
  --"some text endcap================="
    return options.capColor .. leftCap .. options.spacerColor.. string.rep(options.spacer, (leftPadLen - capLen)) .. options.textColor .. str .. options.spacerColor ..string.rep(options.spacer, (rightPadLen - capLen)) .. options.capColor .. rightCap
  else 
  --otherwise, it''s be the spaces on the 'inside'
  -- "endcap===== some text =====endcap"
  -- "endcap===== some text =====pacdne" 
  -- "endcap================= some text" 
  -- "some text =================endcap"
    return options.spacerColor .. string.rep(options.spacer, (leftPadLen - capLen)) .. options.capColor .. leftCap .. options.textColor .. str .. options.capColor .. rightCap .. options.spacerColor .. string.rep(options.spacer, (rightPadLen - capLen))
  end
end
 

Post Reply