This prevents girders from erasing landbacktex (square windows in tunnels and such), at the cost of requiring lfBasic and lfObject to be treated the same apart from graphically
module PascalParser whereimport Text.ParserCombinators.Parsecimport Control.Monaddata PascalUnit = Program Identificator Implementation FunctionBody | Unit Identificator Interface Implementation (Maybe Initialize) (Maybe Finalize) deriving Showdata Interface = Interface Uses TypesAndVars deriving Showdata Implementation = Implementation Uses TypesAndVars Functions deriving Showdata Functions = Functions [Function] deriving Showdata Function = Function String deriving Showdata Identificator = Identificator String deriving Showdata FunctionBody = FunctionBody String deriving Showdata TypesAndVars = TypesAndVars String deriving Showdata Initialize = Initialize Functions deriving Showdata Finalize = Finalize Functions deriving Showdata Uses = Uses [Identificator] deriving ShowparsePascalUnit :: String -> Either ParseError PascalUnitparsePascalUnit = parse pascalUnit "unit" where comments = skipMany (comment >> spaces) identificator = do spaces l <- letter <|> oneOf "_" ls <- many (alphaNum <|> oneOf "_") spaces return $ Identificator (l:ls) pascalUnit = do spaces comments u <- choice [program, unit] comments spaces return u comment = choice [ char '{' >> manyTill anyChar (try $ char '}') , string "(*" >> manyTill anyChar (try $ string "*)") , string "//" >> manyTill anyChar (try newline) ] unit = do name <- unitName spaces comments int <- string "interface" >> interface manyTill anyChar (try $ string "implementation") spaces comments impl <- implementation return $ Unit name int impl Nothing Nothing where unitName = between (string "unit") (char ';') identificator interface = do spaces comments u <- uses return $ Interface u (TypesAndVars "") program = do name <- programName spaces comments impl <- implementation return $ Program name impl (FunctionBody "") where programName = between (string "program") (char ';') identificator implementation = do u <- uses manyTill anyChar (try $ string "end.") return $ Implementation u (TypesAndVars "") (Functions []) uses = liftM Uses (option [] u) where u = do string "uses" spaces u <- (identificator >>= \i -> spaces >> return i) `sepBy1` (char ',' >> spaces) char ';' spaces return u