@+c
/** @mainpage Unity
@@author Norman Gray <http://nxg.me.uk>
<p>The Unity package provides a parser for unit strings.</p>
@-
@+java
/**
The Unity package provides a parser for unit strings.
@-

<p><strong>NOTE: The library should currently be regarded as beta quality:
the implementation and interface may change in response to experience
and comments.</strong></p>

<p>This is the unity parser (version @PACKAGE_VERSION@),
which is a
@=java Java class library
@=c    C library
to help parse unit specification strings such as <code>W.mm**-2</code>.
There is also an associated
@=java C library,
@=c    Java class library
which uses the same grammars.
For more details, see
<a href='@LIBRARY_HOMEPAGE@'>the library's home page</a>; the source is on
<a href='https://bitbucket.org/nxg/unity'>bitbucket</a>.</p>

<p>As well as parsing various unit strings, the library can also
serialise a parsed expression in various formats, including the four
formats that it can parse, a LaTeX version with name
<code>latex</code> (which uses the <code>{siunitx}</code> package) and
a <code>debug</code> format which lists the parsed unit in an
unambiguous, but not otherwise useful, form.</p>

@=java <h2>Parsing Units</h2>
@=c    @section intro Parsing Units
<p>You can parse units using a couple of different syntaxes since,
unfortunately, there is no general consensus on which syntax the world
should agree on.  The ones supported
@=c (and their names within this library)
are as follows
@=java (cf {@link uk.me.nxg.unity.Syntax} for the list of parsers)
:
</p>
<dl>
<dt>fits</dt>
<dd>FITS v3.0, section 4.3, W.D. Pence et al., A&amp;A 524, A42, 2010
        <a href='http://dx.doi.org/10.1051/0004-6361/201015362'>doi:10.1051/0004-6361/201015362</a></dd>
<dt>ogip</dt>
<dd><a href='ftp://legacy.gsfc.nasa.gov/fits_info/fits_formats/docs/general/ogip_93_001/ogip_93_001.ps'
>OGIP memo OGIP/93-001, 1993</a></dd>
<dt>cds</dt>
<dd><a href='http://cdsweb.u-strasbg.fr/doc/catstd-3.2.htx'
>Standards for Astronomical Catalogues, Version 2.0, section 3.2, 2000</a></dd>
<dt>vounits</dt>
<dd><a href='http://ivoa.net/Documents/VOUnits/'>IVOA VOUnits Proposed Recommendation</a></dd>
</dl>

<p>See also:</p>
<ul>
<li>The <a href='http://www.iau.org/static/publications/stylemanual1989.pdf'
>IAU style manual, section 5.1 (1989)</a> is by now rather old, but
appears to be one of the few existing standards for units, specific to
astronomy.</li>
<li>ISO/IEC 80000 (parts 1–13) describes a variety of units, including
the specification of the 'binary' prefixes kibi, mebi, and so on (see
ISO/IEC 80000-13 Sect.4,
and IEEE standard 1541-2002).</li>
<li>The VOUnits Recommendation discusses various tradeoffs and
conflicting specifications, at some length.</li>
</ul>


<p>Each of these has an associated <em>writer</em>, which allows you to
write a parsed UnitExpression to a string, in a format which should be
conformant with the particular syntax's standard.
@=java See {@link uk.me.nxg.unity.UnitExpr#toString}.
@=c    See {@link unity_write_formatted}.
</p>

<p>In addition, there is a <em>latex</em> writer, which produces a
formatted form for the the expression, in a form suitable for
inclusion in a LaTeX document, using the <code>siunitx</code>
package.  To use the resulting output in a LaTeX document, include the
following in the preamble of the file:</p>
<pre>
@=java &#92;usepackage{siunitx}
@=java &#92;DeclareSIQualifier&#92;solar{$&#92;odot$}
@=c    \\usepackage{siunitx}
@=c    \\DeclareSIQualifier\\solar{$\\odot$}
</pre>
<p>You may add any <code>siunitx</code> options that seem convenient,
and you may omit the declaration of 
@=java <code>\solar</code>
@=c    <code>\\solar</code>
if the units in the document do not include the various solar ones.</p>

<p>The parsing is permissive, to the extent that it permits non-recognised and deprecated
units.  The result of the parse may be checked for conformance with
one or other standard using
@+java
the methods
{@link uk.me.nxg.unity.UnitExpr#allUnitsRecognised},
{@link uk.me.nxg.unity.UnitExpr#allUnitsRecommended} and
{@link uk.me.nxg.unity.UnitExpr#allUsageConstraintsSatisfied}.
@-
@+c
the functions
{@link unity_check_unit} and
{@link unity_check_expression}.
@-
Note that SI prefixes are still noticed for unrecognised units: thus <code>furlongs/fortnight</code>
will be parsed as femto-urlongs per femto-ortnight.  The same is not
true of recognised units: a <code>pixel/s</code> is a pixel per
second, and does not involve a pico-ixel.</p>

@=java <h3>Demo</h3>
@=c    @subsection demo Demo

@+java
<p>If you want to experiment with the library, you can do so using the jar file:</p>
<pre>
    % java -jar unity.jar -icds -oogip 'mm2/s'
    mm**2 /s
    % java -jar unity.jar -icds -ofits -v mm/s
    mm s-1
    check: all units recognised?           yes
    check: all units recommended?          yes
    check: all units satisfy constraints?  yes
    % java -jar unity.jar -ifits -ocds -v 'merg/s'
    merg/s
    check: all units recognised?           yes
    check: all units recommended?          no
    check: all units satisfy constraints?  no
    % java -jar unity.jar -icds -ofits -v 'merg/s'
    merg s-1
    check: all units recognised?           no
    check: all units recommended?          no
    check: all units satisfy constraints?  yes
</pre>
@-java
@+c
If you want to experiment with the library, build the program
<code>src/c/unity</code> (in the distribution):
<pre>
    % ./unity -icds -oogip 'mm2/s'
    mm**2 /s
    % ./unity -icds -ofits -v mm/s
    mm s-1
    check: all units recognised?           yes
    check: all units recommended?          yes
    check: all units satisfy constraints?  yes
    % ./unity -ifits -ocds -v 'merg/s'
    merg/s
    check: all units recognised?           yes
    check: all units recommended?          no
    check: all units satisfy constraints?  no
    % ./unity -icds -ofits -v 'merg/s'
    merg s-1
    check: all units recognised?           no
    check: all units recommended?          no
    check: all units satisfy constraints?  yes
</pre>
@-c
<p>In the latter cases, the <code>-v</code> option <em>validates</em> the input string
against various constraints.  The expression <code>mm/s</code> is completely valid
in all the syntaxes.  In the FITS syntax, the <code>erg</code> is a recognised
unit, but it is deprecated; although it is recognised, it is not
permitted to have SI prefixes.  In the CDS syntax, the <code>erg</code> is neither
recognised nor (a fortiori) recommended; since there are no
constraints on it in this syntax, it satisfies all of them (this
latter behaviour is admittedly slightly counterintuitive).</p>


@=java <h2>Grammars supported</h2>
@=c    @section grammars Grammars supported

<p>The four supported grammars have a fair amount in common, but the
differences are nonetheless significant enough that they require
separate grammars.  Important differences are in the number of solidi
they allow in the units specifications, and the symbols they use for
products and powers.</p>

<p>Current limitations:</p>
<ul>
<li>Currently ignores some of the odder unit restrictions (such as the OGIP requirement that 'Crab' can have a 'milli' prefix, but no other SI prefixes)</li>
</ul>

<p>In the grammars below, the common terminals are as follows:</p>
<ul>
<li>WHITESPACE: one or more whitespace characters</li>
<li>STAR, DOT: a star or a dot, generally used to indicate multiplication</li>
<li>DIVISION: a slash</li>
<li>STARSTAR, CARET: the former is '**'; both are used to indicate exponentiation</li>
<li>OPEN_P, CLOSE_P: open and close parentheses</li>
<li>INTEGER, FLOAT: numbers; the syntax of FLOAT is
@=java <code>[+-]?[1-9][0-9]*\.[0-9]+</code>
@=c    <code>[+-]?[1-9][0-9]*\\\.[0-9]+</code>,
so that there are no exponents allowed;
the signed integers have a non-optional leading sign, the unsigned don't</li>
<li>STRING: a sequence of upper- and lower-case letters</li>
</ul>
<p>There are some other terminals used in some grammars.
See the VOUnits specification for further details.</p>

@=java <h3>The FITS grammar</h3>
@=c    @subsection grammar-fits The FITS grammar

<pre>
@<../grammar/unity-fits.txt
</pre>

@=java <h3>The OGIP grammar</h3>
@=c    @subsection grammar-ogip The OGIP grammar

<pre>
@<../grammar/unity-ogip.txt
</pre>

@=java <h3>The CDS grammar</h3>
@=c    @subsection grammar-cds The CDS grammar

<p>This is quite similar to the OGIP grammar, but with more
restrictions.</p>
<p>The <code>CDSFLOAT</code> terminal is a string matching the regular
expression
@=java <code>[0-9]+\.[0-9]+x10[-+][0-9]+</code>
@=c    <code>[0-9]+\\\.[0-9]+x10[-+][0-9]+</code>
(that is, something resembling <code>1.5x10+11</code>).
The termainals <code>OPEN_SQ</code> and <code>CLOSE_SQ</code> are opening
and closing square brackets <code>[...]</code>.
</p>
<pre>
@<../grammar/unity-cds.txt
</pre>

@=java <h3>The VOUnits grammar</h3>
@=c    @subsection grammar-vou The VOUnits grammar

<p>The <code>VOUFLOAT</code> and <code>QUOTED_STRING</code> features
are extensions beyond the other grammars.  These aside, this syntax is
a strict subset of the FITS and CDS grammars, in the sense that any
VOUnit unit string, without these extensions, is a valid FITS and CDS
string, too), and it is almost a subset of the OGIP grammar, except
that it uses the dot for multiplication rather than star.</p>
<p>The <code>VOUFLOAT</code> terminal is a string matching either of the
regular expressions
@=java <code>0\.[0-9]+([eE][+-]?[0-9]+)?</code> or
@=java <code>[1-9][0-9]*(\.[0-9]+)?([eE][+-]?[0-9]+)?</code>
@=c    <code>0\\\.[0-9]+([eE][+-]?[0-9]+)?</code> or
@=c    <code>[1-9][0-9]*(\\\.[0-9]+)?([eE][+-]?[0-9]+)?</code>
(that is, something resembling, for example, <code>0.123</code> or
<code>1.5e+11</code>).  Also <code>QUOTED_STRING</code> is a
<code>STRING</code> enclosed in single quotes <code>'...'</code>.</p>
<pre>
@<../grammar/unity-vounits.txt
</pre>

*/
@=java package uk.me.nxg.unity;
