This function will perform PRINT USING style formatting and then return the formatted output string, so you can either store it in a variable or print it directly. However, compared to the regular PRINT USING conventions, this function has a couple of useful extensions.
The first and most important extension is argument position specification (indexing). That is, each formatting token used in the format template knows to which given argument it belongs to, hence the order of the various format tokens used in the template can be changed without the need of reordering the provided arguments too.
The second extension is a direct result of the first one. With indexing all arguments can be easily reused, simply by using the same index for several format tokens. It is not required to pass the reused arguments multiple times to the function.
The indexing is done really simple in the form IS{PUFS}, where IS = index specifier (0-9/A-Z, hence 36 args max.) and PUFS = PRINT USING format symbols. That is, starting with your regular PRINT USING format template, you just need to go in and enclose each of your used format tokens in curly brackets and give it an index number or letter right in front of the opening bracket.
Have a look on the following examples:
Assuming head = 1, hands = 2 and fingers = 10,
PRINT USING "## head, ## hands and ## fingers"; head, hands, fingers PRINT USING "## fingers, ## head and ## hands"; head, hands, fingers PRINT IndexFormat$("2{##} fingers, 0{##} head and 1{##} hands",_ STR$(head) + "|" + STR$(hands) + "|" + STR$(fingers), "|")These three statements would produce the following output:
" 1 head, 2 hands and 10 fingers" (correct, args order matches the format template) " 1 fingers, 2 head and 10 hands" (wrong, args order doesn't match format template) "10 fingers, 1 head and 2 hands" (indexed, format template picks the right args)Reuse any arguments without providing them multiple times:
PRINT IndexFormat$("0{##} head, 1{##} hands and 2{##} fingers, " +_ "also 1{##} feet and 2{##} toes",_ STR$(head) + "|" + STR$(hands) + "|" + STR$(fingers), "|")This would produce the following output:
" 1 head, 2 hands and 10 fingers, also 2 feet and 10 toes"
The third extension is a small set of new PUFS to format numbers into binary, hexadecimal or octal notation, optional with a given output length. For completeness I've also added decimal (like bin/hex/oct integer only) and real numbers to take a number just as is, hence the way you would get it by calling LTRIM$(STR$(num)). The symbols are B/b, D/d, H/h, O/o and R/r respectively. For hexadecimal the case of the symbol determines whether to use the capital hex letters A-F or the small ones a-f.
The optional output length directly follows the symbol given as decimal number:
0{H8} = hex output (using uppercase letters) extended to 8 digits 0{B16} = binary output extended to 16 digits 0{O} = octal output of variable length (as required) 0{h} = hex output of variable length (using lowercase letters)
As fourth extension, certain format tokens can be prefixed with a special preferences specifier in the form ?p:, where the ? and : are used to uniquely identify the specifier and the p in between is the actual (1-2 chars) preferences setting. The possible settings are (L)eft/(C)enter/(R)ight alignments for strings within a fixed length string field (\\ formatting), of course only if the given string is shorter than the field width. Further grouping of bin/dec/hex/oct outputs is possible in blocks with a certain amount of digits (1-99) and finally the dollar currency sign can be replaced with any other sign (eg. €) and the use of dots and commas can be flipped (,) when needed (for all regular number/currency formatting).
Here some examples for better understanding:
0{?c:\ \} = center string in the specified field (if string < field) 0{?4:B16} = 16 digit binary output in groups of 4 bits (0100 0110 0000 1001) 0{?€:**$#####,.##} = replace the $ sign in the output with the € sign 0{?€,:**$#####,.##} = replace $ sign with € sign, also flip dots and commas 0{?,:###.##} = number without grouping, but comma instead of decimal dot
The fifth and final extension is meant to make the task of writing the format templates somewhat more convenient, especially when it comes to inserting special control chars or extended ASCII chars. This extension easily allows the use of escape sequences as known from C/C++ and other languages.
Using escape sequences within format templates:
fmt$ = "Column-1" + CHR$(9) + "Column-2" (the bulky way adding a tabulator) fmt$ = "Column-1\tColumn-2" (but real easy using the \t sequence) fmt$ = "This is a \x22quoted\x22 section." (quotation with \x22 ASCII code)
SYNTAX:
formatted$ = IndexFormat$ (fmt$, arg$, sep$)
INPUTS:
fmt$ (STRING)
- The format template as usual for PRINT USING, but all format tokens must be indexed, ie. enclosed in curly brackets with a leading one digit index number or letter, which designates the argument to use for the token according to the given arguments order.
- All argument indices may be reused as often as you want.
- Missing arguments will be processed as empty or zero, no error will occur.
- You may also use C/C++ style escape sequences.
\a = CHR$(7) ' audio bell \b = CHR$(8) ' backspace \t = CHR$(9) ' tabulator \n = CHR$(10) 'line feed \v = CHR$(11) 'vertical tabulator \f = CHR$(12) 'form feed \r = CHR$(13) 'carriage return \e = CHR$(27) 'escape \nnn = octal ASCII code ( 3 digits, eg. \042) \xnn = hex ASCII code (x + 2 digits, eg. \x3F)
- Write _{, _} and _\ to get literal curly brackets or a backslash in the output.
- All other format symbols doesn't need to be underscored anymore to make them literals.
- The underscore itself is literal automatically, if not followed by {}\.
- Inside the {} tokens no underscores are allowed at all, these can contain the PRINT USING or the new B/D/H/O/R format symbols only (with or without preferences specifiers).
Finally a feature overview of the new format template:
"Some literal _{text_}: 0{##}. \x221{&}\x22 2{?2:H8}" | | | | | | | \+/ | | | | | | | | | +--+--+ | | +---+---+ preferences specifier | | | | | | | | | escape sequences can be used outside | | | | of the {} formatting tokens | | | | | | | +-- all format symbols must be inside {} | | | | | +---- index of the argument to use for this | | token according to given args order | | | +---- {, } and \ need a leading underscore to get | them as literals in the output, but no other | symbols need the underscore anymore | +---- all other text outside {} is literal and taken as isarg$ (STRING)
- This is a concatenated string of all arguments separated by a user chosen char or string.
- Choose a separator char, which is not used in the arguments itself. If you need all printable chars, then CHR$(0) might be suitable, or you can use a sequence of 2 or more chars which is unique enough to not interfere with the arguments itself, eg. "(+)", "|^|" or similar.
- Use the STR$() function to add in the values of numeric variables.
- It won't hurt, if there are more arguments than used in the format template.
sep$ (STRING)
- The char or string used to separate the arguments in the concatenated argument string.
- Note this is required, even if you pass a single argument only.
RESULT:
formatted$ (STRING)
- Regularly the formatted string as expected.
- If there's a problem with your provided format template, then the output is probably wrong (or at least not as expected), but unlike PRINT USING, this function will always try its best and never throw an Illegal function call error.