We support the dimensional-unit codes defined in Section 7.2, “Dimensional units”.

Some conversions are exact (e.g., `cm`

to `mm`

and `pc`

to `pt`

), while
others are approximate. We would like to use exact
conversions where possible, so we order the units into a
sequence named `unitList`

, and group units
together if they have exact conversions. We define another
sequence `factorList`

that specifies the
conversion factors between two adjacent units in this
sequence. Then, the problem of converting arbitrary units
reduces to finding the position of the old and new units
within this sequence, and finding the product of the
conversion factors for each step.

fohelpers.py

# - - - F o D i m . c o n f a c t o r (static method) unitList = (UNITS_PC, UNITS_PT, UNITS_IN, UNITS_CM, UNITS_MM) factorList = ( Decimal(12), # 1pc = 12pt Decimal(1)/Decimal('72.27'), # 1pt = 1/72.27in Decimal('2.54'), # 1in = 2.54cm Decimal(10) ) # 1cm = 10mm @staticmethod def confactor(fromUnits, toUnits): '''Find any arbitrary conversion factor. [ fromUnits and toUnits are XSL-FO dimensional units -> return the factor that must be multiplied by a quantity using fromUnits to express it as toUnits ] '''

The first step is to locate the two units by their
position in `unitList`

. Note that this
step will raise `ValueError`

if the units
are not standard XSL-FO units.

fohelpers.py

#-- 1 -- # [ fromPos := position of fromUnits in unitList # toPos := position of toUnits in unitList # result := Decimal(1) ] fromPos = FoDim.unitList.index(fromUnits) toPos = FoDim.unitList.index(toUnits) result = Decimal(1)

To move from lower-numbered units to higher ones,
we multiple the `result`

by the factors
for each step. In the reverse direction, we divide
by those factors. If `fromPos==toPos`

, the
result remains at value 1.0.

fohelpers.py

#-- 2 -- # [ if fromPos < toPos -> # result *:= elements of FoDim.factorList in positions # fromPos, fromPos+1, ..., toPos-1, inclusive # else if fromPos > toPos -> # result /:= elements of FoDim.factorList in positions # fromPos-1, fromPos-2, ..., toPos, inclusive ] if fromPos < toPos: for pos in range(fromPos, toPos): result *= FoDim.factorList[pos] elif fromPos > toPos: for pos in range(fromPos-1, toPos-1, -1): result /= FoDim.factorList[pos] #-- 3 -- return result