git.iko.soy/typeable/pandoc
on master help sign in
Process LaTeX macros in markdown, and apply to TeX math.
6b722d1John MacFarlane
pandoc.cabal+1−1
@@ -157,7 +157,7 @@ Library
157 process >= 1, directory >= 1,
157 process >= 1, directory >= 1,
158 bytestring >= 0.9, zip-archive >= 0.1.1.4,
158 bytestring >= 0.9, zip-archive >= 0.1.1.4,
159 utf8-string >= 0.3, old-time >= 1,
159 utf8-string >= 0.3, old-time >= 1,
160− HTTP >= 4000.0.5, texmath >= 0.3, xml >= 1.3.5 && < 1.4,
160+ HTTP >= 4000.0.5, texmath >= 0.4, xml >= 1.3.5 && < 1.4,
161 random, extensible-exceptions
161 random, extensible-exceptions
162 if impl(ghc >= 6.10)
162 if impl(ghc >= 6.10)
163 Build-depends: base >= 4 && < 5, syb
163 Build-depends: base >= 4 && < 5, syb
src/Text/Pandoc/Parsing.hs+7−2
@@ -79,6 +79,7 @@ import Network.URI ( parseURI, URI (..), isAllowedInURI )
79import Control.Monad ( join, liftM )
79import Control.Monad ( join, liftM )
80import Text.Pandoc.Shared
80import Text.Pandoc.Shared
81import qualified Data.Map as M
81import qualified Data.Map as M
82+import Text.TeXMath.Macros (Macro)
82
83
83-- | Like >>, but returns the operation on the left.
84-- | Like >>, but returns the operation on the left.
84-- (Suggested by Tillmann Rendel on Haskell-cafe list.)
85-- (Suggested by Tillmann Rendel on Haskell-cafe list.)
@@ -602,7 +603,9 @@ data ParserState = ParserState
602 stateIndentedCodeClasses :: [String], -- ^ Classes to use for indented code blocks
603 stateIndentedCodeClasses :: [String], -- ^ Classes to use for indented code blocks
603 stateNextExample :: Int, -- ^ Number of next example
604 stateNextExample :: Int, -- ^ Number of next example
604 stateExamples :: M.Map String Int, -- ^ Map from example labels to numbers
605 stateExamples :: M.Map String Int, -- ^ Map from example labels to numbers
605− stateHasChapters :: Bool -- ^ True if \chapter encountered
606+ stateHasChapters :: Bool, -- ^ True if \chapter encountered
607+ stateApplyMacros :: Bool, -- ^ Apply LaTeX macros?
608+ stateMacros :: [Macro] -- ^ List of macros defined so far
606 }
609 }
607 deriving Show
610 deriving Show
608
611
@@ -630,7 +633,9 @@ defaultParserState =
630 stateIndentedCodeClasses = [],
633 stateIndentedCodeClasses = [],
631 stateNextExample = 1,
634 stateNextExample = 1,
632 stateExamples = M.empty,
635 stateExamples = M.empty,
633− stateHasChapters = False }
636+ stateHasChapters = False,
637+ stateApplyMacros = True,
638+ stateMacros = []}
634
639
635data HeaderType
640data HeaderType
636 = SingleHeader Char -- ^ Single line of characters underneath
641 = SingleHeader Char -- ^ Single line of characters underneath
src/Text/Pandoc/Readers/Markdown.hs+28−3
@@ -46,7 +46,8 @@ import Text.Pandoc.Readers.HTML ( rawHtmlBlock, anyHtmlBlockTag,
46 htmlBlockElement, htmlComment, unsanitaryURI )
46 htmlBlockElement, htmlComment, unsanitaryURI )
47import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
47import Text.Pandoc.CharacterReferences ( decodeCharacterReferences )
48import Text.ParserCombinators.Parsec
48import Text.ParserCombinators.Parsec
49−import Control.Monad (when, liftM, unless)
49+import Control.Monad (when, liftM, unless, guard)
50+import Text.TeXMath.Macros (applyMacros, Macro, pMacroDefinition)
50
51
51-- | Read markdown from an input string and return a Pandoc document.
52-- | Read markdown from an input string and return a Pandoc document.
52readMarkdown :: ParserState -- ^ Parser state, including options for parser
53readMarkdown :: ParserState -- ^ Parser state, including options for parser
@@ -284,6 +285,7 @@ block = do
284 , plain
285 , plain
285 , nullBlock ]
286 , nullBlock ]
286 else [ codeBlockDelimited
287 else [ codeBlockDelimited
288+ , macro
287 , header
289 , header
288 , table
290 , table
289 , codeBlockIndented
291 , codeBlockIndented
@@ -867,6 +869,29 @@ table = multilineTable False <|> simpleTable True <|>
867 simpleTable False <|> multilineTable True <|>
869 simpleTable False <|> multilineTable True <|>
868 gridTable False <|> gridTable True <?> "table"
870 gridTable False <|> gridTable True <?> "table"
869
871
872+--
873+-- Macros
874+--
875+
876+-- | Parse a \newcommand or \renewcommand macro definition.
877+macro :: GenParser Char ParserState Block
878+macro = getState >>= guard . stateApplyMacros >>
879+ pMacroDefinition >>= addMacro >> return Null
880+
881+-- | Add a macro to the list of macros in state.
882+addMacro :: Macro -> GenParser Char ParserState ()
883+addMacro m = do
884+ updateState $ \st -> st{ stateMacros = m : stateMacros st }
885+
886+-- | Apply current macros to string.
887+applyMacros' :: String -> GenParser Char ParserState String
888+applyMacros' target = do
889+ apply <- liftM stateApplyMacros getState
890+ if apply
891+ then do macros <- liftM stateMacros getState
892+ return $ applyMacros macros target
893+ else return target
894+
870--
895--
871-- inline
896-- inline
872--
897--
@@ -969,8 +994,8 @@ mathChunk = do char '\\'
969 <|> many1 (noneOf " \t\n\\$")
994 <|> many1 (noneOf " \t\n\\$")
970
995
971math :: GenParser Char ParserState Inline
996math :: GenParser Char ParserState Inline
972−math = (mathDisplay >>= return . Math DisplayMath)
997+math = (mathDisplay >>= applyMacros' >>= return . Math DisplayMath)
973− <|> (mathInline >>= return . Math InlineMath)
998+ <|> (mathInline >>= applyMacros' >>= return . Math InlineMath)
974
999
975mathDisplay :: GenParser Char ParserState String
1000mathDisplay :: GenParser Char ParserState String
976mathDisplay = try $ do
1001mathDisplay = try $ do
src/pandoc.hs+3−2
@@ -786,10 +786,11 @@ main = do
786 stateCitations = map citeKey refs,
786 stateCitations = map citeKey refs,
787#endif
787#endif
788 stateSmart = smart || writerName' `elem`
788 stateSmart = smart || writerName' `elem`
789− ["latex", "context", "man"],
789+ ["latex", "context", "latex+lhs", "man"],
790 stateColumns = columns,
790 stateColumns = columns,
791 stateStrict = strict,
791 stateStrict = strict,
792− stateIndentedCodeClasses = codeBlockClasses }
792+ stateIndentedCodeClasses = codeBlockClasses,
793+ stateApplyMacros = writerName' `notElem` ["latex", "latex+lhs"] }
793
794
794 let writerOptions = WriterOptions { writerStandalone = standalone',
795 let writerOptions = WriterOptions { writerStandalone = standalone',
795 writerTemplate = if null template
796 writerTemplate = if null template