This package contains the machinery to collect test items, format them appropriately, and output them. The classes here are designed toward that single end. The MTest class provides a place to collect Questions and print them in order, to print only the Problems, only the Answers, or both. The MTestElement interface and MTFI exist to support this.

For users desiring more options, MathTestFormatter is available. It's not quite as easy as MTest but it offers a lot more in the way of flexibility and features. It revolves around a template String and an internal java.util.Properties object used to hold data. The class itself offers a templating engine considerably more advanced than the one offered by Question.fillTemplate().

The maximum flexibility is available through the COFormatter interface and the COFormatterFactory class designed to create them. This allows custom Object formatting for each MathTools class that might require it. By intent COFormatters are written for a specific software package or application and produce formatted Objects usable by it.

Philosophy of MTest-ing

MTest exists as a container for holding Questions. It offers a very Question-centric way to format a test. The MTestElement interface is used specifically for the Question and MTFI classes. Together they form the quickest and easiest way to turn a collection of Questions into a coherent test.

The MTFI class (Math Test Formatting Item) offers a way to add short snippets of text to a test. Think title, course, instructions and such like. There are five types of MTFIs, each intended for a specific purpose. These are, however, text and their use is by no means mandatory.

As far as formatting goes, MTest can format per a specific user-supplied template or it can use the pre-set (or default!) templates. It can format only the Problems, only the Answers or both in turn. MTFI templating is patterned after the Question replacement tokens and they will behave accordingly.

The only change MTest makes when rendering its contents is newline replacement. The newline character sequence can be set to a newline ('/n'), a carriage return ('/r') or both ('/r/n'). If this is changed from the default value (newline only) then every newline in the rendered content is replaced with the selected value. NOTE: This change occurs on rendering only, the original data is NOT affected.

The MTestParser finishes the MTest lineup. It provides the ability to parse simply-structured text into a MTest instance. It also contains a simple macro language for setting formats and handling MTFIs. It can parse data from a raw String, a file or a resource stream from the Math ClassLoader.

MathTestFormatter Use and Philosophy

The MathTestFormatter class presents a more robust and capable templating engine than Question.fillTemplate(). It was written around the idea of creating a (simple String) test template using String-based replacement token syntax (e.g. '${Question_1_Problem}', '@{date}') whose replacement values are stored in a Properties object. This is a test-centric approach versus MTest's question-centric one. It offers more flexibility and capability at the price of slightly more complexity.

A MathTestFormatter-based test starts with the test template itself. All of the constant elements (structure, spacing, instructions, etc.) are prepared first with replacement-token placeholders in place of the things that will change. Once the template is finished the test-generation script is written. The data meant for the test is then added as String key-value pairs to a MathTestFormatter instance (or MTFormatter for scripts). Then, once the data is ready, the template can be set or loaded and the test itself formatted as a whole.

And other things...

MathTestFormatter is a templating engine, albeit simple. That means it can be used for more than simply formatting a math test. It has in place the capability to take a java.sql.ResultSet, generated by MathDBC, and apply a formatting template to each row. The row template is a standard template String with the addition of replacement tokens for each cell (column) in a data row. Although originally conceived as an easy way to generate grade reports it can certainly be used beyond that.

In addition, both template Strings and Properties objects can be loaded from external files or resource streams. This allows multiple templates to be applied to the same data, or multiple data sets to be applied to the same template. This enables automation of many mundane tasks, especially when combined with JDBC and possibly JNDI database access and the MathFileIO class.

Don't forget XML!

None of the MathTestFormatter token syntax 'collides' with XML syntax. This allows an XML document to be designed and written with replacement tokens in place. The resulting document can be parsed, verified, validated, DOM-med, XPath-ed and transformed without worrying about the templating symbols choking the process or being altered by it. The template can be filled at any time. The only concern: XML-escape the content when it's added to the data.

COFormatter, the Ultimate Flexibility

The COFormatter interface and its partner, the COFormatterFactory class, present the maximum in formatting flexibility. The 'CO' stands for 'Custom Object' and the interface is designed to provide specific formatting technology for the various MathTools objects that might need it. The class exists solely to provide implementation classes of the interface with or without the Math ClassLoader.

The interface provides formatting methods for all the core classes that represent actual mathematical entities (Polynomial, MFraction etc.) along with generic formatting methods to cover special cases. The use of context Objects is treated more formally than in the graphing.* package. All of the format() methods return an Object and MathTools assumes that these are ready to go once the method returns.