diff --git a/Config.hs b/Config.hs
--- a/Config.hs
+++ b/Config.hs
@@ -4,8 +4,6 @@
 import Data.Configurator
 import Data.Configurator.Types (Value (..),Configured (..))
 import System.IO.Unsafe
-import Data.Traversable
-import Control.Applicative
 
 data List a = L [a]
 
diff --git a/Literate.hs b/Literate.hs
new file mode 100644
--- /dev/null
+++ b/Literate.hs
@@ -0,0 +1,27 @@
+module Literate where
+
+import Data.Monoid
+import Data.DList hiding (foldr, map)
+import MarXupParser
+import Data.List (isPrefixOf)
+import Output
+
+----------------------------------------------
+-- Top-level generation
+
+rHaskells :: [Haskell] -> Doc
+rHaskells xs = mconcat $ map rHaskell xs
+
+rHaskell :: Haskell -> DList Char
+rHaskell (HaskLn pos) = oPos pos <> text "\n"
+rHaskell (Quote xs) = mconcat $ map rMarxup xs
+rHaskell _ = mempty
+
+rMarxup :: MarXup -> Doc
+rMarxup (Unquote _ [(_,HaskChunk fct),(position,Quote code)]) | "haskell" `isPrefixOf` fct = oPos position <> foldMap rInlineHask code
+rMarxup _ = mempty
+
+rInlineHask :: MarXup -> Doc
+rInlineHask (TextChunk x) = text x
+rInlineHask _ = mempty
+
diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,35 @@
+import Text.ParserCombinators.Parsek.Position
+
+import System.Environment
+import Data.Monoid
+import Data.DList hiding (foldr, map)
+import MarXupParser
+import qualified Literate as Lit
+import Output
+
+rHaskells :: [Haskell] -> Doc
+rHaskells xs = mconcat $ map rHaskell xs
+
+rHaskell :: Haskell -> DList Char
+rHaskell (HaskChunk s) = text s
+rHaskell (HaskLn pos) = oPos pos
+rHaskell (Quote xs) = parens $ oConcat $ map rMarxup xs
+rHaskell (List xs) = brackets $ rHaskells xs
+rHaskell (Parens xs) = parens $ rHaskells xs
+rHaskell (String xs) = doubleQuotes $ text xs
+
+rArg :: (SourcePos, Haskell) -> Doc
+rArg (pos,h) = oPos pos <> parens (rHaskell h)
+
+rMarxup :: MarXup -> Doc
+rMarxup (TextChunk s) = oText s
+rMarxup (Unquote var val) =
+  maybe mempty (\(pos,x) -> oPos pos <> text (x <> "<-")) var <>
+  text "element" <+> parens (hcat $ map rArg val)
+rMarxup (Comment _) = mempty
+
+main :: IO ()
+main = do
+  x : y : z : _ <- getArgs
+  parseFile y $ \res -> writeFile z $ render (rHaskells res <> Lit.rHaskells res)
+
diff --git a/Main3.hs b/Main3.hs
deleted file mode 100644
--- a/Main3.hs
+++ /dev/null
@@ -1,188 +0,0 @@
-{-# LANGUAGE TupleSections, FlexibleInstances, TransformListComp #-}
-import Text.ParserCombinators.Parsek.Position
-
-import Data.Char
-import Data.List
-import System.IO
-import System.Environment
-import Control.Monad
-import Data.DList hiding (map,foldr)
-import Data.Monoid
-import GHC.Exts (the,groupWith)
-import Config
-
--- todo: parse haskell comments
-
-------------------
--- Simple printing combinators, which do not add nor remove line breaks
-
-type Doc = DList Char
-
-text = fromList
-x <+> y =  x <> text " " <> y
-oChar = singleton
-parens s = oChar '(' <> s <> oChar ')'
-braces s = oChar '{' <> s <> oChar '}'
-brackets s = oChar '[' <> s <> oChar ']'
-doubleQuotes s = oChar '"' <> s <> oChar '"'
-
-int x = text $ show x
-hcat :: [Doc] -> Doc
-hcat = foldr (<>) mempty
-punctuate t = map (<> t)
-render :: Doc -> String
-render = toList
-
-------------------------------------------
--- Output combinators
-
-oPos :: SourcePos -> Doc
-oPos EOF = mempty
-oPos p = text "{-# LINE" <+> int (sourceLine p) <+> text (show (sourceName p)) <+> text "#-}"
-
-oText :: String -> Doc
-oText x = text "textual" <+> text (show x)
-
-oMappend :: [Doc] -> Doc
-oMappend [] = text "(return ())"
-oMappend [x] = parens x
-oMappend l = text "do" <+> braces (text "rec" <+> braces (hcat (punctuate (text ";") binds)) <> text ";" <> ret)
-  where binds = init l
-        ret = last l
-
-----------------------------------------------
--- Parsing helpers
-
-satisfy' :: (String -> Bool) -> Parser Char
-satisfy' p = do
-  l <- look
-  unless (p l) $
-    fail "Unexpected leading string"
-  anySymbol
-
-munch',munch1' :: (String -> Bool) -> Parser String
-munch' p = scan =<< look
- where
-  scan (c:cs) | p (c:cs) = (:) <$> anySymbol <*> scan cs
-  scan _            = pure []
-
-munch1' p = (:) <$> satisfy' p <*> munch' p
-
--- | A chunck not containing some strings
-pChunk' :: [String] -> Parser String
-pChunk' stops = munch1' (\l -> not $ any (`isPrefixOf` l) stops)
-
-
--- | A chunk not containing some chars.
-pChunk :: [Char] -> Parser String
-pChunk stops = munch1 (not . (`elem` stops))
-
-----------------------------------------------
--- Parsing combinators
-
-anyQuoteStrings :: [String]
-anyQuoteStrings = concatMap (\(x,y) -> [x,y]) quoteStrings
-
-pTextChunk = oText <$> pChunk' ("\n" : commentString : antiQuoteStrings ++ anyQuoteStrings) <?> "Text chunk"
-pHaskChunk = text <$> pChunk' (map box "\n\"[]()" ++ map fst quoteStrings) <?> "Haskell chunk"
-    -- we keep track of balancing
-
-pWPos :: Parser Doc
-pWPos = do
-  char '\n'
-  pos <- getPosition
-  return $ oPos pos <> text "\n"
-
-pHaskLn = pWPos -- before each newline, tell GHC where we are.
-pTextLn = (oText "\n" <>) <$> pWPos
-  -- add code to output a newline; and insert a newline in the code.
-
-box = (:[])
-
-pString :: Parser Doc
-pString = do
-  char '"'
-  result <- many (string "\\\"" <|> pChunk ['"'])
-  char '"'
-  return $ doubleQuotes . hcat . map text $ result
-
--- | Parse some Haskell code with markup inside.
-pHask :: Parser Doc
-pHask =
-  (hcat <$> many ((brackets <$> pArg "[]") <|>
-                  (parens   <$> pArg "()") <|>
-                  (parens   <$> pTextArg ) <|> pString <|> pHaskChunk <|> pHaskLn))
-
--- | Parse a text argument to an element
-pTextArg' :: String -> String -> Parser Doc
-pTextArg' open close = label "quoted text" $
-  string open *>
-  (oMappend <$> many (pElement <|> pTextChunk <|> pTextLn <|> pComment))
-  <* string close
-
-pTextArg :: Parser Doc
-pTextArg = choice $ map (uncurry pTextArg') quoteStrings
-
-pArg :: String -> Parser Doc
-pArg [open,close] = char open *> pHask <*  char close
-
-isIdentChar :: Char -> Bool
-isIdentChar x = isAlphaNum x || (x `elem` "\'_")
-
-pIdent :: Parser Doc
-pIdent = text <$> munch1 isIdentChar <?> "identifier"
-
-pArgument :: Parser Doc
-pArgument = (pArg "()" <|> (brackets <$> pArg "[]") <|> pTextArg <|> pString) <?> "argument"
-
-pElement :: Parser Doc
-pElement = label "Haskell element" $ do
-  choice $ map string $ antiQuoteStrings
-  var <- ((<+> text "<-") <$> (pIdent <* string "<-")) <<|> pure mempty
-  val <- ((:) <$> pIdent <*> manyGreedy pArgument) <|> (box <$> pArg "()")
-  return $ var <> text "element" <+> parens (hcat $ fmap parens val)
-
-commentString :: String
-commentString = "%%"
-
-pComment :: Parser Doc
-pComment = label "Comment" $ do
-  string commentString
-  munch (/= '\n')
-  string "\n"
-  return mempty
-
-main :: IO ()
-main = do
-  x : y : z : _ <- getArgs
-  putStrLn x
-  putStrLn y
-  putStrLn z
-  p <- parseFromFile (pHask <* endOfFile) completeResults y
-  case p of
-    Left e -> handleErr e
-    Right [res] -> writeFile z $ render res
-    Right _ -> hPutStrLn stderr "Amibiguous input!"
-
-handleErr e =
-   sequence_
-          [ hPutStrLn stderr (show $ maybePosToPos $ the pos) >>
-            hPutStrLn stderr ("  Expected:" ++ (intercalate " or " $ nub what))
-           | (exps,_why) <- e, (what,pos) <- exps, then group by pos using groupWith, then reverse ]
-
-instance Show (DList Char) where
-  show x = show $ render x
-
-
--- Tests
-testHask = parse "<interactive>" pHask completeResults "arst « text @z<-fct[x](y) awft"
-testHask2 = parse "<interactive>" pHask completeResults "ars(t) « text @z<-fct[x](y) » awft"
-testText2 = parse "<interactive>" pTextArg completeResults "« text @fct(x »"
-testText3 = parse "<interactive>" pTextArg completeResults "« 1 @x 2 @y 3 @x 4 »"
-testElem = parse "<interactive>" pElement completeResults "@x<-fct(x « yop »)[y]"
-testChunk = parse "<interactive>" pHaskChunk completeResults "t"
-testArg = parse "<interactive>" (pArg "()") completeResults "()"
-
-terr e  = case e of
-    Left x -> handleErr x
-    Right [res] -> putStrLn $ render res
diff --git a/MarXup/DerivationTrees.hs b/MarXup/DerivationTrees.hs
--- a/MarXup/DerivationTrees.hs
+++ b/MarXup/DerivationTrees.hs
@@ -1,19 +1,15 @@
-{-# LANGUAGE DisambiguateRecordFields, NamedFieldPuns, RecordWildCards, PostfixOperators, LiberalTypeSynonyms, TypeOperators, OverloadedStrings, PackageImports #-}
+{-# LANGUAGE DisambiguateRecordFields, NamedFieldPuns, RecordWildCards, PostfixOperators, LiberalTypeSynonyms, TypeOperators, OverloadedStrings, PackageImports, ScopedTypeVariables #-}
 
 module MarXup.DerivationTrees (
 -- * Basics
 module Data.Monoid,
 module Data.LabeledTree,
 
--- * Derivation' building
--- axiom, rule, etc, aborted, 
-emptyDrv, haltDrv, haltDrv', delayPre,
-dummy, rule, Derivation, Premise, Rule(..), 
-
--- * Links
-LineStyle,defaultLink,Link(..),
-
 -- * Engine
+haltDrv,
+module Graphics.Diagrams.DerivationTrees,
+
+-- * Frontend
 derivationTree, derivationTreeD
 
 ) where
@@ -21,60 +17,27 @@
 -- import DerivationTrees.Basics
 import Data.List
 import Control.Monad.Writer 
-import Control.Applicative 
 import Data.LabeledTree
 import Data.Monoid
 import MarXup (element)
 import MarXup.Tex hiding (label)
-import MarXup.MultiRef
-import MarXup.Diagram as D
-import qualified Data.Tree as T
-------------------
---- Basics
-
-type LineStyle = PathOptions -> PathOptions
-
-data Link = Link {label :: Tex (), linkStyle :: LineStyle, steps :: Int}  -- ^ Regular link
-          | Delayed -- ^ automatic delaying
-
-defaultLink :: Link
-defaultLink = Link mempty (denselyDotted . outline "black")  0
-
-
--------------------
-
-data Rule = Rule {ruleStyle :: LineStyle, delimiter :: Tex (), ruleLabel :: Tex (), conclusion :: Tex ()}
---  deriving Show
-
-type Premise = Link ::> Derivation
-type Derivation = Tree Link Rule
-
---------------------------------------------------
--- Delay
-
-depth (Link{steps} ::> Node _ ps) = 1 + steps + maximum (0 : map depth ps)
-
-isDelayed :: Premise -> Bool
-isDelayed (Delayed{} ::> _) = True
-isDelayed _ = False
+import Graphics.Diagrams.DerivationTrees
+import MarXup.Diagram
 
-delayPre s (Link {..} ::> j) = Link {steps = s, ..} ::> j
+----------------------------------------------------------
+-- Tikzify
 
-delayD :: Derivation -> Derivation
-delayD (Node r ps0) = Node r (map delayP ps)
-    where ps = fmap (fmap delayD) ps0
-          ps' = filter (not . isDelayed) ps
-          delayP (Delayed{..} ::> d) = defaultLink {steps = 1 + maximum (0 : map depth ps')} ::> d
-          delayP p = p
+derivationTreeD :: Derivation TeX -> TeX
+derivationTreeD d = element $ (derivationTreeDiag $ delayD d :: TexDiagram ())
 
 ----------------------------------------------------------
 -- TeXify
   
--- | Render a derivation tree without using metapost drv package (links will not be rendered properly)
-derivationTree :: Derivation -> TeX
+-- | Render a derivation tree using simple latex only (links will not be rendered properly)
+derivationTree :: Derivation TeX -> TeX
 derivationTree = stringizeTex
 
-stringizeTex :: Derivation -> TeX
+stringizeTex :: Derivation TeX -> TeX
 stringizeTex (Node Rule {..} premises) = braces $ do
   cmd0 "displaystyle" -- so that the text does not get smaller
   cmdn "frac" [mconcat $
@@ -84,145 +47,7 @@
   braces $ do cmd0 "small"
               ruleLabel
 
-----------------------------------------------------------
--- Tikzify
-
-derivationTreeD :: Derivation -> Tex ()
-derivationTreeD d = element $ derivationTreeDiag $ delayD d
-
-derivationTreeDiag :: Derivation -> Diagram ()
-derivationTreeDiag d = do
-  [h] <- newVars [ContVar] -- the height of a layer in the tree.
-  minimize h
-  h >== 1
-  tree@(T.Node (_,n,_) _) <- toDiagram h d
-  forM_ (T.levels tree) $ \ls ->
-    case ls of
-      [] -> return ()
-      (_:ls') -> forM_ (zip ls ls') $ \((_,_,l),(r,_,_)) ->
-        (l + Point 10 0) `westOf` r
-  let leftFringe = map head nonNilLevs
-      rightFringe = map last nonNilLevs
-      nonNilLevs = filter (not . null) $ T.levels tree
-  [leftMost,rightMost] <- newVars [ContVar,ContVar]
-  forM_ leftFringe $ \(p,_,_) ->
-    leftMost <== xpart p
-  forM_ rightFringe $ \(_,_,p) ->
-    xpart p <== rightMost
-  minimize $ 10 *- (rightMost - leftMost)
-  n # Center .=. Point 0 0
-
-toDiagPart :: Expr -> Premise -> Diagram (T.Tree (Point,Anchorage,Point))
-toDiagPart layerHeight (Link{..} ::> rul)
-  | steps == 0 = toDiagram layerHeight rul
-  | otherwise = do
-    above@(T.Node (_,concl,_) _) <- toDiagram layerHeight rul
-    ptObj <- vrule
-    let pt = ptObj # S
-    pt `eastOf` (concl # W)
-    pt `westOf` (concl # E)
-    xpart pt =~= xpart (concl # Center)
-    let top = ypart (concl # S)
-    ypart pt + (fromIntegral steps *- layerHeight) === top
-    using linkStyle $ path $ polyline [ptObj # Base,Point (xpart pt) top]
-    let embedPt 1 x = T.Node (concl # W,ptObj,concl # E) [x]
-        embedPt n x = T.Node (pt,ptObj,pt) [embedPt (n-1) x]
-    return $ embedPt steps above
-
--- | @chainBases distance objects@
--- - Ensures that all the objects have the same baseline.
--- - Separates the objects by the given distance
--- - Returns an object encompassing the group, with a the baseline set correctly.
--- - Returns the average distance between the objects
-   
-chainBases :: Expr -> [Anchorage] -> Diagram (Anchorage,Expr)
-chainBases _ [] = do
-  o <- box
-  return (o,0)
-chainBases spacing ls = do
-  grp <- box
-  forM_ [Base,N,S] $ \ anch -> do
-    D.align ypart $ map (# anch) (grp:ls)
-  dxs <- forM (zip ls (tail ls)) $ \(x,y) -> do
-    let dx = xdiff (x # E) (y # W)
-    dx >== spacing
-    return dx
-  D.align xpart [grp # W,head ls # W]
-  D.align xpart [grp # E,last ls # E]
-  return (grp,avg dxs)
-
--- | Make an horizontally flexible box of glue.
-mkHGlue :: Expr -> Expr -> Diagram Anchorage
-mkHGlue minimumWidth preferredWidth = do
-  g <- box
-  width g >== minimumWidth
-  width g =~= preferredWidth
-  return g
-
--- | Put object in a box of the same vertical extent, and baseline,
--- but whose height can be bigger.
-relaxHeight o = do
-  b <- box
-  -- using (outline "green")$ traceBounds o
-  D.align xpart [b#W,o#W]
-  D.align xpart [b#E,o#E]
-  D.align ypart [b#Base,o#Base]
-  o `fitsVerticallyIn` b
-  return b
-
-toDiagram :: Expr -> Derivation -> Diagram (T.Tree (Point,Anchorage,Point))
-toDiagram layerHeight (Node Rule{..} premises) = do
-  ps <- mapM (toDiagPart layerHeight) premises
-  concl <- relaxHeight =<< extend 1.5 <$> texBox conclusion
-  -- using (outline "red")$ traceBounds concl
-  lab <- texBox ruleLabel
-
-  -- Grouping
-  (psGrp,premisesDist) <- chainBases 10 [p | T.Node (_,p,_) _ <- ps]
-  -- using (outline "blue" . denselyDotted) $ traceBounds psGrp
-  height psGrp === layerHeight
-
-  -- Sepaartion rule
-  separ <- hrule
-  separ # N .=. psGrp # S
-  align ypart [concl # N,separ # S]
-  minimize $ width separ
-  psGrp `fitsHorizontallyIn` separ
-  concl `fitsHorizontallyIn` separ
-
-  -- rule label
-  lab # BaseW .=. separ # E + Point 3 (negate 1)
-
-
-  -- layout hints (not necessary for "correctness")
-  let xd = xdiff (separ # W) (psGrp # W)
-  xd   === xdiff (psGrp # E) (separ # E) 
-  relax 2 $ (2 *- xd) =~= premisesDist
-  -- centering of conclusion
-  xd' <- absoluteValue $ xdiff (separ # Center) (concl # Center)
-  relax 3 $ minimize xd'
-
-  -- draw the rule.
-  localPathOptions ruleStyle $ path $ polyline [separ # W,separ # E]
-  return $ T.Node (separ # W, concl, lab # E) ps
-
------------------------
-
-
-rule ruleLabel conclusion = Rule {delimiter = mempty, ruleStyle = outline "black", ..}
-
-dummy :: Rule
-dummy = (rule mempty mempty) {ruleStyle = const defaultPathOptions}
-emptyDrv = Node dummy []
-
--- abortDrv (Node Rule {..} _) = Node Rule {ruleStyle = Waved, ..} []
-
--- | Used when the rest of the derivation is known.
-haltDrv' :: Tex () -> Derivation -> Derivation
-haltDrv' tex (Node r _) = Node r {ruleStyle = noOutline}
-     [defaultLink {steps = 1, label = tex} ::> emptyDrv]
-
--- | More compact variant
-haltDrv :: Tex () -> Derivation -> Derivation
+-- -- | More compact variant
+haltDrv :: TeX -> Derivation TeX -> Derivation TeX
 haltDrv t (Node r _) = Node r [defaultLink ::> Node dummy {conclusion = cmd "vdots" nil >> cmd "hspace" (tex "2pt") >> t} []]
 
diff --git a/MarXup/Diagram.hs b/MarXup/Diagram.hs
--- a/MarXup/Diagram.hs
+++ b/MarXup/Diagram.hs
@@ -1,7 +1,4 @@
 module MarXup.Diagram (module D) where
 
-import MarXup.Diagram.Layout as D
-import MarXup.Diagram.Path as D
-import MarXup.Diagram.Point  as D
-import MarXup.Diagram.Object as D
+import Graphics.Diagrams as D
 import MarXup.Diagram.Tikz as D
diff --git a/MarXup/Diagram/Graphviz.hs b/MarXup/Diagram/Graphviz.hs
deleted file mode 100644
--- a/MarXup/Diagram/Graphviz.hs
+++ /dev/null
@@ -1,109 +0,0 @@
-{-# LANGUAGE RecordWildCards #-}
-module MarXup.Diagram.Graphviz (graph) where
-
-import MarXup.Tex
-import MarXup.Diagram.Point as D
-import MarXup.Diagram.Object as D
-import MarXup.Diagram.Tikz as D
-import MarXup.Diagram.Layout
-import MarXup.Diagram.Path
-import Data.GraphViz as G
-import Data.GraphViz.Attributes.Complete as G
-import Data.GraphViz.Parsing as G
-import qualified Data.GraphViz.Types.Generalised as Gen
-import Data.GraphViz.Commands.IO as G
--- import qualified Data.Text.Lazy.Internal as T
-import qualified Data.Text.Lazy as T
-import System.IO.Unsafe (unsafePerformIO)
--- import Data.Traversable
-import Data.Foldable
-import Control.Lens (set)
-
-graph :: (PrintDotRepr g n, ParseDot n, PrintDot n) => GraphvizCommand -> g n -> Dia
-graph cmd gr = graphToDiagram $ layout cmd gr
-
-layout :: (PrintDotRepr g n, ParseDot n, PrintDot n) => GraphvizCommand -> g n -> Gen.DotGraph n
-layout command input = parseIt' $ unsafePerformIO $ graphvizWithHandle command input DotOutput hGetStrict 
-
-pos (Pos p) = Just p
-pos _= Nothing
-
-lpos (LPos p) = Just p
-lpos _= Nothing
-
-shapeA (Shape s) = Just s
-shapeA _ = Nothing
-
-widthA (Width s) = Just s
-widthA _ = Nothing
-
-labelA (Label l) = Just l
-labelA _ = Nothing
-
-arrowHeadA (ArrowHead a) = Just a
-arrowHeadA _ = Nothing
-
-readAttr :: Monad m => (Attribute -> Maybe a) -> [Attribute] -> (a -> m ()) -> m ()
-readAttr f as k = readAttr' f as k (return ())
-
-readAttr' :: (Attribute -> Maybe a) -> [Attribute] -> (a -> k) -> k -> k
-readAttr' f as k1 k2 = case [x | Just x <- map f as] of
-  (x:_) -> k1 x
-  _ -> k2
-
-
-pt' (G.Point x y _z _forced) = D.Point x y
-pt = unfreeze . pt'
-
-diaSpline (w:x:y:z:rest) = curveSegment w x y z:diaSpline (z:rest)
-diaSpline _ = []
-
--- ToTip | CircleTip | NoTip | StealthTip | LatexTip | ReversedTip LineTip | BracketTip | ParensTip
-tipTop def (AType [(_,NoArrow)]) = NoTip
-tipTop def (AType [(_,Normal)]) = LatexTip
-tipTop def (AType [(_,DotArrow)]) = CircleTip
-tipTop def (AType [(_,Vee)]) = StealthTip
-tipTop def _ = def
-
-renderLab l p = do
-  l' <- labelObj $ tex $ T.unpack $ l
-  l' # D.Center .=. pt p
-
-graphToDiagram :: Gen.DotGraph n -> Dia
-graphToDiagram (Gen.DotGraph _strict _directed _grIdent stmts) = do
-  forM_ stmts $ \ stmt -> case stmt of
-    (Gen.DE (DotEdge _from _to attrs)) -> do
-      diaRaw $ "%Edge: " ++ show attrs ++ "\n"
-      let toTip = readAttr' arrowHeadA attrs (tipTop ToTip) ToTip
-      readAttr labelA attrs $ \(StrLabel l) ->
-        readAttr lpos attrs $ \p -> 
-        renderLab l p
-      readAttr pos attrs $ \(SplinePos splines) ->
-        forM_ splines $ \Spline{..} -> do
-          let mid = diaSpline $ map pt' splinePoints
-          let beg = case (startPoint,splinePoints) of
-                (Just p,q:_) -> [lineSegment (pt' p) (pt' q)]
-                _ -> []
-          let end = case (endPoint,reverse splinePoints) of
-                (Just p,q:_) -> [lineSegment (pt' q) (pt' p)]
-                _ -> []
-          using (set endTip toTip) $
-            draw $ frozenPath $ fromBeziers (beg ++ mid ++ end)
-
-    (Gen.DN (DotNode _nodeIdent attrs)) -> do
-      diaRaw $ "%Node: " ++ show attrs ++ "\n"
-      readAttr pos   attrs $ \(PointPos p) -> do
-        readAttr labelA attrs $ \l -> do
-          case l of
-            StrLabel l -> renderLab l p
-        readAttr widthA attrs $ \w ->
-         readAttr shapeA attrs $ \s ->
-          case s of
-            Circle -> do
-              draw $ path $ circle (pt p) (constant $ inch (w/2))
-            _ -> return ()
-    _ -> return ()
-
-inch x = 72 * x
-
-
diff --git a/MarXup/Diagram/Layout.hs b/MarXup/Diagram/Layout.hs
deleted file mode 100644
--- a/MarXup/Diagram/Layout.hs
+++ /dev/null
@@ -1,203 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RecursiveDo, TypeFamilies, OverloadedStrings, RecordWildCards,UndecidableInstances, PackageImports, TemplateHaskell #-}
-
-module MarXup.Diagram.Layout (module MarXup.Diagram.Layout) where
-import Control.Monad.LPMonad
-import Prelude hiding (sum,mapM_,mapM,concatMap)
-import Control.Monad.RWS hiding (forM,forM_,mapM_,mapM)
-import Data.LinearProgram
-import Data.LinearProgram.Common as MarXup.Diagram.Layout (VarKind(..)) 
-import Data.LinearProgram.LinExpr
-import Data.Map (Map)
-import qualified Data.Map as M
-import Control.Lens hiding (element)
-import Data.String
--- import MarXup
-import Data.Traversable
-import Data.Foldable
-import Control.Applicative
-import System.IO.Unsafe
-import MarXup.MultiRef
-import MarXup.Tex
-
-type LPState = LP Var Constant
-
-type Solution = Map Var Double
-type Constant = Double
-
--- | Expressions are linear functions of the variables
-type Expr = LinExpr Var Constant
-
-newtype Decoration = Decoration String
-data LineTip = ToTip | CircleTip | NoTip | StealthTip | LatexTip | ReversedTip LineTip | BracketTip | ParensTip
-type Color = String
-data LineCap = ButtCap | RectCap | RoundCap
-data LineJoin = MiterJoin | RoundJoin | BevelJoin
-type DashPattern = [(Constant,Constant)]
-data PathOptions = PathOptions
-                     {_drawColor :: Maybe Color
-                     ,_fillColor :: Maybe Color
-                     ,_lineWidth :: Constant
-                     ,_startTip  :: LineTip
-                     ,_endTip    :: LineTip
-                     ,_lineCap   :: LineCap
-                     ,_lineJoin  :: LineJoin
-                     ,_dashPattern :: DashPattern
-                     ,_decoration :: Decoration
-                     }
-$(makeLenses ''PathOptions)
-
-data Env = Env {_diaSolution :: Solution
-               ,_diaTightness :: Constant -- ^ Multiplicator to minimize constraints
-               ,_diaPathOptions :: PathOptions}
-
-$(makeLenses ''Env)
-
-defaultPathOptions :: PathOptions
-defaultPathOptions = PathOptions
-  {_drawColor = Nothing
-  ,_fillColor = Nothing
-  ,_lineWidth = 0.4
-  ,_startTip  = NoTip
-  ,_endTip    = NoTip
-  ,_lineCap   = ButtCap
-  ,_lineJoin  = MiterJoin
-  ,_dashPattern = []
-  ,_decoration = Decoration ""
-  }
-
-newtype Diagram a = Dia (RWST Env () (Var,LPState) Multi a)
-  deriving (Monad, Applicative, Functor, MonadReader Env)
-
-type Dia = Diagram ()
-
-instance MonadState LPState Diagram where
-  get = Dia $ snd <$> get
-  put y = Dia $ do
-    (x,_) <- get
-    put (x,y)
-
--------------
--- Diagrams
-
-runDiagram :: Diagram a -> Multi a
-runDiagram (Dia diag) = do
-  rec (a,(_,problem),_) <- runRWST diag (Env solution 1 defaultPathOptions)
-                                        (Var 0,LP Min M.empty [] M.empty M.empty)
-      let solution = case unsafePerformIO $ glpSolveVars simplexDefaults problem of
-            (_retcode,Just (_objFunc,s)) -> s
-            (retcode,Nothing) -> error $ "ret code = " ++ show retcode
-  -- Raw Normal $ "%problem solved: " ++ show problem ++ "\n"
-  return a
-
-diaRawTex :: Tex a -> Diagram a
-diaRawTex (Tex t) = Dia $ lift t
-
-diaRaw :: String -> Dia
-diaRaw = diaRawTex . tex
-
-relax factor = local (over diaTightness (/ factor)) 
-
-instance Monoid (Diagram ()) where
-  mempty = return ()
-  mappend = (>>)
-
-instance IsString (Diagram ()) where
-  fromString = diaRawTex . tex
-
---------------
--- Variables
-varValue :: Var -> Diagram Double
-varValue v = M.findWithDefault 0 v <$> view diaSolution
-
-rawNewVar :: Diagram Var
-rawNewVar = Dia $ do
-      (Var x,y) <- get
-      put $ (Var (x+1),y)
-      return $ Var x
-
-newVars :: [VarKind] -> Diagram [Expr]
-newVars kinds = newVars' (zip kinds (repeat Free))
-
-newVars' :: [(VarKind,Bounds Constant)] -> Diagram [Expr]
-newVars' kinds = forM kinds $ \(k,b) -> do
-  v <- rawNewVar
-  setVarKind v k
-  setVarBounds v b
-  return $ variable v
-
-infix 4 <==,===,>==
-
-----------------
--- Expressions
-instance Fractional Expr where
-  fromRational ratio = constant (fromRational ratio)
-
-instance Num Expr where
-  fromInteger x = LinExpr M.empty (fromInteger x)
-  negate = neg
-  (+) = (^+^)
-  (-) = (^-^)
-
-valueOf :: Expr -> Diagram Double
-valueOf (LinExpr m c) = do
-  vs <- forM (M.assocs m) $ \(v,scale) ->
-    (scale *) <$> varValue v
-  return $ sum $ c:vs
-
-variable :: Var -> Expr
-variable v = LinExpr (var v) 0
-
-constant :: Constant -> Expr
-constant c = LinExpr M.empty c
-
-(*-) :: Module Constant a => Constant -> a -> a
-(*-) = (*^)
-infixr 6 *-
-
-avg :: Module Constant a => [a] -> a
-avg xs = (1/fromIntegral (length xs)) *- gsum xs
-
-absoluteValue :: Expr -> Diagram Expr
-absoluteValue x = do
-  [t1,t2] <- newVars' [(ContVar,LBound 0),(ContVar,LBound 0)]
-  t1 - t2 === x
-  return $ t1 + t2
-
-satAll :: (Expr -> a -> Diagram b) -> [a] -> Diagram Expr
-satAll p xs = do
-  [m] <- newVars [ContVar]
-  mapM_ (p m) xs
-  return m
-
-maximVar, minimVar :: [Expr] -> Diagram Expr
-maximVar = satAll (>==)
-minimVar = satAll (<==)
-
---------------
--- Expression constraints
-(>==), (<==) :: Expr -> Expr -> Diagram ()
-e1 <== e2 = do
-  let LinExpr f c = e1 - e2
-  leqTo f (negate c)
-
-(>==) = flip (<==)
-
-(===) :: Expr -> Expr -> Diagram ()
-e1 === e2 = do
-  let LinExpr f c = e1 - e2
-  equalTo f (negate c)
-
--- | minimize the distance between expressions
-(=~=) :: Expr -> Expr -> Diagram ()
-x =~= y = minimize =<< absoluteValue (x-y)
-
--------------------------
--- Expression objectives
-
-minimize,maximize :: Expr -> Diagram ()
-minimize (LinExpr x _) = do
-  tightness <- view diaTightness
-  addObjective (tightness *- x)
-maximize = minimize . negate
-
-
diff --git a/MarXup/Diagram/Object.hs b/MarXup/Diagram/Object.hs
deleted file mode 100644
--- a/MarXup/Diagram/Object.hs
+++ /dev/null
@@ -1,266 +0,0 @@
-{-# LANGUAGE DataKinds, KindSignatures, OverloadedStrings, EmptyDataDecls, MultiParamTypeClasses, FlexibleContexts, OverlappingInstances, TypeSynonymInstances, FlexibleInstances   #-}
-
-module MarXup.Diagram.Object where
-
--- import MarXup
-import MarXup.Tex
-import MarXup.Diagram.Tikz
-import MarXup.Diagram.Path
-import MarXup.Diagram.Point
-import MarXup.Diagram.Layout
-import MarXup.MultiRef (BoxSpec(..))
-import Control.Monad
-import Control.Applicative
--- import Data.Algebra
--- import Data.List (intersperse)
-import Control.Lens (set)
-
-data Anchor = Center | N | NW | W | SW | S | SE | E | NE | BaseW | Base | BaseE
-  deriving Show
-
--- | Box-shaped object. (a subtype)
-type Box = Object
-
-newtype Anchorage = Anchorage {boxAnchors :: Anchor -> Point}
-data Object = Object {objectOutline :: Path, objectAnchorage :: Anchorage}
-
-class Anchored a where
-  anchors :: a -> Anchor -> Point
-infix 8 #
-
-(#) :: Anchored a => a -> Anchor -> Point
-(#) = anchors
-
-instance Anchored Anchorage where
-  anchors = boxAnchors
-
-instance Anchored Object where
-  anchors = anchors . objectAnchorage
-
-instance Anchored Point where
-  anchors p _ = p
-
--- | Horizontal distance between objects
-hdist :: Anchored a => a -> a -> Expr
-hdist x y = xpart (y # W - x # E)
-
--- | Vertical distance between objects
-vdist :: Anchored a => a -> a -> Expr
-vdist x y = ypart (y # S - x # N)
-
--- | Extend the box boundaries by the given delta
-extend :: Expr -> Anchorage -> Anchorage
-extend e o = Anchorage $ \a -> o # a + shiftInDir a e
-
--- | Makes a shift of size 'd' in the given direction.
-shiftInDir :: Anchor -> Expr -> Point
-shiftInDir N d = 0 `Point` d
-shiftInDir S d = 0 `Point` negate d
-shiftInDir W d = negate d `Point` 0
-shiftInDir E d  = d `Point` 0
-shiftInDir NW d = negate d `Point` d
-shiftInDir SE d = d `Point` negate d
-shiftInDir SW d = negate d `Point` negate d
-shiftInDir NE d = d `Point` d
-shiftInDir _ _  = 0 `Point` 0
-
--- | Make a label object. This is just some text surrounded by 4
--- points of blank.
-mkLabel :: TeX -> Diagram Anchorage
-mkLabel texCode = extend 4 <$> texBox texCode
-
-labelObj :: TeX -> Diagram Box
-labelObj = rectangleShape <=< mkLabel
-
--- | Label a point by a given TeX expression, at the given anchor.
-labelPt :: TeX -> Anchor -> Point -> Diagram Box
-labelPt labell anchor labeled  = do
-  t <- labelObj labell 
-  t # anchor .=. labeled
-  return t
-
--- | A free point
-point :: Diagram Point
-point = do
-  [x,y] <- newVars (replicate 2 ContVar)
-  return $ Point x y
-
--- | A point anchorage (similar to a box of zero width and height)
-pointBox :: Diagram Anchorage
-pointBox = do
-  p <- point
-  return $ Anchorage $ \a -> case a of _ -> p
-
--- | A box. Anchors are aligned along a grid.
-box :: Diagram Anchorage
-box = do
-  [n,s,e,w,base,midx,midy] <- newVars (replicate 7 ContVar)
-  n >== base
-  base >== s
-  w <== e
-  
-  midx === avg [w,e]
-  midy === avg [n,s]
-  let pt = flip Point
-  return $ Anchorage $ \anch -> case anch of
-    NW     -> pt n    w
-    N      -> pt n    midx
-    NE     -> pt n    e  
-    E      -> pt midy e
-    SE     -> pt s    e
-    S      -> pt s    midx
-    SW     -> pt s    w
-    W      -> pt midy w
-    Center -> pt midy midx
-    Base   -> pt base midx
-    BaseE  -> pt base e
-    BaseW  -> pt base w
-
--- | A box of zero width
-vrule :: Diagram Anchorage
-vrule = do
-  o <- box
-  align xpart [o # W, o #Center, o#E]
-  return o
-
--- | A box of zero height
-hrule :: Diagram Anchorage
-hrule = do
-  o <- box
-  height o === 0
-  return o
-
-height o = ypart (o # N - o # S)
-width o = xpart (o # E - o # W)
-ascent o = ypart (o # N - o # Base)
-descent o = ypart (o # Base - o # S)
-
--- fitsVerticallyIn :: Anchorage -> Anchorage -> Diagram ()
-o `fitsVerticallyIn` o' = do
-  let dyN = ypart $ o' # N - o # N
-      dyS = ypart $ o # S - o' # S
-  minimize dyN
-  dyN >== 0
-  minimize dyS
-  dyS >== 0
-
--- fitsHorizontallyIn :: Anchorage -> Anchorage -> Diagram ()
-o `fitsHorizontallyIn` o' = do
-  let dyW = xpart $ o # W - o' # W
-      dyE = xpart $ o' # E - o # E
-  minimize dyW
-  dyW >== 0
-  minimize dyE
-  dyE >== 0
-
-a `fitsIn` b = do
-  a `fitsHorizontallyIn` b
-  a `fitsVerticallyIn` b
-
-circleShape :: Diagram Object
-circleShape = do
-  anch <- box
-  width anch === height anch
-  let radius = 0.5 *- width anch
-  let p = circle (anch # Center) radius
-  path p
-  return $ Object p anch
---   let k1 :: Constant
---       k1 = sqrt 2 / 2
---       k = k1 *^ r
---       p = circle center r
---   return $ Object p $ Anchorage $ \a -> center + case a of
---     N -> Point 0 r
---     S -> Point 0 (-r)
---     E -> Point r 0
---     W -> Point (-r) 0
---     Center -> Point 0 0
---     NE -> Point k k
-
-rectangleShape :: Anchorage -> Diagram Object
-rectangleShape l = do
-  let p = polygon (map (l #) [NW,NE,SE,SW])
-  path p
-  return $ Object p l
-
-traceAnchorage :: Anchored a => Color -> a -> Diagram ()
-traceAnchorage c l = do
-  stroke c $ path $ polygon (map (l #) [NW,NE,SE,SW])
-  -- TODO: draw the baseline, etc.
-
--- | Typeset a piece of text and return its bounding box.
-texBox :: TeX -> Diagram Anchorage
-texBox t = do
-  l <- box
-  -- traceAnchorage "red" l
-  BoxSpec wid h desc <- drawText (l # NW) t
-
-  width   l === constant wid
-  descent l === constant desc
-  height  l === constant (h + desc)
-  return l
-
-data Incidence = Incidence { incidencePoint, incidenceNormal :: Point }
-swap :: Incidence -> Incidence
-swap (Incidence p v) = Incidence p (negate v)
-
--- | Traces a straight edge between two objects.
--- The midpoint is returned, as well as a normal vector.
-edge :: Object -> Object -> Diagram Incidence
-edge source target = do
-  let points@[a,b] = [source # Center,target # Center]
-      link = polyline points
-      targetArea = objectOutline target
-      sourceArea = objectOutline source
-  l' <- freeze link
-  sa' <- freeze sourceArea
-  ta' <- freeze targetArea
-  frozenPath $ (l' `cutAfter` ta') `cutBefore` sa'
-  return $ Incidence (avg points) (rotate90 (b-a))
-
-(.<.) :: Point -> Point -> Diagram ()
-Point x1 y1 .<. Point x2 y2 = do
-  x1 <== x2
-  y1 <== y2
-
--- | Forces the point to be inside the (bounding box) of the object.
-inside :: Point -> Box -> Diagram ()
-inside p o = do
-  (o # SW) .<. p
-  p .<. (o # NE)
-
--- | @autoLabel label i@ Layouts the label at the given incidence
--- point.
-autoLabel :: Box -> Incidence -> Diagram ()
-autoLabel lab (Incidence pt norm) = do
-  pt `inside` lab
-  minimize =<< orthoDist (lab#Center) (pt + norm)
-
--- | @labeledEdge label source target@
-labeledEdge :: Object -> Object -> Box -> Diagram ()
-labeledEdge source target lab = autoLabel lab =<< edge source target
-
-
-
--------------------
--- Even higher-level primitives:
-
-
---example:      spread hdist 30 ps
-
-spread f d (x:y:xs) = do
-  f x y === d
-  spread f d (y:xs)
-spread f _ _ = return ()
-
-node lab = do
-  l <- extend 4 <$> texBox lab
-  c <- draw $ circleShape
-  l `fitsIn` c
-  l # Center .=. c # Center
-  return c
-
-arrow :: Object -> Object -> Diagram Incidence
-arrow src trg = using (outline "black" . set endTip LatexTip) $ do
-  edge src trg
-
diff --git a/MarXup/Diagram/Path.hs b/MarXup/Diagram/Path.hs
deleted file mode 100644
--- a/MarXup/Diagram/Path.hs
+++ /dev/null
@@ -1,156 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RecursiveDo, TypeFamilies, OverloadedStrings, RecordWildCards,UndecidableInstances, PackageImports, TemplateHaskell #-}
-
-module MarXup.Diagram.Path where
-
-import MarXup.Diagram.Layout
-import MarXup.Diagram.Point
-import Data.Traversable
-import Data.Foldable
-import Data.Algebra
--- import Data.Traversable
--- import Data.Foldable
-import Graphics.Typography.Geometry.Bezier
-import Graphics.Typography.Geometry.Bezier as MarXup.Diagram.Point (Curve) 
-import Control.Applicative
-import Data.List (sort,transpose)
-import Data.Maybe (listToMaybe)
-import Prelude hiding (sum,mapM_,mapM,concatMap,maximum,minimum)
-import qualified Data.Vector.Unboxed as V
-import Algebra.Polynomials.Bernstein (restriction,Bernsteinp(..))
-
-type Frozen x = x Constant
-type FrozenPoint = Frozen Point'
-type FrozenPath = Frozen Path'
-
-freeze :: Traversable t => t Expr -> Diagram (t Constant)
-freeze = traverse valueOf
-
-unfreeze :: Functor t => t Constant -> t Expr
-unfreeze = fmap constant
-
-toBeziers :: FrozenPath -> [Curve]
-toBeziers EmptyPath = []
-toBeziers (Path start ss) | not (null ss) &&
-                            isCycle (last ss) = toBeziers' start (init ss ++ [StraightTo start])
-                          | otherwise = toBeziers' start ss
-
-curveSegment (Point xa ya) (Point xb yb) (Point xc yc) (Point xd yd) = bezier3 xa ya xb yb xc yc xd yd
-lineSegment (Point xa ya) (Point xb yb) = line xa ya xb yb
-
-toBeziers' :: FrozenPoint -> [Frozen Segment] -> [Curve]
-toBeziers' _ [] = []
-toBeziers' start (StraightTo next:ss) = curveSegment start mid mid next : toBeziers' next ss
-  where mid = avg [start, next]
-toBeziers' p (CurveTo c d q:ss) = curveSegment p c d q : toBeziers' q ss
-
-fromBeziers :: [Curve] -> FrozenPath
-fromBeziers [] = EmptyPath
-fromBeziers (Bezier cx cy t0 t1:bs) = case map toPt $ V.foldr (:) [] cxy of
-      [p,c,d,q] -> Path p (CurveTo c d q:rest)
-      [p,q] -> Path p (StraightTo q:rest)
-  where [cx',cy'] = map (\c -> coefs $ restriction c t0 t1) [cx,cy]
-        cxy = V.zip cx' cy'
-        toPt (x,y) = Point x y
-        rest = pathSegments (fromBeziers bs)
-
-pathSegments :: Path' t -> [Segment t]
-pathSegments EmptyPath = []
-pathSegments (Path _ ss) = ss
-
-isCycle Cycle = True
-isCycle _  = False
-
-frozenPointElim (Point x y) f = f x y
-
-splitBezier (Bezier cx cy t0 t1) (u,v,_,_) = (Bezier cx cy t0 u, Bezier cx cy v t1)
-
-clipOne :: Curve -> [Curve] -> Maybe Curve
-clipOne b cutter = fmap firstPart $ listToMaybe $ sort $ concatMap (inter b) cutter
-  where firstPart t = fst $ splitBezier b t
-
--- | @cutAfter path area@ cuts the path after its first intersection with the @area@.
-cutAfter', cutBefore' :: [Curve] -> [Curve] -> [Curve]
-cutAfter' [] _cutter = []
-cutAfter' (b:bs) cutter = case clipOne b cutter of
-  Nothing -> b:cutAfter' bs cutter
-  Just b' -> [b']
-
-revBernstein (Bernsteinp n c) = Bernsteinp n (V.reverse c)
-revBeziers :: [Curve] -> [Curve]
-revBeziers = reverse . map rev
-  where rev (Bezier cx cy t0 t1) = (Bezier (revBernstein cx) (revBernstein cy) (1-t1) (1-t0))
-
-cutBefore' path area = revBeziers $ cutAfter' (revBeziers path) area
-
-onBeziers :: ([Curve] -> [Curve] -> [Curve])
-             -> FrozenPath -> FrozenPath -> FrozenPath
-onBeziers op p' q' = fromBeziers $ op (toBeziers p') (toBeziers q')
-
-
-cutAfter :: FrozenPath -> FrozenPath -> FrozenPath
-cutAfter = onBeziers cutAfter'
-
-cutBefore :: FrozenPath -> FrozenPath -> FrozenPath
-cutBefore = onBeziers cutBefore'
-
-data Segment v = CurveTo (Point' v) (Point' v) (Point' v)
-                   | StraightTo (Point' v)
-                   | Cycle
-                   -- | Rounded (Maybe Constant)
-                   -- | HV point | VH point
-  deriving (Show,Eq)
-instance Functor Segment where
-  fmap = fmapDefault
-  
-instance Foldable Segment where
-  foldMap = foldMapDefault
-instance Traversable Segment where
-  traverse _ Cycle = pure Cycle
-  traverse f (StraightTo p) = StraightTo <$> traverse f p
-  traverse f (CurveTo c d q) = CurveTo <$> traverse f c <*> traverse f d <*> traverse f q
-  
-
------------------
--- Paths
-
-type Path = Path' Expr
-
-data Path' a
-  = EmptyPath
-  | Path {startingPoint :: Point' a
-         ,segments :: [Segment a]}
-  deriving Show
-
--- mapPoints :: (Point' a -> Point' b) -> Path' a -> Path' b
-instance Functor Path' where
-  fmap = fmapDefault
-
-instance Foldable Path' where
-  foldMap = foldMapDefault
-instance Traversable Path' where
-  traverse _ EmptyPath = pure EmptyPath
-  traverse f (Path s ss) = Path <$> traverse f s <*> traverse (traverse f) ss
-
-
-polyline :: [Point] -> Path
-polyline [] = EmptyPath
-polyline (x:xs) = Path x (map StraightTo xs)
-
-polygon :: [Point] -> Path
-polygon [] = EmptyPath
-polygon (x:xs) = Path x (map StraightTo xs ++ [Cycle])
-
-
--- | Circle approximated with 4 cubic bezier curves
-circle :: Point -> Expr -> Path
-circle center r =      Path (pt r 0)
-                         [CurveTo (pt r k) (pt k r) (pt 0 r),
-                          CurveTo (pt (-k) r) (pt (-r) k) (pt (-r) 0),
-                          CurveTo (pt (-r) (-k)) (pt (-k) (-r)) (pt 0 (-r)),
-                          CurveTo (pt k (-r)) (pt r (-k)) (pt r 0),
-                          Cycle]
- where k1 :: Constant
-       k1 = 4 * (sqrt 2 - 1) / 3
-       k = k1 *^ r
-       pt x y = center ^+^ (Point x y)
-
diff --git a/MarXup/Diagram/Point.hs b/MarXup/Diagram/Point.hs
deleted file mode 100644
--- a/MarXup/Diagram/Point.hs
+++ /dev/null
@@ -1,96 +0,0 @@
-{-# LANGUAGE TypeSynonymInstances, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RecursiveDo, TypeFamilies, OverloadedStrings, RecordWildCards,UndecidableInstances, PackageImports, TemplateHaskell #-}
-
-module MarXup.Diagram.Point where
-
-import MarXup.Diagram.Layout
-import Data.Traversable
-import Data.Foldable
-import Data.Algebra
-import Control.Applicative
-import Data.List (transpose)
-import Prelude hiding (sum,mapM_,mapM,concatMap,maximum,minimum)
-
-infix 4 .=.
-----------------
--- Points 
--- | A point in 2d space
-data Point' a = Point {xpart :: a, ypart :: a}
-  deriving (Eq,Show)
-
-instance Traversable Point' where
-  traverse f (Point x y) = Point <$> f x <*> f y
-
-instance Foldable Point' where
-  foldMap = foldMapDefault
-
-instance Functor Point' where
-  fmap = fmapDefault
-
-  
-type Point = Point' Expr
-instance Group a => Num (Point' a) where
-  negate = neg
-  (+) = (^+^)
-  (-) = (^-^)
-
-instance Group v => Group (Point' v) where
-  zero = Point zero zero
-  Point x1 y1 ^+^ Point x2 y2 = Point (x1 ^+^ x2) (y1 ^+^ y2)
-  neg (Point x y) = Point (neg x) (neg y)
-
-instance Module Constant v => Module Constant (Point' v) where
-  k *^ Point x y = Point (k *^ x) (k *^ y)
-
--- | Orthogonal norm of a vector
-orthonorm :: Point -> Diagram Expr
-orthonorm (Point x y) =
-  (+) <$> absoluteValue x <*> absoluteValue y
-
--- | Orthogonal distance between points.
-orthoDist :: Point -> Point -> Diagram Expr
-orthoDist p q = orthonorm (q-p)
-
--- | Rotate a vector 90 degres in the trigonometric direction.
-rotate90, rotate180 :: Point -> Point
-rotate90 (Point x y) = Point (negate y) x
-
-rotate180 = rotate90 . rotate90
-
-xdiff,ydiff :: Point -> Point -> Expr
-xdiff p q = xpart (q - p)
-ydiff p q = ypart (q - p)
-
------------------
--- Point constraints
-
-(.=.),northOf,southOf,westOf,eastOf :: Point -> Point -> Diagram ()
-Point x1 y1 .=. Point x2 y2 = do
-  x1 === x2
-  y1 === y2
-
-northOf (Point _ y1) (Point _ y2) = y2 <== y1
-southOf = flip northOf
-westOf (Point x1 _) (Point x2 _) = x1 <== x2
-eastOf = flip westOf
-
-alignHoriz,alignVert :: [Point] -> Diagram ()
-alignHoriz = align ypart
-alignVert = align xpart
-
-align :: (a -> Expr) -> [a] -> Diagram ()
-align _ [] = return ()
-align f (p:ps) = forM_ ps $ \p' -> f p === f p'
-
-alignMatrix :: [[Point]] -> Dia
-alignMatrix ls = do
-  forM_ ls alignHoriz
-  forM_ (transpose ls) alignVert
-
----------------------
--- Point objectives
-
-southwards, northwards, westwards, eastwards :: Point -> Diagram ()
-southwards (Point _ y) = minimize y
-westwards (Point x _) = minimize x
-northwards = southwards . negate
-eastwards = westwards . negate
diff --git a/MarXup/Diagram/Tikz.hs b/MarXup/Diagram/Tikz.hs
--- a/MarXup/Diagram/Tikz.hs
+++ b/MarXup/Diagram/Tikz.hs
@@ -1,145 +1,67 @@
-{-# LANGUAGE TypeSynonymInstances, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RecursiveDo, TypeFamilies, OverloadedStrings, RecordWildCards,UndecidableInstances, PackageImports, TemplateHaskell #-}
+{-# LANGUAGE TypeSynonymInstances, FlexibleContexts, FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RecursiveDo, TypeFamilies, OverloadedStrings, RecordWildCards,UndecidableInstances, PackageImports, TemplateHaskell, RankNTypes #-}
 
 module MarXup.Diagram.Tikz where
 
-import MarXup.Diagram.Layout
-import MarXup.Diagram.Point
-import MarXup.Diagram.Path
-import Control.Lens hiding (element)
+import Graphics.Diagrams.Core
+import Graphics.Diagrams.Path
 import Prelude hiding (sum,mapM_,mapM,concatMap)
-import Control.Applicative
 import Data.List (intercalate)
-import Data.String
 import MarXup
-import MarXup.MultiRef
+import MarXup.MultiRef (newLabel)
 import MarXup.Tex
 import Numeric (showFFloat)
-import Data.Traversable
 import Data.Foldable
 import Data.Monoid
-import Control.Monad.Reader
 
-instance Element Expr where
-  type Target Expr = Dia
-  element x = do
-    v <- valueOf x
-    diaRaw $ showDistance v
+type TexDiagram = Diagram TeX Tex
 
-instance Element (Diagram ()) where
-  type Target (Diagram ()) = TeX
+instance Element (Diagram TeX Tex ()) where
+  type Target (Diagram TeX Tex ()) = TeX
   element d = do
    texLn "" -- otherwise beamer does not understand where a tikzpicture ends (?!!)
    braces $ do
-    cmd0 "normalsize"
-      -- otherwise the boxes use "normalsize", while tikz inherits
-      -- the smaller or bigger size from the current scope. Actually,
-      -- every text styling should be reset, but I don't know how to
-      -- do that.
+    usepkg "tikz" 100 []
     env "tikzpicture" $
-      Tex $ runDiagram d
-
---------------------
--- Point rendering
-instance Element Point where
-  type Target Point = Diagram ()
-  element (Point x y) = "(" <> element x <> "," <> element y <> ")"
-
-diaDebug msg = diaRaw $ "\n%DBG:" ++ msg ++ "\n"
-
-instance (Element (Point' v),Monoid (Target (Point' v)), IsString (Target (Point' v))) => Element (Segment v) where
-  type Target (Segment v) = Target (Point' v)
-  element (StraightTo p) = "--" <> element p
-  element (CurveTo c d p) = "..controls" <> element c <> "and" <> element d <> ".." <> element p
-  element Cycle = "--cycle"
-  -- element (VH p) = "|-" <> element p
-  -- element (HV p) = "-|" <> element p
-  -- element (Rounded Nothing) = "[sharp corners]"
-  -- element (Rounded (Just r)) = "[" <> element (constant r) <> "]"
-
-instance Element Path where
-  type Target Path = Diagram ()
-  element = path
+      runDiagram tikzBackend d
 
-path :: Path -> Dia
-path = frozenPath <=< freeze
+-- diaDebug msg = diaRaw $ "\n%DBG:" ++ msg ++ "\n"
+class Tikz a where
+  toTikz :: a -> String
 
-frozenPath :: FrozenPath  -> Dia
-frozenPath p  = do
-  options <- view diaPathOptions
-  diaRaw $ "\\path"
-    <> element options
-    <> case p of
-      EmptyPath -> ""
-      (Path start segs) -> element start ++ concatMap element segs
-  diaRaw ";\n"
+instance Tikz FrozenPoint where
+  toTikz (Point x y) =  "(" <> showDistance x <> "," <> showDistance y <> ")"
 
+instance Tikz (Frozen Segment) where
+  toTikz (StraightTo p) = "--" <> toTikz p
+  toTikz (CurveTo c d p) = "..controls" <> toTikz c <> "and" <> toTikz d <> ".." <> toTikz p
+  toTikz Cycle = "--cycle"
+  -- toTikz (VH p) = "|-" <> toTikz p
+  -- toTikz (HV p) = "-|" <> toTikz p
+  -- toTikz (Rounded Nothing) = "[sharp corners]"
+  -- toTikz (Rounded (Just r)) = "[" <> toTikz (constant r) <> "]"
 
 showDistance :: Constant -> String
 showDistance x = showFFloat (Just 4) x tikzUnit
     where tikzUnit = "pt"
 
-instance Element FrozenPoint where
-  type Target FrozenPoint = String
-  element pt = frozenPointElim pt $ \x y -> "(" <> showDistance x <> "," <> showDistance y <> ")"
-
-
------------------
--- Path Options
-
-localPathOptions :: (PathOptions -> PathOptions) -> Diagram a -> Diagram a
-localPathOptions f = local (over diaPathOptions f)
-
-instance Show LineTip where
-  show t = case t of
+instance Tikz LineTip where
+  toTikz t = case t of
     ToTip -> "to"
     StealthTip -> "stealth"
     CircleTip -> "o"
     NoTip -> ""
     LatexTip -> "latex"
-    ReversedTip x -> show x ++ " reversed"
+    ReversedTip x -> toTikz x ++ " reversed"
     BracketTip -> "["
     ParensTip -> "("
 
-
-ultraThin, veryThin, thin, semiThick, thick, veryThick, ultraThick :: Constant
-ultraThin = 0.1
-veryThin = 0.2
-thin = 0.4
-semiThick = 0.6
-thick = 0.8
-veryThick = 1.2
-ultraThick = 1.6
-
-
 showDashPat :: DashPattern -> String
 showDashPat xs = intercalate " " ["on " <> showDistance on <>
                                   " off " <> showDistance off | (on,off) <- xs]
 
-solid             o@PathOptions{..} = o { _dashPattern = [] }
-dotted            o@PathOptions{..} = o { _dashPattern = [(_lineWidth,2)] }
-denselyDotted     o@PathOptions{..} = o { _dashPattern = [(_lineWidth, 1)] }
-looselyDotted     o@PathOptions{..} = o { _dashPattern = [(_lineWidth, 4)] }
-dashed            o@PathOptions{..} = o { _dashPattern = [(3, 3)] }
-denselyDashed     o@PathOptions{..} = o { _dashPattern = [(3, 2)] }
-looselyDashed     o@PathOptions{..} = o { _dashPattern = [(3, 6)] }
-dashdotted        o@PathOptions{..} = o { _dashPattern = [(3, 2), (_lineWidth, 2)] }
-denselyDashdotted o@PathOptions{..} = o { _dashPattern = [(3, 1), (_lineWidth, 1)] }
-looselyDashdotted o@PathOptions{..} = o { _dashPattern = [(3, 4), (_lineWidth, 4)] }
-
-using = localPathOptions
-stroke color = using (outline color)
-draw = stroke "black"
-
-noOutline = set drawColor Nothing
-outline color = set drawColor (Just color)
-fill color = set fillColor (Just color)
-
-zigzagDecoration = set decoration (Decoration "zigzag")
-
-instance Element PathOptions where
-  type Target PathOptions = String
-  element PathOptions{..} = "["
-    <> show _startTip <> "-" <> show _endTip <> ","
+instance Tikz PathOptions where
+  toTikz PathOptions{..} = "["
+    <> toTikz _startTip <> "-" <> toTikz _endTip <> ","
     <> col "draw" _drawColor
     <> col "fill" _fillColor
     <> "line width=" <> showDistance _lineWidth <> ","
@@ -158,15 +80,28 @@
     <> "]"
     where col attr = maybe "" (\c -> attr <> "=" <> c <> ",")
 
-----------
--- Text
-
-drawText :: Point -> TeX -> Diagram BoxSpec
-drawText point t = do
-  diaRawTex $ tex $ "\\node[anchor=north west,inner sep=0] at "
-  element point
-  (_,box) <- diaRawTex $ inBox $ braces $ t
-  diaRawTex $ tex ";\n"
-  return box
+tikzBackend :: Backend TeX Tex
+tikzBackend = Backend {..} where
+  _tracePath options p = do
+     tex $ "\\path"
+       <> toTikz options
+       <> case p of
+         EmptyPath -> ""
+         (Path start segs) -> toTikz start ++ concatMap toTikz segs
+     tex ";\n"
+  _traceLabel :: Monad x =>
+                   (location -> (FrozenPoint -> Tex ()) -> x ()) -> -- freezer
+                   (forall a. Tex a -> x a) -> -- embedder
+                   location ->
+                   Tex () -> -- label specification
+                   x BoxSpec
+  _traceLabel freezer embedder point lab = do
+       bxId <- embedder $ Tex newLabel
+       freezer point $ \p' -> do
+         tex $ "\\node[anchor=north west,inner sep=0] at " ++ toTikz p'
+         fillBox bxId True $ braces $ lab
+         tex ";\n"
+       embedder $ getBoxFromId bxId
 
 
+type Dia = TexDiagram ()
diff --git a/MarXup/Latex.hs b/MarXup/Latex.hs
--- a/MarXup/Latex.hs
+++ b/MarXup/Latex.hs
@@ -3,14 +3,12 @@
 
 import MarXup
 import MarXup.Verbatim
-import Control.Monad (forM_)
+import Control.Monad (forM_,when,forM)
 import MarXup.Tex
-import Data.List (intersperse,groupBy,elemIndex,nub)
+import Data.List (intersperse,groupBy,elemIndex,nub,intercalate)
 import Data.Monoid
-import Control.Applicative
 import Data.Function (on)
 
-
 -- | Separate the arguments with '\\'
 mkrows,mkcols :: [TeX] -> TeX
 mkrows ls = sequence_ $ intersperse newline ls
@@ -19,35 +17,37 @@
 mkcols = sequence_ . intersperse newcol
 
 vspace, hspace :: String -> TeX
-vspace = cmd "vspace" . textual
-hspace = cmd "hspace" . textual
+vspace = cmd "vspace" . tex
+hspace = cmd "hspace" . tex
+
+hfill :: TeX
 hfill = cmd0 "hfill"
 
 title :: TeX -> TeX
 title = cmd "title"
 
-
-data ClassFile = Plain | LNCS | SIGPlan | IEEE | EPTCS | Beamer
-  deriving Eq
 type AuthorInfoStyle = ClassFile
 
 data AuthorInfo = AuthorInfo {authorName :: String, authorEmail :: String, authorInst :: String}
 
--- | author info in as triplets name, institution, email
-authorinfo :: AuthorInfoStyle -> [AuthorInfo] -> TeX
-authorinfo LNCS as = do
+authorinfo :: [AuthorInfo] -> Tex ()
+authorinfo as = do c<-askClass; authorinfo' c as
+
+-- | author info as triplets name, institution, email
+authorinfo' :: AuthorInfoStyle -> [AuthorInfo] -> TeX
+authorinfo' LNCS as = do
   cmd "author" $ mconcat $ intersperse (cmd0 "and") $ map oneauthor as
   cmd "institute" $ mconcat $ intersperse (cmd0 "and") $ map textual $ insts
   where oneauthor AuthorInfo{..} = textual authorName <> (if length insts > 1 then cmd "inst" (textual $ show $ 1 + instIdx) else mempty)
            where Just instIdx = elemIndex authorInst insts
         insts = nub $ map authorInst as
 
-authorinfo SIGPlan as = forM_ (groupBy ((==) `on` authorInst) as) $ \ (g@((AuthorInfo _ _ institution):_)) -> do
+authorinfo' SIGPlan as = forM_ (groupBy ((==) `on` authorInst) as) $ \ (g@((AuthorInfo _ _ institution):_)) -> do
     let names = map authorName g
         emails = mconcat $ intersperse (cmd0 "and") $ map (textual . authorEmail) g
     cmdn "authorinfo" [mconcat $ intersperse (cmd0 "and") $ map textual names, textual institution, emails]
     return ()
-authorinfo EPTCS as = mconcat $ intersperse and' $
+authorinfo' EPTCS as = mconcat $ intersperse and' $
   flip map (groupBy ((==) `on` authorInst) as) $ \ (g@((AuthorInfo _ _ institution):_)) -> do
     cmd "author" $ do
       mconcat $ intersperse dquad $ map (textual . authorName) g
@@ -56,28 +56,59 @@
     return ()
   where dquad = cmd0 "quad" <> cmd0 "quad"
         and' = cmd0 "and"
-authorinfo IEEE as = cmd "author" $ do
+authorinfo' Beamer as = do
+  cmd "author" $ mconcat $ intersperse (cmd0 "and") $ flip map as $ \a -> do
+      textual $ authorName a
+      case elemIndex (authorInst a) institutions of
+        Nothing -> textual $ "error: could not find " ++ (authorInst a)
+        Just idx -> inst idx
+      -- No emails in beamer
+  cmd "institute" $
+      forM_ (zip institutions [0..]) $ \(i,idx) -> do
+        inst idx
+        textual i
+  return ()
+  where institutions = nub $ map authorInst $ as
+        inst :: Int -> TeX
+        inst i = when (length institutions > 1) $ cmd "inst" $ tex $ show (i+1)
+
+authorinfo' IEEE as = cmd "author" $ do
   cmd "IEEEauthorblockN" $ mconcat $ intersperse (hspace "1cm") $ map (textual . authorName) as
   tex "\n\n" -- for some reason the IEEE class wants a paragraph separation here.
   cmd "IEEEauthorblockA" $ mkrows $ [textual inst,"email: " <> textual (mconcat $ intersperse " " $ map authorEmail as)]
   where (AuthorInfo {authorInst = inst}:_) = as
-authorinfo _ {- Plain, EPTCS, Beamer -} as = cmd "author" $ mconcat $ intersperse (cmd0 "and") $ map oneauthor as
+authorinfo' _ {- Plain -} as = cmd "author" $ mconcat $ intersperse (cmd0 "and") $ map oneauthor as
   where oneauthor (AuthorInfo name _ institution) = textual name <> newline <> textual institution
 
-keywords :: ClassFile -> [String] -> TeX
-keywords LNCS ks = do
-  cmd "keywords" $ mconcat $ intersperse ", " $ map textual ks
-keywords IEEE ks = env "IEEEkeywords" $ do
-  mconcat $ intersperse ", " $ map textual ks
-keywords SIGPlan ks = do
-  cmd0 "keywords"
-  mconcat $ intersperse ", " $ map textual ks
-keywords _ _ = return ()
+keywords :: [String] -> TeX
+keywords ks = do
+  classFile <- askClass
+  case classFile of
+    Plain -> do
+      paragraph "keywords"
+      mconcat $ intersperse ", " $ map textual ks
+      return ()
+    LNCS -> do cmd "keywords" $ mconcat $ intersperse ", " $ map textual ks
+    IEEE -> env "IEEEkeywords" $ do mconcat $ intersperse ", " $ map textual ks
+    SIGPlan -> do cmd0 "keywords"
+                  mconcat $ intersperse ", " $ map textual ks
+    _ -> return ()
 
+acknowledgements :: Tex a -> Tex a
+acknowledgements body = do
+  classFile <- askClass
+  case classFile of
+    SIGPlan -> cmd0 "acks" >> body
+    _ -> do paragraph "acknowledgements"
+            body
 
+
+newline :: TeX
 newline = backslash <> backslash
+newcol :: TeX
 newcol = tex "&"
-newpara = texLines ["",""]
+newpara :: Tex ()
+newpara = texLn "\\par"
 
 maketitle :: Tex ()
 maketitle = cmd "maketitle" $ return ()
@@ -86,7 +117,7 @@
 ldots = cmd "ldots" (return ())
 
 -- | Sectioning
-section,subsection,paragraph :: TeX -> Tex SortedLabel
+section,subsection,subsubsection,paragraph :: TeX -> Tex SortedLabel
 section s = cmd "section" s >> label "Sec."
 subsection s = cmd "subsection" s >> label "Sec."
 subsubsection s = cmd "subsubsection" s >> label "Sec."
@@ -107,19 +138,45 @@
 stdPreamble :: TeX
 stdPreamble = do
   usepackage "graphicx" []
+  usepackage "ifxetex" []
+  cmd0 "ifxetex"
+  usepackage "fontspec" []
+  usepackage "newunicodechar" []
+  mapM_ texLn ["\\newcommand{\\DeclareUnicodeCharacter}[2]{%"
+              ,"\\begingroup\\lccode`|=\\string\"#1\\relax"
+              ,"\\lowercase{\\endgroup\\newunicodechar{|}}{#2}%"
+              ,"}"]
+  cmd0 "else"
   usepackage "inputenc" ["utf8"]
+  cmd0 "fi"
   return ()
 
-documentClass :: String -> [String] -> TeX
-documentClass docClass options = cmd' "documentclass" options (tex docClass)
-
 ----------
 -- Lists
 
+{-# DEPRECATED item, enumerate, itemize "Since Aug 2015. Use itemList, enumList, descList instead "#-}
 item = cmd0 "item"
 enumerate = env "enumerate"
 itemize = env "itemize"
 
+itemList :: [TeX] -> TeX
+itemList [] = mempty
+itemList xs = env "itemize" $ forM_ xs $ \x -> do
+  cmd0 "item"
+  x
+
+enumList :: [TeX] -> TeX
+enumList [] = mempty
+enumList xs = env "enumerate" $ forM_ xs $ \x -> do
+  cmd0 "item"
+  x
+
+descList :: [(TeX,TeX)] -> TeX
+descList [] = mempty
+descList xs = env "enumerate" $ forM_ xs $ \(lab,x) -> do
+  cmdm "item" [lab] []
+  x
+
 ------------------------
 -- Various environments
 
@@ -231,5 +288,4 @@
         opt' = tex $ mconcat . intersperse ", "
                $ "basicstyle=\\ttfamily" :  opt in
     backslash <> "lstinline" <> brackets opt' <> sep <> tex s <> sep
-
 
diff --git a/MarXup/Latex/Math.hs b/MarXup/Latex/Math.hs
--- a/MarXup/Latex/Math.hs
+++ b/MarXup/Latex/Math.hs
@@ -5,9 +5,9 @@
 import MarXup.Tex
 import MarXup
 import Data.Monoid
-import Data.Ratio
 import Control.Monad (unless)
 
+align :: [[TeX]] -> Tex ()
 align  = env "align*" . mkrows . map mkcols
 
 array :: [String] -> String -> [[TeX]] -> TeX
@@ -30,7 +30,9 @@
 mbox = cmd "mbox"
 fbox :: TeX -> TeX
 fbox = cmd "fbox"
+superscript :: Tex () -> TeX
 superscript y = tex "^" <> braces y
+subscript :: Tex () -> TeX
 subscript x = tex "_" <> braces x
 
 displayMath = env "displaymath"
@@ -38,60 +40,65 @@
 mathsf :: Tex a -> Tex a
 mathsf = cmd "mathsf"
 
-mathpreamble :: ClassFile -> TeX
-mathpreamble sty = do
-  usepackage "graphicx" []
+mathpreamble :: TeX
+mathpreamble = do
   usepackage "amsmath"  []
-  unless (sty == LNCS) $ usepackage "amsthm"   []
   usepackage "amssymb"  []   -- extra symbols such as □
   usepackage "stmaryrd" [] -- has ⟦ and ⟧
-  usepackage "mathpartir" [] -- mathpar environment
 
-  unless (sty == LNCS || sty == Beamer) $ do
-    newtheorem "theorem" "Theorem"
-    newtheorem "corollary" "Corollary"
-    newtheorem "lemma" "Lemma"
-    newtheorem "definition" "Definition"
-    newtheorem "proposition" "Proposition"
 
 mathpar :: [[TeX]] -> TeX
-mathpar = env "mathpar" . mkrows . map mk . filter (not . null)
- where mk = foldr1 (\x y -> x <> cmd0 "and" <> y)
+mathpar ps = do
+   usepkg "mathpartir" 100 []
+   env "mathpar" . mkrows . map mk . filter (not . null) $ ps
+  where mk = foldr1 (\x y -> x <> cmd0 "and" <> y)
 
+mathbox :: Tex a -> Tex a
 mathbox = mbox . ensureMath
 
-newtheorem :: String -> TeX -> TeX
-newtheorem ident txt = cmd "newtheorem" (tex ident) >> braces txt
 
-deflike :: String -> String -> TeX -> TeX -> Tex SortedLabel
-deflike reference nv name statement = env'' nv [] [name] $ do
-  statement
-  label reference
+-- | @deflike referent nv header name statement@:
+-- Environement of name @nv@, which should be refered as @referent@.
+deflike :: String -> String -> String -> TeX -> TeX -> Tex SortedLabel
+deflike referent nv header name statement = do
+  newtheorem nv header
+  cls <- askClass
+  unless (cls == LNCS) $ usepkg "amsthm" 100 []
+  let envir body = case cls of
+        SIGPlan -> env'' nv [name] [] (hspace "0cm" >> body)
+        _ -> env'' nv [] [name] body
+  envir $ do
+    statement
+    label referent
 
-thmlike :: String -> String -> TeX -> TeX -> TeX -> Tex SortedLabel
-thmlike reference nv name statement proof = do
-  x <- deflike reference nv name statement
+thmlike :: String -> String -> String -> TeX -> TeX -> TeX -> Tex SortedLabel
+thmlike referent nv header name statement proof = do
+  x <- deflike referent nv header name statement
   env "proof" proof
   return x
 
 theorem,lemma ::  TeX -> TeX -> TeX -> Tex SortedLabel
-theorem = thmlike "Thm." "theorem"
-lemma = thmlike "Lem." "lemma"
+theorem = thmlike "Thm." "theorem" "Theorem"
+lemma = thmlike "Lem." "lemma" "Lemma"
 
-definition,corollary :: TeX -> TeX -> Tex SortedLabel
-definition = deflike "Def." "definition"
-corollary = deflike "Cor." "corollary"
-proposition = deflike "Prop." "proposition"
-example = deflike "Ex." "example"
+definition,corollary,proposition,example :: TeX -> TeX -> Tex SortedLabel
+definition = deflike "Def." "definition" "Definition"
+corollary = deflike "Cor." "corollary" "Corollary"
+proposition = deflike "Prop." "proposition" "Proposition"
+example = deflike "Ex." "example" "Example"
 
 -- Other stuff
 oxford :: Tex a -> Tex a
 oxford = bigParenthesize (textual "⟦") (textual "⟧")
 
+multiline' :: [TeX] -> Tex ()
 multiline' body = env "multline*" $ mkrows body
 
+frac :: TeX -> TeX -> Tex ()
 frac x y = cmdn_ "frac" [x,y]
 
+centerVertically :: Tex a -> Tex a
 centerVertically = ensureMath . cmd "vcenter" . cmd "hbox"
 
+qedhere :: Tex ()
 qedhere = cmd0 "qedhere"
diff --git a/MarXup/LineUp.hs b/MarXup/LineUp.hs
new file mode 100644
--- /dev/null
+++ b/MarXup/LineUp.hs
@@ -0,0 +1,111 @@
+{-# LANGUAGE RecordWildCards #-}
+module MarXup.LineUp (Tok(..),lineup,mkSpaces) where
+
+import Data.List
+import Data.Foldable
+import Control.Monad (when)
+import Data.Monoid
+import Data.Maybe (catMaybes)
+
+import MarXup.Tex
+
+data Tok = Tok {
+  startCol :: Int,
+  endCol :: Int,
+  preSpace :: Float, -- max amount of space which should come before this token, in mu
+  render :: TeX,
+  postSpace :: Float -- max amount of space which should come after this token, in mu
+  }
+
+
+justIf True x = Just x
+justIf _ _ = Nothing
+
+marx True = '!'
+marx False = '-'
+
+lineup :: [[Tok]] -> TeX
+lineup input = env'' "list" [] [mempty,tex "\\setlength\\leftmargin{1em}"] $ do
+  usepkg "polytable" 100 []
+  texLn ""
+  texLines $ map (("% " ++) . map marx . drop 1 . isIndentTab ) array
+  
+  texLn "\\item\\relax"
+  cmd "ensuremath" $ env "pboxed" $ do
+    declColumn Nothing "B"
+    forM_ (zip3 allTabStops [(1::Int)..] (drop 1 indentColumns)) $ \(_col,tab,indenting) -> 
+      declColumn (justIf (indenting) $ tex $ show (tab-1) ++ "em") (show tab)
+    declColumn Nothing "E"
+    texLn "%"
+    sequence_ $ intersperse (texLn "\\\\") $ map printLine array
+  where
+    showCol 0 = "B"
+    showCol n = show n
+    declColumn :: Maybe TeX -> String -> TeX
+    declColumn dim c = do
+      cmdm "column" (catMaybes [dim]) [tex c,tex "@{}>{}l<{}@{}"]
+      return ()
+
+    printLine :: [[Tok]] -> TeX
+    printLine xs = do
+      forM_ (zip xs [(0::Int)..]) $ \(ts,colName) -> do
+         when (not $ null ts) $ do
+           cmdn' ">" [showCol colName] []
+           braces $ forM_ ts $ \t -> do 
+                render t
+      cmdn' "<" ["E"] []
+      return ()
+
+    -- The input, grouped in lines and columns
+    array :: [[[Tok]]]
+    array = map (tabify . mkSpaces) input
+
+    -- Is the token preceded by two spaces or starts a line?
+    isAligning :: [Tok] -> [(Bool,Tok)]
+    isAligning [] = []
+    isAligning (x:xs) = (True,x) :
+                        [(startCol t2 > 1 + endCol t1,t2) | (t1,t2) <- zip (x:xs) xs]
+
+    -- | The tabstop possibly beginning an indentation? It cannot be
+    -- if it both contains a token and is preceded by stuff.
+    isIndentTab :: [[Tok]] -> [Bool]
+    isIndentTab xs = zipWith (||) nulls (scanl (&&) True nulls) 
+      where nulls = map null xs
+
+    -- | Is a tabstop an indentation? (Take the intersection for all lines)
+    indentColumns :: [Bool]
+    indentColumns = map and $ transpose $ map isIndentTab array
+
+    -- The tab stops in a line
+    tabStops :: [Tok] -> [Int]
+    tabStops xs = [startCol x | (align,x) <- isAligning xs, align]
+
+    -- all the tab stops
+    allTabStops :: [Int]
+    allTabStops = sort $ nub $ concatMap tabStops input
+
+    tabify :: [Tok] -> [[Tok]]
+    tabify xs = tabify' (isAligning xs) allTabStops
+
+    clearMeta :: [(Bool,Tok)] -> [Tok]
+    clearMeta = map snd
+
+    tabify' :: [(Bool,Tok)] -> [Int]-> [[Tok]]
+    tabify' [] _ = []
+    tabify' xs [] = [clearMeta xs]
+    tabify' xs (t:ts) = clearMeta col:tabify' xs' ts
+      where (col,xs') = break (\(align,s) -> align && (startCol s >= t)) xs
+
+
+
+--- | Transform a list of tokens to move the spacing info into the TeX
+-- field of the tokens (spacing goes after the texts)
+mkSpaces :: [Tok] -> [Tok]
+mkSpaces [] = []
+-- mkSpaces ts = [ Tok startCol endCol
+--                 0 (tex (show preSpace) <> render <> tex (show postSpace) <> tex "\\;") 0
+--               | Tok{..} <- ts]
+mkSpaces ts = [ Tok (startCol l) (endCol l) 0
+                (render l <>
+                 tex ("\\mskip " ++ show (min (postSpace l) (preSpace r)) ++ "mu" )) 0
+              | (l,r) <- zip ts (tail ts) ] ++ [last ts]
diff --git a/MarXup/LineUp/Haskell.hs b/MarXup/LineUp/Haskell.hs
new file mode 100644
--- /dev/null
+++ b/MarXup/LineUp/Haskell.hs
@@ -0,0 +1,217 @@
+module MarXup.LineUp.Haskell where
+
+import Data.List
+import Data.Function
+import Language.Haskell.Exts.Lexer
+import Language.Haskell.Exts.Parser (ParseResult(..),ParseMode(..),defaultParseMode)
+import Language.Haskell.Exts.SrcLoc
+import MarXup
+import MarXup.LineUp
+import MarXup.Tex
+import MarXup.Verbatim
+import Data.Monoid
+import Data.Char (isDigit)
+
+haskell :: Verbatim a -> Tex ()
+haskell = haskellCust defaultParseMode printTok
+
+haskellInline :: Verbatim a -> Tex ()
+haskellInline = haskellInlineCust defaultParseMode printTok
+
+type PrintTok = Token -> (Float,TeX,Float)
+
+haskellInlineCust :: ParseMode -> (PrintTok) -> Verbatim a -> Tex ()
+haskellInlineCust mode custPrintTok v = case lexTokenStreamWithMode mode (fromVerbatim v) of
+   ParseOk toks -> mconcat $ map render $ mkSpaces $ map (mkTok custPrintTok) toks
+   ParseFailed location err -> textual (show location ++ show err)
+
+mkTok :: (t -> (Float, TeX, Float)) -> Loc t -> Tok
+mkTok custPrintTok (Loc l t) = Tok (srcSpanStartColumn l) (srcSpanEndColumn l) before txt after
+  where (before,txt,after) = custPrintTok t
+
+haskellCust :: ParseMode -> (PrintTok) -> Verbatim a -> Tex ()
+haskellCust mode custPrintTok v = case lexTokenStreamWithMode mode (fromVerbatim v) of
+  ParseOk toks -> lineup (map (map (mkTok custPrintTok)) lins)
+    where lins = groupBy ((==) `on` (srcSpanStartLine . loc)) toks
+  ParseFailed location err -> textual (show location ++ show err)
+
+splitTok :: String -> (String, Maybe String)
+splitTok input = (reverse prefix ++ primes, if null numbers then Nothing else Just (reverse numbers))
+  where (numbers,prefix) = span isDigit revNonPrimes
+        (primes,revNonPrimes) = span (== '\'') revIn
+        revIn = reverse input
+
+printTok :: PrintTok
+printTok t = let s = textual $ showToken t
+                 ident = regular $ case splitTok $ showToken t of
+                              (_,Nothing) -> cmd "mathsf" s
+                              (pref,Just suff) -> cmd "mathsf" (textual pref) <> tex "_" <> braces (textual suff)
+                 unquote = regular $ cmd "mathsf" s
+                 quote = regular $ cmd "mathtt" s
+                 literal = regular $ cmd "mathrm" s
+                 string = regular $ cmd "texttt" s
+                 keyword = regular $ cmd "mathbf" s
+                 pragma = regular $ cmd "mathrm" s
+                 symbol = regular $ cmd "mathnormal" s
+                 regular tx = (5,tx,5)
+                 leftParen  = (5,cmd "mathnormal" s,0)
+                 rightParen = (0,cmd "mathnormal" s,5)
+                 special x = regular $ cmd "mathnormal" $ tex x
+                 debug = regular $ textual "[" <> ( cmd "mathnormal" $ textual $ show t) <> textual "]"
+  in case t of
+        -- _ -> cmd "mathrm" $ textual $ show t -- Debug
+        VarId _ -> ident
+        QVarId _ -> ident
+        IDupVarId _ -> ident
+        ILinVarId _ -> ident
+        ConId _ -> ident
+        QConId _ -> ident
+        DVarId _ -> ident
+        VarSym "==" -> special "\\equiv" -- ≡
+        VarSym "=~" -> special "\\cong" -- ≅
+        VarSym "<=" -> special "\\leq" -- ≤
+        VarSym ">=" -> special "\\geq" -- ≥
+        VarSym "<>" -> special "<\\!>"
+        VarSym "<|>" -> special "<\\!\\mid\\!>"
+        VarSym "<+>" -> special "<{\\mkern-12mu}+{\\mkern-12mu}>"
+        VarSym "<*>" -> special "<{\\mkern-12mu}*{\\mkern-12mu}>"
+        VarSym "<$>" -> special "<{\\mkern-12mu}\\${\\mkern-12mu}>"
+        VarSym "++" -> special "+\\!+"
+        VarSym _ -> symbol
+        ConSym _ -> ident
+        QVarSym _ -> ident
+        QConSym _ -> ident
+        IntTok _ -> literal
+        FloatTok _ -> literal
+        Character _ -> string
+        StringTok _ -> string
+        IntTokHash _ -> literal
+        WordTokHash _ -> literal
+        FloatTokHash _ -> literal
+        DoubleTokHash _ -> literal
+        CharacterHash _ -> literal
+        StringHash _ -> literal
+        LeftParen    -> leftParen
+        RightParen -> rightParen
+        LeftHashParen  -> symbol
+        RightHashParen -> symbol
+        SemiColon    -> symbol
+        LeftCurly    -> leftParen
+        RightCurly   -> rightParen
+        VRightCurly -> rightParen
+        LeftSquare   -> leftParen
+        RightSquare          -> rightParen
+        ParArrayLeftSquare   -> leftParen
+        ParArrayRightSquare -> rightParen
+        Comma -> rightParen
+        Underscore -> symbol
+        BackQuote -> symbol
+        Dot -> symbol
+        DotDot -> symbol
+        Colon -> symbol
+        QuoteColon -> symbol
+        DoubleColon -> symbol
+        Equals -> symbol
+        Backslash -> symbol
+        Bar -> symbol
+        LeftArrow -> regular $ cmd0 "leftarrow"
+        RightArrow -> regular $ cmd0 "rightarrow"
+        At -> symbol
+        Tilde -> symbol
+        DoubleArrow -> regular $ cmd0 "Rightarrow"
+        Minus -> symbol
+        Exclamation -> symbol
+        Star -> symbol
+        LeftArrowTail -> symbol
+        RightArrowTail -> symbol
+        LeftDblArrowTail -> symbol
+        RightDblArrowTail -> symbol
+        THExpQuote -> symbol
+        THPatQuote -> symbol
+        THDecQuote -> symbol
+        THTypQuote -> symbol
+        THCloseQuote -> symbol
+        THIdEscape _ -> unquote
+        THParenEscape -> symbol
+        THVarQuote -> symbol
+        THTyQuote -> symbol
+        THQuasiQuote _ -> quote
+        RPGuardOpen -> symbol
+        RPGuardClose -> symbol
+        RPCAt -> symbol
+        XCodeTagOpen -> symbol
+        XCodeTagClose -> symbol
+        XStdTagOpen -> symbol
+        XStdTagClose -> symbol
+        XCloseTagOpen -> symbol
+        XEmptyTagClose -> symbol
+        XChildTagOpen -> symbol
+        XPCDATA _ -> symbol
+        XRPatOpen -> symbol
+        XRPatClose -> symbol
+        PragmaEnd -> symbol
+        RULES -> pragma
+        INLINE _ -> pragma
+        INLINE_CONLIKE -> pragma
+        SPECIALISE -> pragma
+        SPECIALISE_INLINE _ -> pragma
+        SOURCE -> pragma
+        DEPRECATED -> pragma
+        WARNING -> pragma
+        SCC -> pragma
+        GENERATED -> pragma
+        CORE -> pragma
+        UNPACK -> pragma
+        OPTIONS _ -> pragma
+        LANGUAGE -> pragma
+        ANN -> pragma
+        MINIMAL -> pragma
+        NO_OVERLAP -> pragma
+        OVERLAP -> pragma
+        INCOHERENT -> pragma
+        KW_As -> keyword
+        KW_By -> keyword
+        KW_Case -> keyword
+        KW_Class -> keyword
+        KW_Data -> keyword
+        KW_Default -> keyword
+        KW_Deriving -> keyword
+        KW_Do -> keyword
+        KW_MDo -> keyword
+        KW_Else -> keyword
+        KW_Family -> keyword
+        KW_Forall -> keyword
+        KW_Group -> keyword
+        KW_Hiding -> keyword
+        KW_If -> keyword
+        KW_Import -> keyword
+        KW_In -> keyword
+        KW_Infix -> keyword
+        KW_InfixL -> keyword
+        KW_InfixR -> keyword
+        KW_Instance -> keyword
+        KW_Let -> keyword
+        KW_Module -> keyword
+        KW_NewType -> keyword
+        KW_Of -> keyword
+        KW_Proc -> keyword
+        KW_Rec -> keyword
+        KW_Then -> keyword
+        KW_Type -> keyword
+        KW_Using -> keyword
+        KW_Where -> keyword
+        KW_Qualified -> keyword
+        KW_Foreign -> keyword
+        KW_Export -> keyword
+        KW_Safe -> keyword
+        KW_Unsafe -> keyword
+        KW_Threadsafe -> keyword
+        KW_Interruptible -> keyword
+        KW_StdCall -> keyword
+        KW_CCall -> keyword
+        KW_CPlusPlus -> keyword
+        KW_DotNet -> keyword
+        KW_Jvm -> keyword
+        KW_Js -> keyword
+        KW_CApi -> keyword
+        _ -> debug
diff --git a/MarXup/Math.hs b/MarXup/Math.hs
--- a/MarXup/Math.hs
+++ b/MarXup/Math.hs
@@ -54,6 +54,7 @@
 --------------
 -- Operators
 
+infixr 1 =:
 (=:) = binop 0 "="
 
 instance Num Math where
@@ -76,6 +77,7 @@
     log = fct (cmd "mathnormal" "log")
     sin = fct (cmd "mathnormal" "sin")
     cos = fct (cmd "mathnormal" "cos")
+    tan = fct (cmd "mathnormal" "tan")
     asin = fct (cmd "mathnormal" "asin")
     acos = fct (cmd "mathnormal" "acos")
     atan = fct (cmd "mathnormal" "atan")
diff --git a/MarXup/MultiRef.hs b/MarXup/MultiRef.hs
--- a/MarXup/MultiRef.hs
+++ b/MarXup/MultiRef.hs
@@ -3,48 +3,47 @@
 module MarXup.MultiRef where
 
 import Control.Monad.Fix
-import "mtl" Control.Monad.RWS.Lazy
-import Control.Applicative
-import Control.Arrow (first)
+import Control.Monad.RWS.Lazy
+import Data.Map.Strict (Map,insert)
+import qualified Data.Map.Strict as M
+import Graphics.Diagrams.Core (BoxSpec, nilBoxSpec)
+type MetaData key = Map key String
+type BoxSpecs = Map Int BoxSpec
 
-newtype Multi a = Multi {fromMulti :: RWS InterpretMode String (References,[BoxSpec]) a }
-  deriving (Functor, Monad, Applicative, MonadWriter String, MonadState (References,[BoxSpec]), MonadFix, MonadReader InterpretMode)
+-- FIXME: Move boxspecs to the Read part.
+newtype Multi config key a = Multi {fromMulti :: RWS config String (References,BoxSpecs,MetaData key) a }
+  deriving (Functor, Monad, MonadReader config, Applicative, MonadWriter String, MonadState (References,BoxSpecs,MetaData key), MonadFix)
 
 -----------------------------------
 -- Basic datatype and semantics
 type Label = Int
 
--- | Size of a box, in points. boxDepth is how far the baseline is
--- from the bottom. boxHeight is how far the baseline is from the top.
--- (These are TeX meanings)
-data BoxSpec = BoxSpec {boxWidth, boxHeight, boxDepth :: Double}
-             deriving (Show)
 
-nilBoxSpec :: BoxSpec
-nilBoxSpec = BoxSpec 0 0 0
 
-raw :: String -> Multi ()
+raw :: String -> Multi config key ()
 raw s = tell s
 
-getBoxSpec :: Multi BoxSpec
-getBoxSpec = do
-  (refs,bs) <- get
-  case bs of
-    [] -> error "display: ran out of boxes!"
-    (b:bs') -> do
-      put (refs,bs')
-      return b
- 
+getBoxSpec :: Int -> Multi config key BoxSpec
+getBoxSpec bxId = do
+  (_,bs,_) <- get
+  return $ case M.lookup bxId bs of
+    Nothing -> nilBoxSpec -- TODO: log this error somehow
+    Just b -> b
 
+-- | allocate a new label
+newLabel :: Multi key config Label -- create a new label
+newLabel = do (r,bx,m) <- get
+              put (r+1,bx,m)
+              return r
 
--- Reference management
-newLabel :: Multi Label -- create a new label
-newLabel = do x <- fst <$> get;  modify (first (+1)); return x
+-- | output some meta data
+metaData :: Ord key => key -> String -> Multi config key ()
+metaData k val = do
+   (r,bx,m) <- get
+   put (r,bx,insert k val m)
+   return ()
 
 type References = Int -- how many labels have been allocated
 emptyRefs :: References
 emptyRefs = 0
-
-type Mode = InterpretMode -> Bool
-data InterpretMode = OutsideBox | InsideBox | Regular deriving Eq
 
diff --git a/MarXup/PrettyPrint/Core.hs b/MarXup/PrettyPrint/Core.hs
--- a/MarXup/PrettyPrint/Core.hs
+++ b/MarXup/PrettyPrint/Core.hs
@@ -5,7 +5,8 @@
 import MarXup (textual)
 import MarXup.Latex
 import MarXup.Tex
-import MarXup.MultiRef 
+import MarXup.MultiRef
+import Graphics.Diagrams.Core (BoxSpec (..))
 import MarXup.Diagram.Tikz (showDistance)
 import Data.Foldable (forM_)
 import Control.Applicative
diff --git a/MarXup/Tex.hs b/MarXup/Tex.hs
--- a/MarXup/Tex.hs
+++ b/MarXup/Tex.hs
@@ -3,26 +3,67 @@
 module MarXup.Tex where
 
 import MarXup
-import "mtl" Control.Monad.Reader
-import "mtl" Control.Monad.RWS
-import Control.Applicative
+import Control.Monad.Reader
+import Control.Monad.RWS
 import GHC.Exts( IsString(..) )
-import Data.List (intersperse)
+import Data.List (intersperse,intercalate)
 import MarXup.MultiRef
-import System.Process
 import System.Directory (doesFileExist)
+import Data.Char (isSpace)
+import Data.Map (assocs, Map)
+import qualified Data.Map as Map
+import Graphics.Diagrams.Core (BoxSpec (..))
 
-newtype Tex a = Tex {fromTex :: Multi a}
+data ClassFile = Plain | LNCS | SIGPlan | IEEE | EPTCS | Beamer
+  deriving Eq
+
+
+------------------------------------
+-- MetaData
+
+data Key = PreClass String | PrePackage Int String | PreTheorem String String   -- priority
+  deriving (Ord,Eq)
+
+newtheorem :: String -> String -> TeX
+newtheorem ident txt = do
+  sty <- askClass
+  unless ((sty == LNCS || sty == Beamer) && ident `elem` ["theorem", "corollary", "lemma", "definition", "proposition"]) $ do
+  Tex $ metaData (PreTheorem ident txt) ""
+
+usepkg :: String -> Int -> [String] -> TeX
+usepkg ident prio options = Tex $ metaData (PrePackage prio ident) (intercalate "," options)
+
+documentClass :: String -> [String] -> TeX
+documentClass docClass options = Tex $ metaData (PreClass docClass) (intercalate "," options)
+
+
+renderKey :: Key -> String -> String
+renderKey o options = case o of
+  PreClass name -> "\\documentclass[" ++ options ++ "]{" ++ name ++ "}"
+  PrePackage _ name -> "\\usepackage[" ++ options ++ "]{" ++ name ++ "}"
+  PreTheorem ident txt  -> "\\newtheorem{" ++ ident ++ "}{" ++ txt ++ "}"
+
+newtype Tex a = Tex {fromTex :: Multi ClassFile Key a}
   deriving (Monad, MonadFix, Applicative, Functor)
 
+
+
+
 ---------------------------------
 -- MarXup interface
 instance Textual Tex where
-    textual s = tex $ concatMap escape s
+  textual s = case break (== '\n') s of
+    -- The 1st blank line of a MarXup chunk is replaced by a
+    -- space. This means that to create a paragraph after an element,
+    -- one needs a double blank line.
+    (l,'\n':s') | all isSpace l -> tex (' ' : process s')
+    _ -> tex $ process s
+   where process = concatMap escape
 
 kern :: String -> TeX
 kern x = braces $ tex $ "\\kern " ++ x
 
+escape :: Char -> [Char]
 escape '\\' = "\\ensuremath{\\backslash{}}"
 escape '~' = "\\ensuremath{\\sim{}}"
 escape '<' = "\\ensuremath{<}"
@@ -34,11 +75,8 @@
   type Target (Tex a) = Tex a
   element = id
 
-texInMode ::  Mode -> String ->TeX
-texInMode mode s = whenMode mode $ Tex $ raw s
-
-tex :: String -> TeX
-tex = texInMode (`elem` [Regular,InsideBox])
+tex ::  String ->TeX
+tex = Tex . raw
 
 texComment :: String -> TeX
 texComment s =
@@ -51,7 +89,7 @@
 reference l = tex (show l)
 
 instance Monoid (TeX) where
-  mempty = textual ""
+  mempty = tex ""
   mappend = (>>)
 
 instance IsString (TeX) where
@@ -99,7 +137,7 @@
   when (null args) $ tex "{}" -- so that this does not get glued with the next thing.
   return res
 
--- | Command with tex options and many arguments
+-- | Command with tex options and several arguments
 cmdm :: String -> [Tex a] -> [Tex a] -> Tex [a]
 cmdm cmd options args = do
   backslash >> tex cmd
@@ -109,6 +147,7 @@
   return res
 
 
+-- | Command with string options and several arguments; no result
 cmdn'_ :: String -> [String] -> [TeX] -> Tex ()
 cmdn'_ cmd options args = cmdn' cmd options args >> return ()
 
@@ -116,8 +155,9 @@
 cmdn :: String -> [Tex a] -> Tex [a]
 cmdn c args = cmdn' c [] args
 
+-- | Command with n arguments, no result
 cmdn_ :: String -> [TeX] -> Tex ()
-cmdn_ cmd args = cmdn'_ cmd [] args
+cmdn_ theCmd args = cmdn'_ theCmd [] args
 
 -- | Environment
 env :: String -> Tex a -> Tex a
@@ -125,13 +165,13 @@
 
 -- | Environment with options
 env' :: String -> [String] -> Tex a -> Tex a
-env' e opts body = env'' e opts [] body
+env' e opts body = env'' e (map textual opts) [] body
 
--- | Environment with a tex option
-env'' :: String -> [String] -> [TeX] -> Tex a -> Tex a
+-- | Environment with tex options and tex arguments
+env'' :: String -> [TeX] -> [TeX] -> Tex a -> Tex a
 env'' e opts args body = do
   cmd "begin" $ tex e
-  when (not $ null opts) $ brackets $ sequence_ $ map tex $ intersperse "," opts
+  when (not $ null opts) $ brackets $ sequence_ $ intersperse (tex ",") opts
   mapM_ braces args
   x <- body
   cmd "end" $ tex e
@@ -171,88 +211,80 @@
 -----------------
 -- Generate boxes
 
-outputAlsoInBoxMode :: Tex a -> Tex a
-outputAlsoInBoxMode (Tex a) = Tex $ local moveInBox $ a
-         where moveInBox m = case m of
-                 OutsideBox -> InsideBox
-                 _ -> m
 
-texAlways = texInMode (const True)
+inBox :: Tex a -> Tex (a, BoxSpec)
+inBox = helpBox True
 
-inBoxComputMode :: String -> TeX
-inBoxComputMode = texInMode (`elem` [OutsideBox,InsideBox])
+justBox :: Tex a -> Tex BoxSpec
+justBox x = snd <$> helpBox False x
 
-whenMode :: Mode -> Tex () -> Tex ()
-whenMode mode act = do
-  interpretMode <- Tex ask
-  when (mode interpretMode) act
 
-inBox :: Tex a -> Tex (a, BoxSpec)
-inBox x = do
-  inBoxComputMode $ "\n\\savebox{\\marxupbox}{"
-  a <- outputAlsoInBoxMode x
-  inBoxComputMode $ 
+helpBox :: Bool -> Tex a -> Tex (a,BoxSpec)
+helpBox showBox x = do bxId <- Tex newLabel
+                       a <- fillBox bxId showBox x
+                       b <- Tex (getBoxSpec bxId)
+                       return (a,b)
+
+getBoxFromId :: Int -> Tex BoxSpec
+getBoxFromId = Tex . getBoxSpec
+
+fillBox :: Label -> Bool -> Tex a -> Tex a
+fillBox bxId showBox x = braces $ do
+  tex $ "\\savebox{\\marxupbox}{"
+  a <- x
+  tex $
     "}"
+    ++ "\\immediate\\write\\boxesfile{" ++ show bxId ++ "}"
     ++ writeBox "wd"
     ++ writeBox "ht"
     ++ writeBox "dp"
-    ++ "\n"
-  b <- Tex getBoxSpec
+  when showBox $ tex $ "\\box\\marxupbox"
 
-  return (a,b)
+  return a
   where writeBox l = "\\immediate\\write\\boxesfile{\\number\\"++ l ++"\\marxupbox}"
 
+-- TODO: it would be nice to have:
+-- withBox :: Bool -> Tex a -> (Tex a -> Tex a) -> Tex BoxSpec
+-- withBox showBox boxContents boxContext = ...
 
-justBox :: Tex a -> Tex BoxSpec
-justBox x = do
-  whenMode (`elem` [OutsideBox, InsideBox]) $ outputAlsoInBoxMode $ do
-    tex "\n\\savebox{\\marxupbox}{"
-    x
-    tex $ 
-      "}"
-      ++ writeBox "wd"
-      ++ writeBox "ht"
-      ++ writeBox "dp"
-      ++ "\n"
-  b <- Tex getBoxSpec
+-- however this may require some latex trickery. The idea would be to
+-- create the box upfront (and thus we can obtain its boundaries), and
+-- invoke it wherever the context calls it. This means that we need a
+-- new 'box' for every invokation. It may be that latex does not have
+-- infinitely many boxes, and thus we need to reuse (latex-side) box
+-- ids.
 
-  return b
-  where writeBox l = "\\immediate\\write\\boxesfile{\\number\\"++ l ++"\\marxupbox}"
+renderWithBoxes :: ClassFile -> BoxSpecs -> Tex a -> String
+renderWithBoxes classFile bs (Tex t) = (preamble ++ doc)
+  where (_,(_,_,metaDatum),doc) = runRWS (fromMulti $ t) classFile (0,bs,mempty)
+        preamble :: String
+        preamble = unlines $ map (uncurry renderKey) $ assocs metaDatum
 
-renderWithBoxes :: [BoxSpec] -> InterpretMode -> Tex a -> String
-renderWithBoxes bs mode (Tex t) = doc
-  where (_,_,doc) = runRWS (fromMulti $ t) mode (0,bs)
+renderSimple :: ClassFile -> Tex a -> String
+renderSimple classFile = renderWithBoxes classFile Map.empty
 
-renderSimple :: TeX -> String
-renderSimple = renderWithBoxes [] Regular
-  
-renderTex :: (Bool -> TeX) -> TeX -> IO String
-renderTex preamble body = do
-  let bxsTex = renderWithBoxes (repeat nilBoxSpec) OutsideBox (wholeDoc True)
-      boxesName = "mpboxes"
-      boxesTxt = boxesName ++ ".txt"
-      wholeDoc inBoxMode = do
-        outputAlsoInBoxMode (preamble inBoxMode)
-        inBoxComputMode $ "\\newwrite\\boxesfile"
-        texAlways "\\begin{document}"
-        inBoxComputMode $ "\\immediate\\openout\\boxesfile="++boxesTxt++"\n \\newsavebox{\\marxupbox}"
-        body
-        inBoxComputMode "\n\\immediate\\closeout\\boxesfile"
-        texAlways "\\end{document}"
-  writeFile (boxesName ++ ".tex") bxsTex
-  system $ "latex " ++ boxesName
-  boxes <- do
+renderTex :: ClassFile -> String -> TeX -> IO ()
+renderTex classFile fname body = do
+  let boxesTxt = fname ++ ".boxes"
+  boxes <- getBoxInfo . map read . lines <$> do
     e <- doesFileExist boxesTxt
     if e
-      then do
-        boxData <- map read . lines <$> readFile boxesTxt
-        return $ getBoxInfo boxData
-      else return []
-  putStrLn $ "Number of boxes found: " ++ show (length boxes)
-  return $ renderWithBoxes boxes Regular $ (wholeDoc False)
+      then readFile boxesTxt
+      else return ""
+  putStrLn $ "Found " ++ show (length boxes) ++ " boxes"
+  let texSource = renderWithBoxes classFile boxes wholeDoc
+      wholeDoc = do
+        tex $ "\\newwrite\\boxesfile"
+        tex $ "\\immediate\\openout\\boxesfile="++boxesTxt++"\n\\newsavebox{\\marxupbox}"
+        body
+        tex "\n\\immediate\\closeout\\boxesfile"
+  writeFile (fname ++ ".tex") texSource
 
-getBoxInfo :: [Int] -> [BoxSpec]
-getBoxInfo [] = []
-getBoxInfo (width:height:depth:bs) = BoxSpec (scale width) (scale height) (scale depth):getBoxInfo bs
+askClass :: Tex ClassFile
+askClass = Tex ask
+
+getBoxInfo :: [Int] -> Map Int BoxSpec
+getBoxInfo (ident:width:height:depth:bs) = Map.insert ident (BoxSpec (scale width) (scale height) (scale depth)) (getBoxInfo bs)
   where scale x = fromIntegral x / 65536
+getBoxInfo _ = Map.empty
 
diff --git a/MarXup/Verbatim.hs b/MarXup/Verbatim.hs
--- a/MarXup/Verbatim.hs
+++ b/MarXup/Verbatim.hs
@@ -4,12 +4,18 @@
 
 import MarXup
 import Control.Monad.Fix
+import Control.Monad (ap)
+import Control.Applicative
 
 data Verbatim a = Verbatim {fromVerbatim::String, value::a}
   deriving Functor
 
 instance Textual Verbatim where
     textual s = Verbatim s ()
+
+instance Applicative Verbatim where
+    pure = return
+    (<*>) = ap
 
 instance Monad Verbatim where
     return x = Verbatim "" x
diff --git a/MarXupParser.hs b/MarXupParser.hs
new file mode 100644
--- /dev/null
+++ b/MarXupParser.hs
@@ -0,0 +1,156 @@
+{-# LANGUAGE TupleSections, FlexibleInstances, TransformListComp #-}
+
+module MarXupParser (parseFile, Haskell(..), MarXup(..)) where
+
+import Text.ParserCombinators.Parsek.Position
+import Data.Char
+import Data.List
+import System.IO
+import Control.Monad
+import GHC.Exts (the,groupWith)
+import Config
+
+-- todo: parse haskell comments (so that marxup there is not recognized)
+
+------------------
+-- Simple printing combinators, which do not add nor remove line breaks
+
+data Haskell = HaskChunk String | HaskLn SourcePos | Quote [MarXup] | List [Haskell] | Parens [Haskell] | String String deriving (Show)
+data MarXup = TextChunk String | Unquote (Maybe (SourcePos,String)) [(SourcePos,Haskell)] | Comment String deriving (Show)
+
+----------------------------------------------
+-- Parsing combinators
+
+anyQuoteStrings :: [String]
+anyQuoteStrings = concatMap (\(x,y) -> [x,y]) quoteStrings
+
+pTextChunk = TextChunk <$> pChunk' (commentString : antiQuoteStrings ++ anyQuoteStrings) <?> "Text chunk"
+pHaskChunk = HaskChunk <$> pChunk' (map box "\n\"[]()" ++ map fst quoteStrings) <?> "Haskell chunk"
+    -- we keep track of balancing
+
+pWPos :: Parser SourcePos
+pWPos = do
+  char '\n'
+  getPosition
+
+withPos :: Parser a -> Parser (SourcePos,a)
+withPos p = do
+  pos <- getPosition
+  x <- p
+  return (pos,x)
+
+pHaskLn = HaskLn <$> pWPos -- before each newline, tell GHC where we are.
+
+box = (:[])
+
+pString :: Parser Haskell
+pString = do
+  char '"'
+  result <- many (string "\\\"" <|> pChunk ['"'])
+  char '"'
+  return $ String $ concat result
+
+-- | Parse some Haskell code with markup inside.
+pHask :: Parser [Haskell]
+pHask = many ((List <$> pArg "[]") <|>
+              (Parens <$> pArg "()") <|>
+              pTextArg  <|>
+              pString <|>
+              pHaskChunk <|>
+              pHaskLn)
+
+-- | Parse a text argument to an element
+pTextArg' :: String -> String -> Parser Haskell
+pTextArg' open close = Quote <$> (label "quoted text" $
+  string open *>
+  (many (pElement <|> pTextChunk <|> pComment))
+  <* string close)
+
+pTextArg :: Parser Haskell
+pTextArg = choice $ map (uncurry pTextArg') quoteStrings
+
+pArg :: String -> Parser [Haskell]
+pArg [open,close] = char open *> pHask <*  char close
+
+isIdentChar :: Char -> Bool
+isIdentChar x = isAlphaNum x || (x `elem` "\'_")
+
+pIdent :: Parser String
+pIdent = munch1 isIdentChar <?> "identifier"
+
+pArgument :: Parser Haskell
+pArgument = (Parens <$> pArg "()" <|> (List <$> pArg "[]") <|> pTextArg <|> pString) <?> "argument"
+
+pId :: Parser Haskell
+pId = HaskChunk <$> pIdent
+
+pElement :: Parser MarXup
+pElement = 
+  label "Haskell element" $ do
+    choice $ map string $ antiQuoteStrings
+    var <- (Just <$> (withPos pIdent <* string "<-")) <<|> pure Nothing
+    val <- ((:) <$> withPos pId <*> manyGreedy (withPos pArgument)) <|>
+           (box <$> withPos (Parens <$> pArg "()"))
+    return $ Unquote var val
+
+commentString :: String
+commentString = "%%"
+
+pComment :: Parser MarXup
+pComment = Comment <$> do
+  label "Comment" $ do
+    string commentString
+    munch (/= '\n')
+    string "\n"
+    return mempty
+
+parseFile :: String -> ([Haskell] -> IO ()) -> IO ()
+parseFile fname k = do
+  p <- parseFromFile (pHask <* endOfFile) completeResults fname
+  case p of
+    Left e -> handleErr e
+    Right [res] -> k res
+    Right _ -> hPutStrLn stderr "Amibiguous input!"
+
+handleErr e =
+   sequence_
+          [ hPutStrLn stderr (show $ maybePosToPos $ the pos) >>
+            hPutStrLn stderr ("  Expected:" ++ (intercalate " or " $ nub what))
+           | (exps,_why) <- e, (what,pos) <- exps, then group by pos using groupWith, then reverse ]
+
+----------------------------------------------
+-- Parsing helpers
+
+satisfy' :: (String -> Bool) -> Parser Char
+satisfy' p = do
+  l <- look
+  unless (p l) $
+    fail "Unexpected leading string"
+  anySymbol
+
+munch',munch1' :: (String -> Bool) -> Parser String
+munch' p = scan =<< look
+ where
+  scan (c:cs) | p (c:cs) = (:) <$> anySymbol <*> scan cs
+  scan _            = pure []
+
+munch1' p = (:) <$> satisfy' p <*> munch' p
+
+-- | A chunk not containing some strings
+pChunk' :: [String] -> Parser String
+pChunk' stops = munch1' (\l -> not $ any (`isPrefixOf` l) stops)
+
+
+-- | A chunk not containing some chars.
+pChunk :: [Char] -> Parser String
+pChunk stops = munch1 (not . (`elem` stops))
+
+
+-- Tests
+testHask = parse "<interactive>" pHask completeResults "arst « text @z<-fct[x](y) awft"
+testHask2 = parse "<interactive>" pHask completeResults "ars(t) « text @z<-fct[x](y) » awft"
+testText2 = parse "<interactive>" pTextArg completeResults "« text @fct(x »"
+testText3 = parse "<interactive>" pTextArg completeResults "« 1 @x 2 @y 3 @x 4 »"
+testElem = parse "<interactive>" pElement completeResults "@x<-fct(x « yop »)[y]"
+testChunk = parse "<interactive>" pHaskChunk completeResults "t"
+testArg = parse "<interactive>" (pArg "()") completeResults "()"
diff --git a/Output.hs b/Output.hs
new file mode 100644
--- /dev/null
+++ b/Output.hs
@@ -0,0 +1,43 @@
+module Output where
+
+import Text.ParserCombinators.Parsek.Position
+
+import Data.Monoid
+import Data.DList hiding (foldr, map)
+
+------------------
+-- Simple printing combinators, which do not add nor remove line breaks
+
+type Doc = DList Char
+
+text = fromList
+x <+> y =  x <> text " " <> y
+parens s = singleton '(' <> s <> singleton ')'
+braces s = singleton '{' <> s <> singleton '}'
+brackets s = singleton '[' <> s <> singleton ']'
+doubleQuotes s = singleton '"' <> s <> singleton '"'
+
+int x = text $ show x
+hcat :: [Doc] -> Doc
+hcat = foldr (<>) mempty
+punctuate t = map (<> t)
+render :: Doc -> String
+render = toList
+
+------------------------------------------
+-- Output combinators
+
+oPos :: SourcePos -> Doc
+oPos EOF = mempty
+oPos p = text "\n{-# LINE" <+> int (sourceLine p) <+> text (show (sourceName p)) <+> text "#-}\n" <>
+         Data.DList.replicate (sourceCol p) ' '
+
+oText :: String -> Doc
+oText x = text "textual" <+> text (show x)
+
+oConcat :: [Doc] -> Doc
+oConcat [] = text "return ()"
+oConcat [x] = x
+oConcat l = text "do" <+> braces (text "rec" <+> braces (hcat (punctuate (text ";") binds)) <> text ";" <> ret)
+  where binds = init l
+        ret = last l
diff --git a/examples/LaTeX.hs b/examples/LaTeX.hs
--- a/examples/LaTeX.hs
+++ b/examples/LaTeX.hs
@@ -1,28 +1,46 @@
-{-# OPTIONS_GHC -XTypeSynonymInstances -XOverloadedStrings -XRecursiveDo -pgmF marxup3 -F #-}
+{-# OPTIONS_GHC -XTypeSynonymInstances -XOverloadedStrings -XRecursiveDo -pgmF dist/build/marxup/marxup -F #-}
 
 import MarXup
 import MarXup.Latex
 import MarXup.Latex.Math
 import MarXup.Math
 import MarXup.Tex
+import MarXup.LineUp.Haskell
 import MarXup.DerivationTrees
 import MarXup.PrettyPrint as PP hiding (width)
 import MarXup.PrettyPrint.Core as PC
 import Control.Applicative
 import Data.Monoid
 import Control.Monad (unless)
-import MarXup.Diagram
-import MarXup.Diagram.Graphviz
+import MarXup.Diagram as D
+import Graphics.Diagrams.Plot
+import Graphics.Diagrams.Graphviz
 import Control.Lens (set)
-import Data.GraphViz
+import Data.GraphViz hiding (Plain)
 import Data.String
 import Data.Traversable
 import Data.GraphViz.Attributes.Complete
   (Attribute(RankSep,Shape,Label,Margin,Width,Len,RankDir),
    Shape(..),Label(StrLabel),DPoint(..),RankDir(..))
+import Numeric (showFFloat, showEFloat)
 
 data SExp = Atom String | SX [SExp]
 
+textualS = textual . ($ "")
+
+aPlot :: Dia
+aPlot = do
+  c@(bx,_) <- simplePlot (Point (textualS . showFFloat (Just 1)) (textualS . showEFloat (Just 0)))
+                         (vec (simplLinAxis 0.1,
+                               logAxis 10
+                               -- simplLinAxis 2000
+                              ))
+                         (map vec [(0.1,139),(0.35,10035),(0.23,1202)])
+  functionPlot c 100 (\x -> 100 + 300000*(x-0.2)^^2)
+  width bx === constant 200
+  height bx === constant 100
+  where vec (x,y) = Point x y
+
 prettyS :: SExp -> Tex Doc
 prettyS (Atom x) = PP.text (textual x)
 prettyS (SX xs) = do
@@ -42,23 +60,16 @@
   three = SX $ map Atom ["arstarsx","wftwfy","varstw","x","M"]
   six = SX [ three , three , three ]
 
-preamble inMP = do
+preamble body = do
   documentClass "article" []
   usepackage "inputenc" ["utf8x"]
-  unless inMP $ usepackage "tikz" []
   usepackage "graphicx" []
-
--- arrow :: Object -> Object -> Diagram Incidence
--- arrow src trg = using (outline "black" . set endTip ToTip) $ do
---   edge src trg
-
-autoLab s i = do
-  o <- labelObj s
-  autoLabel o i
+  env "document" body
 
 (▸) = flip (#)
 
-grDiag = graph Dot gr
+grDiag :: TexDiagram ()
+grDiag = graph tex Dot gr
 
 nod x = DotNode x [Margin (DVal 0),Width 0, Shape Circle, Label $ StrLabel $ fromString x]
 edg x y z = DotEdge x y [Label $ StrLabel z, Len 0.1]
@@ -71,21 +82,22 @@
       ,edg "B" "D" "3"
       ,edg "D" "A" "4"])
 
+testDiagram :: TexDiagram ()
 testDiagram = do
   -- draw $ path $ circle (Point 0 0) 5
-  a   <- labelObj $ ensureMath $ "a"
-  b   <- labelObj $ ensureMath $ "b"
-  a'  <- draw $ circleShape -- labelObj $ ensureMath $ "c"
-  width a' === 15
-  b'  <- labelObj $ ensureMath $ "d"
-  a'' <- labelObj $ ensureMath $ "."
-  b'' <- labelObj $ ensureMath $ "."
+  a   <- D.label "a" $ ensureMath $ "a"
+  b   <- D.label "b" $ ensureMath $ "b"
+  a'  <- draw $ circle "a'" -- label $ ensureMath $ "c"
+  width a' === constant 15
+  b'  <- D.label "b'" $ ensureMath $ "d"
+  a'' <- D.label "a''" $ ensureMath $ "."
+  b'' <- D.label "b''" $ ensureMath $ "."
 
   -- c <- texObj $ ensureMath $ "c"
   -- Center ▸ c === MP.center [E ▸ a'', E ▸ b''] + (20 +: 0)
 
-  let width = 70
-  vdist b a === 30
+  let width = constant 70
+  vdist b a === constant 30
   hdist a a' === width
   hdist a' a'' === width
   alignMatrix [[Center ▸ a, Center ▸ a',Center ▸ a'']
@@ -93,9 +105,9 @@
               ]
   autoLab "bing" =<< arrow a a'
   autoLab "bang" =<< arrow b b'
-  autoLab "oops" . swap =<< arrow a b
+  autoLab "oops" . turn180 =<< arrow a b
   autoLab "pif" =<< arrow a' a''
-  autoLab "paf" =<< arrow b' b'' 
+  autoLab "paf" =<< arrow b' b''
 
   draw $ do
     autoLab "equal" =<< edge a'' b''
@@ -129,8 +141,11 @@
 
 (≜) = binop 1 "="
 
-main = writeFile ("LaTeX.tex") =<< renderTex preamble «
 
+main = renderTex Plain "LaTeX" docu
+
+docu = preamble «
+
 @intro<-section«Intro»
 
 At-syntax is used to call a Haskell function. The result can be bound.
@@ -168,20 +183,39 @@
 @someTree
 
 @section«Diagrams»
-
-One can also draw diagrams:
 @testDiagram
+One can also draw diagrams:
 
 @section«Graphviz»
 
 There is partial, rudimentary support for layout of graphs using graphviz.
 
-grDiag
+@grDiag
+%% This is deactivated for now; it requires graphviz to be installed
 
 
+@section«Plots»
+
+@aPlot
+
+@cmd0"newpage"
+@section«Haskell»
+
+There is simple support for lhs2tex-style stuff.
+
+Another paragaph.
+
+
+@haskell«
+
+autoLab :: String -> OVector -> Diagram TeX Tex Object
+autoLab s = autoLabel s (textual s)
+
+»
+some text after
+
 @concl<-section«Conclusion»
 
 Mar@ensureMath«@cmd0"chi"»up is awesome :p .
 
 »
-
diff --git a/marxup.cabal b/marxup.cabal
--- a/marxup.cabal
+++ b/marxup.cabal
@@ -1,76 +1,63 @@
 name:           marxup
-version:        3.0.0.1
+version:        3.1.0.0
 category:       Text
 synopsis:       Markup language preprocessor for Haskell
 description:
   Markup syntax preprocessor for Haskell. Steals ideas from the Scribble project (in Scheme).
   The package also provides a DSL to output Latex seamlessly from MarXup output.
-license:        GPL
+license:        GPL-2
 license-file:   LICENSE
 author:         Jean-Philippe Bernardy
 maintainer:     jeanphilippe.bernardy@gmail.com
 Cabal-Version:  >= 1.8
-tested-with:    GHC==6.12.1
-tested-with:    GHC==7.4.1
 build-type:     Simple
 
 data-files:
      examples/LaTeX.hs
 
-
--- executable marxup
---   extensions: FlexibleInstances, TupleSections
---   main-is: Main.hs
---   build-depends: base>=4.2&&<=5
---   build-depends: pretty==1.1.*
---   build-depends: parsec>=3
---   build-depends: dlist>=0.5
+Flag example
+  Description: Compile example. This will generally not work unless you know what you're doing.
+  manual: True
+  Default:     False
 
-executable marxup3
+executable marxup
   extensions: FlexibleInstances, TupleSections
-  main-is: Main3.hs
+  main-is: Main.hs
   build-depends: configurator>=0.2&&<2
   build-depends: base>=4.2&&<=58
   build-depends: pretty==1.1.*
   build-depends: parsek==1.*
   build-depends: dlist>=0.7
-  other-modules: Config
-  
+  other-modules: Config, MarXupParser, Literate, Output
+
 library
   extensions: FlexibleInstances, TypeSynonymInstances, GADTs
   build-depends: base>=4.2&&<5
 --  build-depends: pandoc==1.5.*  (support broken)
   build-depends: mtl>=2.1
   build-depends: labeled-tree==1.*
-  build-depends: filepath==1.3.*
+  build-depends: filepath>=1.3 && <2
   build-depends: containers>=0.4 &&<1
   build-depends: process>=1.1
-  build-depends: glpk-hs>=0.3.4
-  build-depends: cubicbezier>=0.2
   build-depends: lens>=3.10
   build-depends: directory>=1.2
-  build-depends: typography-geometry
-  build-depends: polynomials-bernstein==1.*
-  build-depends: vector
-  build-depends: graphviz
+  build-depends: haskell-src-exts
+  build-depends: lp-diagrams
   build-depends: text
 
   exposed-modules: MarXup
   exposed-modules: MarXup.Tex
   exposed-modules: MarXup.Latex
   exposed-modules: MarXup.Latex.Math
+  exposed-modules: MarXup.LineUp
+  exposed-modules: MarXup.LineUp.Haskell
   exposed-modules: MarXup.Math
   exposed-modules: MarXup.Latex.Bib
   exposed-modules: MarXup.Beamer
   exposed-modules: MarXup.DerivationTrees
   exposed-modules: MarXup.Text
   exposed-modules: MarXup.Diagram
-  exposed-modules: MarXup.Diagram.Object
-  exposed-modules: MarXup.Diagram.Path
-  exposed-modules: MarXup.Diagram.Point
-  exposed-modules: MarXup.Diagram.Layout
   exposed-modules: MarXup.Diagram.Tikz
-  exposed-modules: MarXup.Diagram.Graphviz
   exposed-modules: MarXup.MultiRef
   exposed-modules: MarXup.Verbatim
   exposed-modules: MarXup.PrettyPrint.Core
@@ -78,3 +65,16 @@
   
 --  exposed-modules: MarXup.Pandoc (broken)
 
+executable marxup-example
+   if  flag(example)
+     buildable: True
+   else
+     buildable: False
+   hs-source-dirs: examples
+   main-is: LaTeX.hs
+   build-depends: marxup
+   build-depends: lp-diagrams
+   build-depends: base
+   build-depends: lens
+   build-depends: graphviz
+  
