Fig is a Haskell library for manipulating files in the FIG format (the format used by the Xfig drawing program). Only version 3.2 of the format is supported. To compile the library you will need GHC.
Fig is mostly useful for simple search-and-replace operations that change the file header or the style of individual elements. Operations that insert objects or change their sizes or positions are trickier to implement and are usually easier done in Xfig.
BSD style license.
Files in FIG format are parsed into a syntax tree of type Fig.
The Fig data type and all of its sub elements are defined in
the Graphics.Fig.Syntax module (the Graphics/Fig/Syntax.hs
file). For names of fonts, colors, line styles, etc., refer to this
module.
The layout and naming of the Fig data type is adapted from the
description in the FORMAT3.2 file included with the
Xfig distribution. The best way to get familiar with the meaning of
the different names and units really is the Xfig user interface.
The Fig module exports a parser, a pretty printer, and an interface
for performing search-and-replace operations on Fig values.
The parser converts a string in the FIG format into a value of type
Fig:
parse ::
FilePath -> -- Name of input source (used in error messages).
String -> -- String in FIG format.
Either
String -- Error messages if failed parse.
Fig -- Syntax tree if successful parse.
The pretty printer performs the opposite operation of converting a
Fig value into a string suitable for printing to a FIG file:
pretty ::
Fig -> -- Syntax tree of a FIG file.
String -- String in FIG format.
Search-and-replace operations are specified by a record of type ReplaceDef:
data ReplaceDef =
ReplaceDef
{ headerOrientation :: Orientation -> Orientation
, headerJustification :: Justification -> Justification
, headerUnits :: Units -> Units
, headerPapersize :: PaperSize -> PaperSize
, headerMagnification :: Double -> Double
, headerMultiplePage :: MultiplePage -> MultiplePage
, headerTransparentColor :: Transparent -> Transparent
, headerResolution :: Integer -> Integer
, textColor :: ColorSpec -> ColorSpec
, textFontSize :: Double -> Double
, textFont :: Font -> Font
, textFontFlags :: FontFlags -> FontFlags
, picFlipped :: Flipped -> Flipped
, picFile :: FilePath -> FilePath
, arrowType :: ArrowType -> ArrowType
, arrowStyle :: ArrowStyle -> ArrowStyle
, arrowThickness :: Double -> Double
, arrowWidth :: Double -> Double
, arrowHeight :: Double -> Double
, areaFill :: AreaFill -> AreaFill
, areaFillColor :: ColorSpec -> ColorSpec
, lineStyle :: LineStyle -> LineStyle
, lineThickness :: Integer -> Integer
, linePenColor :: ColorSpec -> ColorSpec
, lineStyleVal :: Double -> Double
, lineCapStyle :: CapStyle -> CapStyle
, lineJoinStyle :: JoinStyle -> JoinStyle
}
Each field of ReplaceDef specifies how attributes of a certain
type should be transformed. The definitions of the types Orientation, Justification, etc., are found in Graphics.Fig.Syntax.
The area and line functions of ReplaceDef apply to all line based objects of the figure. Thus
setting linePenColor = const Pink will change the color of
every line in the figure to pink.
Not all attributes of objects or the FIG file header are included in
ReplaceDef. In particular the attributes do not involve the
layout or positions of individual objects like boxes, ellipses, or
splines.
The value emptyDef is convenient when constructing values of
type ReplaceDef:
emptyDef :: ReplaceDef
emptyDef is the value of type ReplaceDef with every
field set to the identity function id.
The functions of a ReplaceDef value are applied to to the
attributes of a Fig syntax tree by the function applyReplaceDef:
applyReplaceDef ::
ReplaceDef -> -- The replacements to perform.
Fig -> -- A syntax tree of a Fig file.
Fig -- The syntax tree with elements replaced.
The main function below reads a FIG file from stdin and prints the
transformed file to stdout. The program calls a function process to transform the Fig value of the parsed input. If
the parse fails, the program aborts with an error message.
module Main where
import Graphics.Fig
main = do
input <- getContents
either fail succeed
(parse "stdin" input)
where
succeed = putStr . pretty . process
To transform the Fig value we choose to write the process function by help of the ReplaceDef interface:
process = applyReplaceDef replaceDef
The replacement specification selects a font, pen color, and arrow type; the width of arrows are scaled by a factor of 1.5; and a pair of green and blue colors are swapped:
replaceDef =
emptyDef
{ textFontSize = const 14
, textFont = const (Ps HelveticaBold)
, linePenColor = const Magenta
, arrowWidth = (* 1.5)
, arrowType = const Closed
, areaFillColor = x ->
case x of
Green4 -> LtBlue
LtBlue -> Green4
_ -> x
}
The figure shows the effect of running the program for one particular FIG file:
![]() |
![]() |
| Anders Lau Olsen (an...@bergsoe.org) |
Page created Mar 2004, last
updated Aug 2011 |