content: {-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
  module PrintXPath where
  
  -- pretty-printer generated by the BNF converter
  
  import AbsXPath
  import Data.Char
  
  
  -- the top-level printing method
  printTree :: Print a => a -> String
  printTree = render . prt 0
  
  type Doc = [ShowS] -> [ShowS]
  
  doc :: ShowS -> Doc
  doc = (:)
  
  render :: Doc -> String
  render d = rend 0 (map ($ "") $ d []) "" where
    rend i ss = case ss of
      "["      :ts -> showChar '[' . rend i ts
      "("      :ts -> showChar '(' . rend i ts
      "{"      :ts -> showChar '{' . new (i+1) . rend (i+1) ts
      "}" : ";":ts -> new (i-1) . space "}" . showChar ';' . new (i-1) . rend (i-1) ts
      "}"      :ts -> new (i-1) . showChar '}' . new (i-1) . rend (i-1) ts
      ";"      :ts -> showChar ';' . new i . rend i ts
      t  : "," :ts -> showString t . space "," . rend i ts
      t  : ")" :ts -> showString t . showChar ')' . rend i ts
      t  : "]" :ts -> showString t . showChar ']' . rend i ts
      t        :ts -> space t . rend i ts
      _            -> id
    new i   = showChar '\n' . replicateS (2*i) (showChar ' ') . dropWhile isSpace
    space t = showString t . (\s -> if null s then "" else (' ':s))
  
  parenth :: Doc -> Doc
  parenth ss = doc (showChar '(') . ss . doc (showChar ')')
  
  concatS :: [ShowS] -> ShowS
  concatS = foldr (.) id
  
  concatD :: [Doc] -> Doc
  concatD = foldr (.) id
  
  replicateS :: Int -> ShowS -> ShowS
  replicateS n f = concatS (replicate n f)
  
  -- the printer class does the job
  class Print a where
    prt :: Int -> a -> Doc
    prtList :: [a] -> Doc
    prtList = concatD . map (prt 0)
  
  instance Print a => Print [a] where
    prt _ = prtList
  
  instance Print Char where
    prt _ s = doc (showChar '\'' . mkEsc '\'' s . showChar '\'')
    prtList s = doc (showChar '"' . concatS (map (mkEsc '"') s) . showChar '"')
  
  mkEsc :: Char -> Char -> ShowS
  mkEsc q s = case s of
    _ | s == q -> showChar '\\' . showChar s
    '\\'-> showString "\\\\"
    '\n' -> showString "\\n"
    '\t' -> showString "\\t"
    _ -> showChar s
  
  prPrec :: Int -> Int -> Doc -> Doc
  prPrec i j = if j<i then parenth else id
  
  
  instance Print Integer where
    prt _ x = doc (shows x)
  
  
  instance Print Double where
    prt _ x = doc (shows x)
  
  
  instance Print Ident where
    prt _ (Ident i) = doc (showString ( i))
  
  
  
  instance Print XPath where
    prt i e = case e of
     XPCont xaxis xitem xcond xpath -> prPrec i 0 (concatD [prt 0 xaxis , prt 0 xitem , prt 0 xcond , prt 0 xpath])
     XPEnd  -> prPrec i 0 (concatD [])
  
  
  instance Print XAxis where
    prt i e = case e of
     XAPlain  -> prPrec i 0 (concatD [doc (showString "/")])
     XADesc  -> prPrec i 0 (concatD [doc (showString "//")])
  
  
  instance Print XItem where
    prt i e = case e of
     XINone  -> prPrec i 0 (concatD [])
     XIElem id -> prPrec i 0 (concatD [prt 0 id])
     XIAttr id -> prPrec i 0 (concatD [doc (showString "@") , prt 0 id])
     XIAxis id0 id -> prPrec i 0 (concatD [prt 0 id0 , doc (showString "::") , prt 0 id])
     XIAnces  -> prPrec i 0 (concatD [doc (showString "..")])
  
  
  instance Print XCond where
    prt i e = case e of
     XCNone  -> prPrec i 0 (concatD [])
     XCOp xexp0 xop xexp -> prPrec i 0 (concatD [doc (showString "[") , prt 0 xexp0 , prt 0 xop , prt 0 xexp , doc (showString "]")])
  
  
  instance Print XExp where
    prt i e = case e of
     XEPath xpath -> prPrec i 0 (concatD [prt 0 xpath])
     XEIdent id -> prPrec i 0 (concatD [prt 0 id])
     XEAttr id -> prPrec i 0 (concatD [doc (showString "@") , prt 0 id])
     XEInt n -> prPrec i 0 (concatD [prt 0 n])
     XEStr str -> prPrec i 0 (concatD [prt 0 str])
  
  
  instance Print XOp where
    prt i e = case e of
     XOEq  -> prPrec i 0 (concatD [doc (showString "=")])
     XONEq  -> prPrec i 0 (concatD [doc (showString "!=")])
  
  
  
  