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