Commits

John Lenz committed d11050f

Be smarter about looking for closing brace or bracket in commands

  • Participants
  • Parent commits 2b7363f

Comments (0)

Files changed (11)

File src/Text/LatexCandle/Errors.hs

 -- This is used to mark the start column for a warning or message which spans
 -- multiple columns.  The mark is passed to 'tellErrsR' or 'tellErrR'
 newtype Mark = Mark SourcePos
-    deriving (Show,Eq)
+    deriving (Eq)
+
+instance Show Mark where
+    show (Mark s) = "line " ++ show (sourceLine s) ++ ", column " ++ show (sourceColumn s)
 
 -- | Stores a range of the input.
 type Range = (Mark,Mark)

File src/Text/LatexCandle/Parser.hs

    whitespace
    eof <|> tellErr "Extra characters after \\end{document}"
 
--- | Parse a LaTeX document.  Calls either 'latexBody' or 'latexFullDoc' depending
--- on options or if no options are given detecting the existance of documentclass
+-- | Parse a LaTeX document.
+--
+-- Calls either 'latexBody' or 'latexFullDoc' depending
+-- on options. If no options are given, it detects the existance of documentclass and runs
+-- the proper parser.
 latexParser :: LatexP ()
 latexParser = do
     onlybody <- asks optOnlyBody

File src/Text/LatexCandle/Parser/Base.hs

     -- * Basic parsers
   , whitespace
   , string_
+  , lookFor
 
     -- * Re-exports
   , module X
                <|> void newline
                <|> void (char '%' >> manyTill anyChar newline))
 
+
+-- | A parser which looks for something (usually end brace or bracket).  If it
+-- is found on the current line, this parser consumes up to and including it
+-- and logs a warning if there is text in the way using the provided message.
+-- If the character is not found, the parser fails.
+lookFor :: LatexP () -- ^ what to look for
+        -> String    -- ^ message if it is found on the current line
+        -> LatexP ()
+lookFor x m = (try x >> whitespace) <|> inline
+  where inline = try $ do s <- mark
+                          void $ manyTill (satisfy (/='\n')) (try x)
+                          tellErrM s m
+                          whitespace

File src/Text/LatexCandle/Parser/Commands.hs

                      void (char '[')
                      whitespace
                      r <- sepBy1 arg (char ',')
-                     void (char ']') <|> tellErrM start "No matching closing bracket ']' found"
+                     lookFor (void $ char ']') "Invalid characters in optional argument"
+                         <|> tellErrs [ "Opening bracket at " ++ show start ++ " has no closing bracket."
+                                      , "Assuming closing bracket exists here."
+                                      ]
                      whitespace
                      return $ filter (\(_,s) -> not (null s)) r
 
         arg = do whitespace
                  start <- mark
                  s <- many alphaNum
-                 when (null s) $ tellErr "Expecting optional argument string"
+                 when (null s) $ tellErr "Expecting an optional argument"
                  r <- range start
                  whitespace
                  return (r, s)
     start <- mark
     void (char '{')
     ret <- inner
+    lookFor (void $ char '}') "Invalid characters in command argument"
+      <|> tellErrs [ "Opening brace at " ++ show start ++ " has no closing brace."
+                   , "Assuming closing brace exists here."
+                   ]
     whitespace
-    void (char '}') <|> tellErrM start "No matching closing brace '}' found"
     return ret

File test/generror.sh

 
 if [ "$errs" != "" ]; then
 	( echo "%Run:$name: $args"
-	  echo "$errs" | sed 's/^[^:]*/%/'
+	  echo "$errs" | sed 's/^[^:]*:/:/' | sed 's/^/%/'
 	  echo "%EndErrors"
 	  echo ""
 	) >> $1

File test/test.hs

 -- drop filename and the final newline
 procErrs :: [LatexError] -> [String]
 procErrs = concatMap proc
-  where proc e = map (dropWhile (/=':')) $ lines $ show e
+  where proc e = map dropFile $ lines $ show e
+        dropFile x | ':' `elem` x = dropWhile (/=':') x
+                   | otherwise    = x
 
 runTest :: FilePath -> SingleRun -> Test
 runTest f (SingleRun name opt []) = testCase name $ do

File test/tex/docclass-bad-arg.tex

 Hello world
 \end{document}
 %Run:default: 
-%:1:23: Expecting optional argument string
+%:1:23: Expecting an optional argument
 %EndErrors
 

File test/tex/docclass-invalid-chars-arg.tex

+\documentclass[arg1, arg2,arg3, a$#^ ]{article}
+\begin{document}
+Hello, world
+\end{document}
+%Run:default: 
+%:1:34-39: Invalid characters in optional argument
+%EndErrors
+

File test/tex/docclass-invalid-chars-doctype.tex

+\documentclass[arg1]{ article &@# }
+\begin{document}
+Hello world
+\end{document}
+%Run:default: 
+%:1:31-36: Invalid characters in command argument
+%EndErrors
+

File test/tex/docclass-missing-end-arg.tex

 Hello, world
 \end{document}
 %Run:default: 
-%:1:15-27: No matching closing bracket ']' found
+%:1:27:+ Opening bracket at line 1, column 15 has no closing bracket.
+%        Assuming closing bracket exists here.
 %EndErrors
 

File test/tex/docclass-missing-end-brace.tex

 Hello there
 \end{document}
 %Run:default: 
-%:1:21: No matching closing brace '}' found
+%:2:1:+ Opening brace at line 1, column 21 has no closing brace.
+%        Assuming closing brace exists here.
 %EndErrors