Next / Previous / Contents / Shipman's homepage

27.9. FoDim.confactor(): Find a conversion factor

The purpose of this static method is to find the conversion factor to be used in converting a dimension to different units.

First, unitList is a sequence of the five unit codes, arranged in a sequence in which units with an exact conversion factor are adjacent (picas next to points, and millimeters next to centimeters) when possible.

The sequence factorList is set up so that element factorList[i] is the factor that must be used to convert from a dimension in terms of unitList[i] to a dimension in terms of unitList[i+1].

Then in order to derive a net conversion factor, we find the positions of the desired old and new units in unitList. If the new units are past the old units, we find the product of the factors between them; if the new units are before the old units, we find the inverse of the product of the factors between them.

fosox.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 ]
        '''
        #-- 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)

        #-- 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

For a test script that exercises all possible conversions, see Section 41, “confactest: Test driver for FoDim unit conversions”.