* * DOLRFMT.KEX * * Format numbers to have commas, a leading dollar sign, a decimal point * and two digits to the right of the decimal point. If there are less than * 2 digits to the right of the decimal point the number is padded with zeroes. * If there are more than 2 digits to the right of the decimal point then it * is to two digits and is not rounded. * * If a block is currently marked then it's assumed that the numbers are in * the block, otherwise each line should contain a single number. Blank lines * are ignored. For box blocks, the resulting formatted numbers are placed in * the block without disturbing text to the left or right of the block unless * the resulting formatted numbers end up being wider than the block. If any * of the resulting numbers are wider than the block then these items are * replaced with a string of asterisks and an error message is generated. The * results are right-adjusted to the right edge of the block. For line blocks * (or no block) resulting numbers are arranged so that the decimal points * line up in the same column. * * For example, given the following text in a box block: * * 33821190.2 * 229334.34 * 1002333 * 44560010 * * this macro produces: * * $3,821,190.20 * $229,334.34 * $1,002,333.00 * $44,560,010.00 * * Works with: * * KEDIT for Windows 1.5 * KEDIT 5.0 for DOS * KEDIT 5.0 for OS/2 * * Original author: Kent Downs, MSG, 8/96 * * Set this to 0 if you don't want a leading dollar sign AddDollarSign = 1 "preserve" "set autosave off" ResetBlock = 0 ProcessingBlock = 0 if AddDollarSign then DollarSign = "$" else DollarSign = "" if block.1() \= "NONE" then do if block.1() = "STREAM" then do "emsg DOLRFMT Error 1: Stream blocks are not supported" exit 1 end if block.6() \= fileid.1() then do "emsg DOLRFMT Error 2: Marked block not in current file" exit 1 end if version.1() = "KEDIT/WINDOWS" then do if block.7() = "SELECTION" then do ResetBlock = 1 "mark persistent" end end ProcessingBlock = 1 EndOfBlock = block.4() "sos blockstart" end else do ":1" end FirstLine = line.1() widest = 0 TruncatedItems = 0 * Process each line of the file and convert the number on each do while \EORange() * Grab a copy of the current line line = curline.3() if ProcessingBlock & block.1() = "BOX" then do BlockWidth = block.5() - block.3() + 1 if block.3() = 1 then do left = "" RawNumber = strip(substr(line, 1, block.5())) right = substr(line, block.5() + 1) end else do left = substr(line, 1, block.3() - 1) right = substr(line, block.5() + 1) RawNumber = strip(substr(line, block.3(), BlockWidth)) end end else do left = "" right = "" RawNumber = strip(line) end if RawNumber \= "" then do * Format the number NewNumber = FormatNum(RawNumber) * Track the widest - we'll need this to line up the results if length(NewNumber) > widest then widest = length(NewNumber) if ProcessingBlock & block.1() = "BOX" then do if BlockWidth < length(NewNumber) then do NewNumber = copies("*", BlockWidth) TruncatedItems = TruncatedItems + 1 end else do NewNumber = copies(" ", BlockWidth - length(NewNumber)) || NewNumber end end "replace" left || NewNumber || right end * Next line to process "down 1" end ":"FirstLine if ProcessingBlock then do if block.1() = "BOX" then do if ResetBlock then "reset block" "restore" if TruncatedItems = 1 then do say TruncatedItems "formatted number was too wide" end else if TruncatedItems > 1 then do say TruncatedItems "formatted numbers were too wide" end exit 0 end end do while \EORange() line = curline.3() if length(line) < widest then do line = copies(" ", widest - length(line)) || line "replace" line end "down 1" end if ResetBlock then "reset block" ":"FirstLine exit 0 * Subroutine to do the formatting FormatNum: parse arg RawNum j = pos(".", RawNum) if j = 0 then do * No decimal place so we'll add one lRawNum = RawNum rRawNum = "00" end else do lRawNum = substr(RawNum, 1, j - 1) rRawNum = substr(RawNum, j + 1) n = 2 - length(rRawNum) * Make sure we have 2 digits after the decimal point if n > 0 then rRawNum = rRawNum || copies("0", n) else do n = length(rRawNum) if n > 2 then do * We have more than 2 digits after the decimal point - truncate rRawNum = substr(rRawNum, 1, 2) end end end n = length(lRawNum) * Numbers of 3 or less digits only need the dollar sign if n < 4 then return DollarSign || RawNum * This is the number we'll build up from the original but without commas NonFormat = substr(lRawNum, n - 2) * This is the number we'll build up from the original WITH commas NewNum = substr(lRawNum, n - 2) * This is the remainder of the original number to process lRawNum = substr(lRawNum, 1, n - 3) * Starting with the fourth digit from the right, scan left one digit at a * time do i = n - 4 to 0 by -1 * We need a comma prefix every 3 digits if length(NonFormat) // 3 = 0 & i \= n then NewNum = "," || NewNum * Concatenate the next digit NewNum = substr(lRawNum, length(lRawNum), 1) || NewNum NonFormat = substr(lRawNum, length(lRawNum), 1) || NonFormat * Move left one digit on the original number lRawNum = substr(RawNum, 1, length(lRawNum) - 1) end NewNum = DollarSign || NewNum if length(rRawNum) > 0 then NewNum = NewNum"."rRawNum return NewNum * Return 1 if the focus line is below the last number to format EORange: if ProcessingBlock then do if line.1() > EndOfBlock then return 1 end else do return focuseof() end return 0