Code archives/Miscellaneous/String Format module
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| Download complete mod with help examples from here or install from the source below. PrintSF prints a string by combining str and values according to specified formats in str. SFormat parses str for the following directives. It then interprets those directives to format a value which is then inserted into the return string. values is an array of strings that will be processed one by one with format. clip determines the output of a specific format if the value is too large to fit within that format. A format consists of "@" followed by any of >,<,|,.,0. For example: "@>>>>>" will result in a right justified text field 6 (@ is included) characters wide. "@>>>0.00" will result in a right justified field with 2 decimals of precision @ : By itself, will print out the next value unchanged, otherwise it marks the start of a format consisting of some of the following directives. > : Right justify. < : Left justify. | : Center. . : Indicates how and to what precision a floating point number should be format. Set the global sformatPrecisionChar to use a different character to indicate precision in the output. 0 : Used to left or right pad numbers. example: Local str:String = SFormat("blah @|||||||||| blah",["cen"])
Print str
Local x:Int = 10
Local y:Int = 56
Local z:Int = 9
PrintSF "x:@ y:@ z:@",[String(x),String(y),String(z)]
Print
PrintSF "x:@<<<< y:@<<<< z:@<<<<",[String(x),String(y),String(z)]
PrintSF "x:@>>>> y:@>>>> z:@>>>>",[String(x),String(y),String(z)]
PrintSF "x:@0000 y:@0000 z:@0000",[String(x),String(y),String(z)]
Print
PrintSF "num: @>>>>>.>>",["8373.892"]
PrintSF "num: @>>>>>.>>",["8373.8"]
PrintSF "num: @>>>>>.00",["8373.8"]
PrintSF "num: @>>>>0.00",[".89"]Output blah cen blah x:10 y:56 z:9 x:10 y:56 z:9 x: 10 y: 56 z: 9 x: 0010 y: 0056 z: 0009 num: 8373.89 num: 8373.8 num: 8373.80 num: 0.89 | |||||
SuperStrict
Import BRL.StandardIO
Rem
bbdoc: SFormat
End Rem
Module dmaz.SFormat
ModuleInfo "Version: 1.0"
ModuleInfo "Author: David Maziarka"
ModuleInfo "License: Public Domain"
ModuleInfo "History: 1.00 Release"
Const CLIPERROR:Int = -1
Global sformatPrecisionChar:String = "."
Rem
bbdoc: Print a string by combining @str and @values according to specified formats in @str
about: See #SFormat
End Rem
Function PrintSF( str:String, values:String[], clip:Int=CLIPERROR )
Print SFormat(str,values,clip)
End Function
Function PrintSFD( str:String, values:String[], clip:Int=CLIPERROR )
Print str + " [" + ", ".join(values) + "]"
Print SFormat(str,values,clip)
Print
End Function
Rem
bbdoc: Parse string for specified formats and combine it with one or more values.
returns: Returns a string produced according to the supplied string.
about:
#SFormat parses @str for the following directives. It then interprets those directives to format a value which
is then inserted into the return string. @values is an array of strings that will be processed
one by one with format. @clip determines the output of a specific format if the value is
too large to fit within that format.
<br>
@str is composed of normal text, copied directly to the result and zero or more formats each of which
coincide with a value from @values. Null values are ok and will still result in the specified format.
<br>
A format consists of "@" followed by any of >,<,|,.,0. For example: "@>>>>>" will result in a right justified
text field 6 (@ is included) characters wide. "@>>>0.00" will result in a right justified field with 2 decimals
of precision
<ul>
<li><b>@</b> : By itself, will print out the next value unchanged, otherwise it marks the start of
a format consisting of some of the following directives.</li>
<li><b>></b> : Right justify.</li>
<li><b><</b> : Left justify.</li>
<li><b>|</b> : Center.</li>
<li><b>.</b> : Indicates how and to what precision a floating point number should be format. Set the global
@sformatPrecisionChar to use a different character to indicate precision in the output.</li>
<li><b>0</b> : Used to left or right pad numbers.</li>
</ul>
<br>
@clip can be one of the 3 options...
<ul>
<li><b>True</b> : Any value too big for the format will be clipped. The format type will determine which
side of the value will be cut off.</li>
<li><b>False</b> : Don't do any clipping. Although precision will still be clipped.</li>
<li><b>CLIPERROR</b> : Fill the format with #'s instead of the value, this is the default</li>
</ul>
End Rem
Function SFormat:String( str:String, values:String[], clip:Int=CLIPERROR )
Local i:Int = 0
While i < str.length
Local b0:String = Chr(str[i])
If str[i] = "@"[0]
If i = str.length-1
ReplaceF(str,ShiftValue(values),i,i,clip)
Else
For Local i2:Int = i+1 Until str.length
Local c:Int = str[i2]
Local b:String = Chr(c)
If Not(c="0"[0] Or c="<"[0] Or c=">"[0] Or c="|"[0] Or c="."[0])
i :+ ReplaceF(str,ShiftValue(values),i,i2-1,clip)
Exit
Else If i2+1 = str.length
ReplaceF(str,ShiftValue(values),i,i2,clip)
EndIf
Next
EndIf
EndIf
i :+ 1
Wend
Return str
Function ReplaceF:Int( str:String Var, value:String, startx:Int, endx:Int, clip:Int )
Local format:String = str[startx..endx+1]
If format.length = 1
' no format, insert the whole value.
str = str[..startx] + value + str[endx+1..]
Else
' process format determined by the first < | > . 0 after the @
Select str[startx+1]
Case ">"[0], "0"[0], "."[0]
Local fdotx:Int = format.FindLast(".")
If fdotx >= 0
Local vdotx:Int = value.FindLast(".")
If vdotx < 0 Then vdotx = value.length
Local ends:String = value[vdotx+1..]
ends = ends[..Len(format)-fdotx-1]
value = value[..vdotx] + sformatPrecisionChar + ends
EndIf
If value.length < format.length
value = value[Len(value)-format.length..]
ElseIf Clip = True And value.length > format.length
If fdotx >= 0
value = value[..Len(format)]
Else
value = value[Len(value)-Len(format)..]
EndIf
EndIf
Case "|"[0]
While value.length < format.length
If value.length & 1 Then value = value+" " Else value = " "+value
Wend
If clip = True And value.length > format.length
While value.length > format.length
If value.length & 1 Then value = value[1..] Else value = value[..Len(value)-1]
Wend
EndIf
Default ' <
If value.length < format.length
value = value[..format.length]
ElseIf clip = True And value.length > format.length
value = value[..format.length]
EndIf
End Select
If clip = CLIPERROR And value.length > format.length
value = ""[..format.length].Replace(" ","#")
Else
For Local i:Int = 0 Until format.length
If format[i] = "0"[0] And value[i] = " "[0]
value = value[..i] + "0" + value[i+1..]
EndIf
Next
EndIf
str = str[..startx] + value + str[endx+1..]
EndIf
Return value.length - 1
End Function
Function ShiftValue:String( values:String[] Var )
Local first:String = ""
If values.length
first = values[0]
values = values[1..]
EndIf
Return first
End Function
End Function |
Comments
| ||
| I remove the c code to edit the string in place. |
Code Archives Forum