Base class for ALib built-in formatters. This class implements abstract method Formatter.format and introduces a set of new abstract methods that have to be implemented by descendants.
The documentation of the class is split into two sections: The first addresses users of descendent classes, the second provides information on how to extend this class to implement a custom formatter.
Documentation For Users Of Derived Classes
The following public fields may be modified with descendent types:
- Derived formatter types will set attributes in fields defaultNumberFormat and alternativeNumberFormat to reflect the default behavior of their formatting syntax.
Users of derived formatters may modify these attributes prior to performing a format operation to change those defaults. While this leads to a deviation of the formatting standard, it may be used instead of providing corresponding syntactic information within each and every replacement field of the format strings. Some modifications may not even be possible with just using the format specification.
- Field writeALibErrorReports defaults to
true
and may be used to disable ALib error reports on illegal formed format strings.
- Field writeErrorsToTargetString defaults to
true
and may be used to disable the writing of of error messages about illegal formed format strings to the target string.
Documentation For Implementing Derived, Custom Formatters
Derived types need to set default values for attributes in fields defaultNumberFormat and alternativeNumberFormat within their constructor once - according to defaults specified by the formatting syntax. This should not be repeated per format operation. This way users of the type are allowed to change such default setting (even if they this may the formatter deviates from the standard it implements).
All fields of this class named with prefix pha
(for example, phaAlignment) together comprise the set of formatting attributes which can be modified by placeholder semantics of the format string. If further attributes are needed, derived types are free to define custom members to store such attributes. Implementations provided with ALib give such extended attributes the prefix phaExt
.
When parsing a placeholder of a format string, abstract method parsePlaceholder may set field phaFormatSpec to reflect a format-specific portion the placeholder string. This then can be checked in an overloaded version of writeCustomFormat. In the Java version of ALib, the default implementation of this method does not forward this to a Java specific, "native" interface as it is done in C# and C++ versions. Instead, the only thing that is done in this method is that the argument is checked for being a date/time object and custom format string is processed using public field dateTimeFormat.
- Note
- This concept (of writing a custom format specification to phaFormatSpec) is implemented with class FormatterPythonStyle as the "Python format mini language" supports such custom format specifications. Class FormatterJavaStyle does not support this mechanism.
The following describes the formatting process in detail (the implementation of method format) and this way helps to understand what is required from the implementation of the abstract methods:
- A newline character check is made and formatting is aborted if one was found (as proposed by contract with parent class).
- Method parameters are stored in fields ptargetString, pformatString, parguments and pargOffset. This way, the parameters can be accessed from any implemented method without the need of passing them as parameters once more.
In addition, field parser is initialized. This Substring is used to parse the format string. Parsed portions will be consumed from the front of the string. Finally fields argsConsumed and nextAutoIdx are initialized to value 0
.
- Start of the loop to find and process placeholders in the format string.
- Abstract method findPlaceholder is invoked. If this fails (no further placeholder was found) parsing stops. If, and only if, a placeholder was found before, the rest of the string in parser is written and abstract method replaceEscapeSequences is invoked for this rest.
- The portion of the format string before the placeholder position is written and abstract method replaceEscapeSequences is invoked on this portion (if not empty).
- Method resetPHAs is invoked, to reset the attributes that will be parsed in the next step. The values that are set are implementation specific and need to reflect the default formatting options if no specific options are given in the format string.
- Abstract Method parsePlaceholder is invoked to parse and consume tokens from string parser and while doing this, to store the parsed format attributes in the fields with name prefix
pha
(or extended attributes of a derived formatter type).
If an argument (positional) index is found during parsing, then method setArgument is to be invoked by abstract method parsePlaceholder providing that index.
If the format syntax of the formatter contains a separated format specification string (a substring of the placeholder string), then the method may store such format substring in field phaFormatSpec.
- Next, it is checked if an argument was set by parsePlaceholder. If not, setArgument is invoked providing
-1
for the index to indicate auto-indexing. - Note
- If auto-indexing should be implemented differently than done with default method setArgument, then a custom formatter might either override the method or, in the case no index is given in the format string, just set fields phaArgument and phaArgumentIdx already in parsePlaceholder according to its own strategy
- Method preAndPostProcess is invoked with parameter startIdx equalling
-1
(indicating pre-processing). This allows for example to insert tab fill-characters (tab stops) prior to writing the contents of the field.
- Method writeCustomFormat is invoked. This allows derived formatters to write arguments in a custom way. If the method returns
true
, the loop is continued ( → Step 4.).
The default implementation checks if a format specification was stored in phaFormatSpec and if yes, if phaArgument represents a date. If so, field dateTimeFormat is used to write the date/time value to the target string and true
is returned.
- Again, if a format specification was stored in phaFormatSpec method parseStdFormatSpec is invoked which needs to set further attributes in the Placeholder object according to to the standard format specification of the formatter.
- Now, as all fields that represent formatting attributes (fields with prefix
pha
) are well set (or kept with their defaulted value), method checkStdFieldAgainstArgument is invoked. This method is virtual but not abstract. Its default implementation checks the placeholder attributes against the provided argument type and raises an error if the argument does not fit to the placeholder format specification.
- Method writeStdArgument is invoked. This method is virtual but not abstract. Its default implementation writes the argument value formatted according to the attribute fields.
- Finally preAndPostProcess is invoked with parameter startIdx pointing to the first character in ptargetString of the argument written. Here, actions like case conversion might be done on the field written.
- End of loop ( → Step 4.)
boolean preAndPostProcess |
( |
int |
startIdx, |
|
|
AString |
target |
|
) |
| |
|
protected |
Virtual method to do pre- and post- processing of the field written. Pre-processing could for example be adding tabulator spaces, letter case conversions,
A negative given index startIdx indicates the pre-processing phase. If target is given, this indicates an "intermediate phase": The argument has been written, but no alignment or cutting has been done, yet. This phase should usually be ignored, but is for example important for search and replacement actions. If a field has a custom format implementation (e.g. time and date values), then the intermediate phase is never called.
- Note
- The reason why this method is not implemented as two different ones is that derived classes might do some more complicated parsing of parts of the placeholder string in this method. In this case, the parsing is needed to be implemented only once, while the finally parsed commands are only conditionally executed depending if executed as pre or post phase.
- Parameters
-
startIdx | If -1 pre-processing is indicated, otherwise post-processing and the index of the start of the field written in ptargetString is given. |
target | The target string, only if different from field ptargetString, which indicates intermediate phase. |
- Returns
false
, if the placeholder should be skipped (nothing is written for it). true
otherwise.
Reimplemented in FormatterPythonStyle, and FormatterJavaStyle.