Implements a Formatter according to the formatting standards of the Python language.
In general, the original Python specification is covered quite well. However, there are some differences, some things are not possible (considering python being a scripting language) but then there are also found some very helpful extensions to that standard. Instead of repeating a complete documentation, please refer to the Python Documentation as the foundation and then take note of the following list of differences, extensions and general hints:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
0
and is incremented each time automatic indexing is used. Occurrences of explict indexing have no influence on the automatic indexing.{:11.5,}
where Python allows only {:11,.5}
','
) can also be used with binary, hexadecimal and octal output. The types support different grouping separators for nibbles, bytes, 16-bit and 32-bit words. Changing the separator symbols, is not possible with the format fields of the format strings (if it was, this would become very incompatible to Python standards). Changes have to be made prior to the format operation by modifying field AlternativeNumberFormat which is provided through parent class FormatterStdImpl.Alternative form ('#'
) adds prefixes as specified in members
For upper case formats, those are taken from field DefaultNumberFormat, for lower case formats from AlternativeNumberFormat. However, in alignment with the Python specification, both default to lower case literals "0b"
, "0o"
and "0x"
. All defaults may be changed by the user.
'f'
and 'e'
), the values specified in attributes ExponentSeparator, NANLiteral and INFLiteral of object AlternativeNumberFormat are used. For upper case types ('F'
and 'E'
) the corresponding attributes in DefaultNumberFormat apply.'f'
and 'F' types) are not supported to use arbitrary length. See class NumberFormat for the limits. Also, very high values and values close to zero may be converted to scientific format. Finally, if flag ForceScientific of field DefaultNumberFormat is true
, types 'f'
and 'F' behave like types 'e'
and 'E'.'#'
("alternate form") for floating point values to not omit trailing zeros of the fractional part even if a fractional width was given. However, in scientific notation and in percentage output (type code '%'
), python never omits trailing zeros.'#'
the the format specification. This way, all numbers written have the same size, independent of the value of their fractional part.'g'
or 'G'
in the python implementation limits the precision of the fractional part, even if precision is not further specified. This implementation does limit the precision only if type is 'f'
or 'F'
.String Conversion:
If type 's'
(or no type) is given in the format_spec of the replacement field, a string representation of the given argument is used. In Java and C# such representation is received by invoking Object.[t|T]oString()
. Consequently, to support string representations of custom types, in these languages the corresponding [t|T]oString() methods of the type have to be implemented.
In this C# implmentation, for the string representation the formatter invokes method Object.ToString
. To support string representations for custom types, this method needs to be implemented for the type in question.
Boolean output:
In extension (and deviation) of the Python specification, format specification type 'B'
is implemented. The word "true" is written if the given value represents a boolean true
value, "false" otherwise.
In the C# language implementation of ALib, in the case the argument is of type bool
, the its value is used. If the argument is an integral type, it is true
if the value is not equal to 0
. Otherwise, the value is true
if the argument is not null
.
'h'
and its upper case version 'H'
is implemented. The hash-values of the argument object is written in hexadecimal format. Options of the type are identical to those of 'x'
, respectively 'X'
.Custom Format Specifications:
With Python
formatting syntax, placeholders have the the following syntax:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
The part that follows the colon is called format_spec. Python passes this portion of the placeholder to a built-in function format()
. Now, each type may interpret this string in a type specific way. But most built-in Python types do it along what they call the "Format Specification Mini Language".
With this implementation, the approach is very similar. The only difference is that the "Format Specification Mini Language" is implemented for standard types right within this class. But before processing format_spec, this class will check if an argument provides a custom implementation for formatting.
In this C# implementation of ALib, custom formatting is done using .Net mechanics and interface IFormattable. For further information see user documentation of parent class FormatterStdImpl.
Conversions:
In the Python placeholder syntax specification:
"{" [field_name] ["!" conversion] [":" format_spec] "}"
symbol '!'
if used prior to the colon ':'
defines what is called the conversion. With Python, three options are given: '!s'
which calls str()
on the value, '!r'
which calls repr()
and '!a'
which calls ascii()
. This is of-course not applicable to this formatter. As a replacement, this class extends the original specification of that conversion using '!'
. The following provides a list of conversions supported. The names given can be abbreviated at any point and ignore letter case, e.g. !Upper
can be !UP
or just !u
. In addition, multiple conversions can be given by concatenating them, each repeating character '!'
.
The conversions supported are:
'"'
around the field. Note that these characters are not respecting any optional given field width but instead are added to such.'<'
is specified, certain characters are converted to escape sequences. If '>'
is given, escape sequences are converted to their (ascii) value. See AString.Escape for details about the conversion that is performed.' '
. It can be changed with optional character 'C' plus the character wanted.#' '
. It can be changed with optional character 'C' plus the character wanted. The tab width defaults to 8
. It can be changed by adding an unsigned decimal number.!ATab[[Cc][NNN]|Reset]
Inserts an "automatic tabulator stop". These are tabulator positions that are stored internally and are automatically extended in the moment the actual contents exceeds the currently stored tab-position. An arbitrary amount of auto tab stop and field width (see !AWith below) values is maintained by the formatter.
Which each new invocation of Formatter.Format, the first auto value is chosen and with each use of !ATab
or !AWidth
, the next value is used.
By default, the fill character is space ' '
. It can be changed with optional character 'C' plus the character wanted. The optional number provided gives the growth value by which the tab will grow if its position is exceeded. This value defaults to 3
. The positions currently stored with the formatter can be reset with providing argument Reset
. Alternatively to this, outside of a formatting process, the tab stops can be reset by invoking method Formatter.Reset.
Both, auto tab and auto width conversions may be used to increase readability of multiple output lines. Of-course, output is not completely tabular, only if those values that result in the biggest sizes are formatted first. If a perfect tabular output is desired, the data to be formatted may be processed twice: Once to temporary buffer which is disposed and then a second time to the desired output AString.
'<'
and '>'
. In the special case that search is empty (<>
), string replace will be inserted if the field argument is an empty string. Public Fields | |
AutoSizes | Sizes = new AutoSizes() |
Public Fields inherited from FormatterStdImpl | |
NumberFormat | AlternativeNumberFormat = new NumberFormat() |
DateTimeFormatInfo | DateTimeFormatProvider = DateTimeFormatInfo.InvariantInfo |
NumberFormat | DefaultNumberFormat = new NumberFormat() |
bool | WriteALibErrorReports = true |
bool | WriteErrorsToTargetString = true |
Public Fields inherited from Formatter | |
Formatter | Next |
Public Methods | |
FormatterPythonStyle () | |
override void | Reset () |
Public Methods inherited from FormatterStdImpl | |
FormatterStdImpl (String formatterClassName) | |
virtual void | CloneSettings (FormatterStdImpl reference) |
Public Methods inherited from Formatter | |
virtual void | Format (AString target, List< Object > args) |
virtual void | Format (AString target, params Object[] args) |
Protected Types | |
enum | ppStates { POSITION = 1, CONVERSION = 2, COLON = 3, FORMAT_SPEC = 4, END = 10 } |
Protected Types inherited from FormatterStdImpl | |
enum | PHType { NotGiven, String, Character, IntBase10, IntBinary, IntOctal, IntHex, Float, Bool, HashCode, Fill } |
Protected Static Fields | |
static char[] | constColonAndClosingBracket = ":}".ToCharArray() |
Protected Static Fields inherited from Formatter | |
static Formatter | defaultFormatter |
static ThreadLock | defaultFormatterLock = new ThreadLock() |
Protected Fields | |
Substring | conversion = new Substring() |
Substring | phaExtConversion = new Substring() |
int | phaExtDefaultPrecision |
int | phaExtPrecision |
Protected Fields inherited from FormatterStdImpl | |
int | argOffset |
int | argsConsumed |
List< Object > | arguments |
AString | fieldBuffer = new AString() |
Substring | formatString = new Substring() |
String | formatterName |
int | nextAutoIdx |
Substring | parser = new Substring() |
Alignment | phaAlignment |
bool | phaAlignmentSpecified |
Object | phaArgument |
int | phaArgumentIdx |
int | phaCutContent |
char | phaFillChar |
Substring | phaFormatSpec = new Substring() |
bool | phaIsPercentage |
NumberFormat | phaNF = new NumberFormat() |
int | phaPreviousArgumentIdx |
bool | phaSignPaddingMode |
PHType | phaType |
char | phaTypeCode |
int | phaWidth |
bool | phaWriteBinOctHexPrefix |
AString | targetString |
int | targetStringStartLength |
Protected Fields inherited from Formatter | |
List< Object > | boxes |
Substring | lamFormatString = new Substring() |
Protected Methods | |
override bool | checkStdFieldAgainstArgument () |
override int | findPlaceholder () |
override void | initializeFormat () |
override bool | parsePlaceholder () |
override bool | parseStdFormatSpec () |
override bool | preAndPostProcess (int startIdx, AString target) |
override void | replaceEscapeSequences (int startIdx) |
override void | resetPHAs () |
Protected Methods inherited from FormatterStdImpl | |
virtual void | errorFormatString (String msg) |
override int | format (AString targetString, Substring formatString, List< Object > arguments, int argOffset) |
virtual bool | setArgument (int pos, bool countStartsWith_1) |
virtual bool | writeCustomFormat () |
virtual void | writeStdArgument () |
Additional Inherited Members | |
Public Static Methods inherited from Formatter | |
static Formatter | AcquireDefault () |
static void | ReleaseDefault () |
|
strongprotected |
States used in parsePlaceholder.
|
inline |
Constructs this formatter. Inherited field DefaultNumberFormat is initialized to meet the formatting defaults of Python.
|
inlineprotectedvirtual |
Makes some attribute adjustments and invokes standard implementation
true
if OK, false
if replacement should be aborted. Reimplemented from FormatterStdImpl.
|
inlineprotectedvirtual |
Searches for '{'
which is not '{{'.
Implements FormatterStdImpl.
|
inlineprotectedvirtual |
|
inlineprotectedvirtual |
Parses placeholder field in python notation. The portion format_spec is not parsed but stored in member Formatter.phaFormatSpec.
true
on success, false
on errors. Implements FormatterStdImpl.
|
inlineprotectedvirtual |
Parses the format specification for standard types as specified in "Format Specification Mini Language".
true
on success, false
on errors. Implements FormatterStdImpl.
|
inlineprotectedvirtual |
Processes "conversions" which are specified with '!'
.
startIdx | The int of the start of the field written in targetString. -1 indicates pre-phase. |
target | The target string, only if different from field targetString, which indicates intermediate phase. |
false
, if the placeholder should be skipped (nothing is written for it). true
otherwise. Reimplemented from FormatterStdImpl.
|
inlineprotectedvirtual |
Implementation of abstract method.
Replaces "{{"
with "{"
and "}}"
with "}"
. In addition applies AString.Escape on target which replaces standard codes like "\\n"
, "\\r"
or "\\t"
with corresponding ascii codes.
startIdx | The start of the region to replace |
Implements FormatterStdImpl.
|
inlineprotectedvirtual |
Invokes parent implementation and then applies some changes to reflect what is defined as default in the Python string format specification.
Reimplemented from FormatterStdImpl.
|
staticprotected |
Constant string array
Reused object used to parse phaExtConversion in method preAndPostProcess.
The portion of the replacement field that represents the conversion specification. This specification is given at the beginning of the replacement field, starting with '!'
.
|
protected |
The default precision if not given. This is set to 6
in resetPHAs, but is changed when specific.
|
protected |
The value read from the precision field. This is set to -1
in resetPHAs.
Storage of sizes for auto-tabulator feature {!ATab} and auto field width feature {!AWidth}