[Haskell] Latex and Bibtex

Doaitse Swierstra doaitse at cs.uu.nl
Thu Apr 7 05:13:58 EDT 2005


At least I can provide you with a bibtex parser written using the  
Utrecht Parser Combinators. As you will see from the text the bibtex  
format is actually quite intricate.

  Doaitse Swierstra



--  $Header:  
/data/cvs-rep/uust/examples/bibtex-parser/BibtexParser.hs,v 1.8  
2002/11/08 12:48:00 uust Exp $
--  $Name:  $ (version name)
{- Fast, Error Correcting Parser Combinators; Version: see Version  
History in same directory.
  - Copyright:  S. Doaitse Swierstra
                Department of Computer Science
                Utrecht University
                P.O. Box 80.089
                3508 TB UTRECHT
                the Netherlands
                swierstra at cs.uu.nl
-}

{- file: bibtex6.hs
    A parser for BibTeX
    using the UU parsing combinators
    Piet van Oostrum, Atze Dijkstra, Doaitse Swierstra (April 22, 2001)
-}
module Main where
import UU.Parsing
import UU.Parsing.CharParser
import UU.Scanner.Position
import System
import Char

showMessage (Msg exp pos action) =
   "\nParse error: " ++  show pos ++ "\n" ++
   actionMessage ++ "\n"
  where actionMessage = case action of
                         Insert s -> "expecting: " ++ show exp ++
                                     "\nrepaired by inserting " ++ show s
                         Delete s -> "expecting: " ++ show exp ++
                                     "\nrepaired by deleting unexpected  
symbol " ++ show s
                         Other m  -> m

parsebib filename -- e.g. parsebib "btxdoc.bib"
   = do res   <- parseFile showMessage pBibData filename
        putStrLn ("\nResult:" ++ show (length res) ++ " bib items were  
parsed")

main
   = do args <- getArgs
        if null args
          then putStr "BibtexParser <bibfile>\n"
          else parsebib (head args)

--  
======================================================================== 
===============
-- ===== DATA TYPES  
======================================================================
--  
======================================================================== 
===============
type BibParser = AnaParser Input Pair Char Pos

type BibData  = [ BibEntry]

data BibEntry = Entry     String  (String, [Field])  -- kind keyword  
fieldlist
	             | Comment   String
	             | Preamble  [ValItem]
	             | StringDef Field
               deriving Show

type Field    = (String, [ValItem])

data ValItem  = StringVal String
	             | IntVal    Int
	             | NameUse   String
	            	deriving Show
--  
======================================================================== 
===============
-- ===== PARSERS  
======================================================================== 
=
--  
======================================================================== 
===============
pBibData    = pChainr ((\ entry  _ right -> entry:right) <$> pBibEntry)
                       ( [] <$ pList (allChars `pExcept` "@"))

pBibEntry
  =  (   Entry     <$ pAt <*> pName           <*> pOpenClose (    
pKeyName       <*  pSpec ','
		                                                          <+>  
pListSep_ng pComma pField
                                                             <* (pComma  
`opt` ' '))
     <|> Comment   <$ pAt <*  pKey "comment"  <*> (  pCurly (pList  
(allChars `pExcept` "}"))
	                                               <|> pParen (pList  
(allChars `pExcept` ")"))
                                                  )
     <|> Preamble  <$ pAt <*  pKey "preamble" <*> pOpenClose pValItems
     <|> StringDef <$ pAt <*  pKey "string"   <*> pOpenClose pField
     )

pField     :: BibParser (String, [ValItem])
pField     =  pName <* pSpec '=' <+> pValItems

pValItems  =  pList1Sep (pSpec '#') (   StringVal   <$> pString
	                                   <|> int_or_name <$> pName
                                     )
               where int_or_name s = if all isDigit s
                                     then IntVal.(read::String->Int) $ s
                                     else NameUse s
--  
======================================================================== 
===============
-- ===== LEXICAL STUFF  
===================================================================
--  
======================================================================== 
===============
pLAYOUT :: BibParser String
pLAYOUT = pList (EOr [] `setfirsts` pAnySym " \t\r\n")
pSpec c = pSym c  <* pLAYOUT

pParen      p = pPacked (pSpec '(') (pSpec ')') p
pCurly      p = pPacked (pSpec '{') (pSpec '}') p
pOpenClose  p = pParen p <|> pCurly p
pComma        = pCostSym  4 ',' ',' <* pLAYOUT
pAt           = pSpec '@'

allChars = (chr 1, chr 127, ' ')

pName     = pList1 ('a'<..>'z' <|> 'A'<..>'Z' <|> '0'<..>'9'  <|>  
pAnySym "-_/") <* pLAYOUT
pKeyName  = pList1 ((chr 33, chr 127, ' ') `pExcept` ",=@"               
        ) <* pLAYOUT

pKey [s]     = lift <$> (pSym s <|> pSym (toUpper s)) <*  pLAYOUT
pKey (s:ss)  = (:)  <$> (pSym s <|> pSym (toUpper s)) <*> pKey ss
pKey []      = error "Scanner: You cannot have empty reserved words!"

pString
  = let  curlyStrings  = stringcons <$> pSym '{' <*> pConc pStringWord  
<*> pSym '}'
         pStringWordDQ = lift       <$> pStringCharDQ <|> curlyStrings
         pStringWord   = lift       <$> pStringChar   <|> curlyStrings
         pStringCharDQ = allChars `pExcept` "\"{}"
         pStringChar   = pStringCharDQ <|> pSym '\"'
         pConc         = pFoldr ((++),[])
         stringcons c1 ss c2 = [c1] ++ ss ++ [c2]
    in (   pSym '"' *> pConc pStringWordDQ <* pSym '"'
	     <|> pSym '{' *> pConc pStringWord   <* pSym '}'
       ) <* pLAYOUT

lift c              = [c]



On 2005 apr 07, at 4:18, Thomas Bevan wrote:

> Does anyone know of any work being done on Latex with Haskell?
>
> I am particularly interested in finding a Haskell replacement to  
> Bibtex.
>
> Thanks.
>
> Tom
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell



More information about the Haskell mailing list