@@ -1,14 +1,10 @@
1−{-# LANGUAGE BangPatterns #-}
3−{-# LANGUAGE FlexibleInstances #-}
4−{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE PatternGuards #-}
2{-# LANGUAGE PatternGuards #-}
7{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
8{-# LANGUAGE ViewPatterns #-}
4{-# LANGUAGE ViewPatterns #-}
10 Module : Text.Pandoc.Readers.LaTeX
6 Module : Text.Pandoc.Readers.LaTeX
11− Copyright : Copyright (C) 2006-2020 John MacFarlane
7+ Copyright : Copyright (C) 2006-2021 John MacFarlane
12 License : GNU GPL, version 2 or above
8 License : GNU GPL, version 2 or above
14 Maintainer : John MacFarlane <jgm@berkeley.edu>
10 Maintainer : John MacFarlane <jgm@berkeley.edu>
@@ -22,50 +18,58 @@ module Text.Pandoc.Readers.LaTeX ( readLaTeX,
22 applyMacros,
18 applyMacros,
23 rawLaTeXInline,
19 rawLaTeXInline,
24 rawLaTeXBlock,
20 rawLaTeXBlock,
25− inlineCommand,
21+ inlineCommand
30import Control.Applicative (many, optional, (<|>))
24import Control.Applicative (many, optional, (<|>))
31import Control.Monad
25import Control.Monad
32import Control.Monad.Except (throwError)
26import Control.Monad.Except (throwError)
33−import Data.Char (isDigit, isLetter, toUpper, chr)
27+import Data.Char (isDigit, isLetter, isAlphaNum, toUpper, chr)
34import Data.Default
28import Data.Default
35−import Data.Functor (($>))
36import Data.List (intercalate)
29import Data.List (intercalate)
37import qualified Data.Map as M
30import qualified Data.Map as M
38import Data.Maybe (fromMaybe, maybeToList)
31import Data.Maybe (fromMaybe, maybeToList)
39import qualified Data.Set as Set
32import qualified Data.Set as Set
40−import qualified Data.Sequence as Seq
41import Data.Text (Text)
33import Data.Text (Text)
42import qualified Data.Text as T
34import qualified Data.Text as T
35+import Skylighting (defaultSyntaxMap)
43import System.FilePath (addExtension, replaceExtension, takeExtension)
36import System.FilePath (addExtension, replaceExtension, takeExtension)
44−import Text.Pandoc.BCP47 (Lang (..), renderLang)
37+import Text.Collate.Lang (renderLang)
45−import Text.Pandoc.Builder
38+import Text.Pandoc.Builder as B
46import Text.Pandoc.Class.PandocPure (PandocPure)
39import Text.Pandoc.Class.PandocPure (PandocPure)
47import Text.Pandoc.Class.PandocMonad (PandocMonad (..), getResourcePath,
40import Text.Pandoc.Class.PandocMonad (PandocMonad (..), getResourcePath,
48− readFileFromDirs, report, setResourcePath,
41+ readFileFromDirs, report,
49− setTranslations, translateTerm)
42+ setResourcePath)
50import Text.Pandoc.Error (PandocError (PandocParseError, PandocParsecError))
43import Text.Pandoc.Error (PandocError (PandocParseError, PandocParsecError))
51−import Text.Pandoc.Highlighting (fromListingsLanguage, languagesByExtension)
44+import Text.Pandoc.Highlighting (languagesByExtension)
52import Text.Pandoc.ImageSize (numUnit, showFl)
45import Text.Pandoc.ImageSize (numUnit, showFl)
53import Text.Pandoc.Logging
46import Text.Pandoc.Logging
54import Text.Pandoc.Options
47import Text.Pandoc.Options
55import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
48import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
56 optional, space, spaces, withRaw, (<|>))
49 optional, space, spaces, withRaw, (<|>))
57−import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
50+import Text.Pandoc.Readers.LaTeX.Types (Tok (..), TokType (..))
58− ArgSpec (..), Tok (..), TokType (..))
59import Text.Pandoc.Readers.LaTeX.Parsing
51import Text.Pandoc.Readers.LaTeX.Parsing
60−import Text.Pandoc.Readers.LaTeX.Lang (polyglossiaLangToBCP47,
52+import Text.Pandoc.Readers.LaTeX.Citation (citationCommands, cites)
61− babelLangToBCP47)
53+import Text.Pandoc.Readers.LaTeX.Math (dollarsMath, inlineEnvironments,
62−import Text.Pandoc.Readers.LaTeX.SIunitx
54+ inlineEnvironment,
55+ mathDisplay, mathInline,
56+ newtheorem, theoremstyle, proof,
58+import Text.Pandoc.Readers.LaTeX.Table (tableEnvironments)
59+import Text.Pandoc.Readers.LaTeX.Macro (macroDef)
60+import Text.Pandoc.Readers.LaTeX.Lang (inlineLanguageCommands,
62+ babelLangToBCP47, setDefaultLanguage)
63+import Text.Pandoc.Readers.LaTeX.SIunitx (siunitxCommands)
64+import Text.Pandoc.Readers.LaTeX.Inline (acronymCommands, refCommands,
65+ nameCommands, charCommands,
67+ biblatexInlineCommands,
68+ verbCommands, rawInlineOr,
63import Text.Pandoc.Shared
70import Text.Pandoc.Shared
64−import qualified Text.Pandoc.Translations as Translations
65import Text.Pandoc.Walk
71import Text.Pandoc.Walk
66−import qualified Text.Pandoc.Builder as B
72+import Data.List.NonEmpty (nonEmpty)
67−import qualified Data.Text.Normalize as Normalize
70-- for debugging:
74-- for debugging:
71-- import Text.Pandoc.Extensions (getDefaultExtensions)
75-- import Text.Pandoc.Extensions (getDefaultExtensions)
@@ -73,16 +77,17 @@ import Safe
73-- import Debug.Trace (traceShowId)
77-- import Debug.Trace (traceShowId)
75-- | Parse LaTeX from string and return 'Pandoc' document.
79-- | Parse LaTeX from string and return 'Pandoc' document.
76−readLaTeX :: PandocMonad m
80+readLaTeX :: (PandocMonad m, ToSources a)
77 => ReaderOptions -- ^ Reader options
81 => ReaderOptions -- ^ Reader options
78− -> Text -- ^ String to parse (assumes @'\n'@ line endings)
82+ -> a -- ^ Input to parse
79 -> m Pandoc
83 -> m Pandoc
80readLaTeX opts ltx = do
84readLaTeX opts ltx = do
85+ let sources = toSources ltx
81 parsed <- runParserT parseLaTeX def{ sOptions = opts } "source"
86 parsed <- runParserT parseLaTeX def{ sOptions = opts } "source"
82− (tokenize "source" (crFilter ltx))
87+ (tokenizeSources sources)
83 case parsed of
88 case parsed of
84 Right result -> return result
89 Right result -> return result
85− Left e -> throwError $ PandocParsecError ltx e
90+ Left e -> throwError $ PandocParsecError sources e
87parseLaTeX :: PandocMonad m => LP m Pandoc
92parseLaTeX :: PandocMonad m => LP m Pandoc
88parseLaTeX = do
93parseLaTeX = do
@@ -93,11 +98,7 @@ parseLaTeX = do
93 let doc' = doc bs
98 let doc' = doc bs
94 let headerLevel (Header n _ _) = [n]
99 let headerLevel (Header n _ _) = [n]
95 headerLevel _ = []
100 headerLevel _ = []
96−#if MIN_VERSION_safe(0,3,18)
101+ let bottomLevel = maybe 1 minimum $ nonEmpty $ query headerLevel doc'
97− let bottomLevel = minimumBound 1 $ query headerLevel doc'
99− let bottomLevel = minimumDef 1 $ query headerLevel doc'
101 let adjustHeaders m (Header n attr ils) = Header (n+m) attr ils
102 let adjustHeaders m (Header n attr ils) = Header (n+m) attr ils
102 adjustHeaders _ x = x
103 adjustHeaders _ x = x
103 let (Pandoc _ bs') =
104 let (Pandoc _ bs') =
@@ -132,11 +133,11 @@ resolveRefs _ x = x
134rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
135rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
135− => ParserT Text s m Text
136+ => ParserT Sources s m Text
136rawLaTeXBlock = do
137rawLaTeXBlock = do
137 lookAhead (try (char '\\' >> letter))
138 lookAhead (try (char '\\' >> letter))
138 inp <- getInput
139 inp <- getInput
139− let toks = tokenize "source" inp
140+ let toks = tokenizeSources inp
140 snd <$> (rawLaTeXParser toks False (macroDef (const mempty)) blocks
141 snd <$> (rawLaTeXParser toks False (macroDef (const mempty)) blocks
141 <|> rawLaTeXParser toks True
142 <|> rawLaTeXParser toks True
142 (do choice (map controlSeq
143 (do choice (map controlSeq
@@ -163,14 +164,14 @@ beginOrEndCommand = try $ do
163 (txt <> untokenize rawargs)
164 (txt <> untokenize rawargs)
165rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
166rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
166− => ParserT Text s m Text
167+ => ParserT Sources s m Text
167rawLaTeXInline = do
168rawLaTeXInline = do
168 lookAhead (try (char '\\' >> letter))
169 lookAhead (try (char '\\' >> letter))
169 inp <- getInput
170 inp <- getInput
170− let toks = tokenize "source" inp
171+ let toks = tokenizeSources inp
171 raw <- snd <$>
172 raw <- snd <$>
172 ( rawLaTeXParser toks True
173 ( rawLaTeXParser toks True
173− (mempty <$ (controlSeq "input" >> skipMany opt >> braced))
174+ (mempty <$ (controlSeq "input" >> skipMany rawopt >> braced))
175 <|> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
176 <|> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
@@ -178,11 +179,11 @@ rawLaTeXInline = do
178 finalbraces <- mconcat <$> many (try (string "{}")) -- see #5439
179 finalbraces <- mconcat <$> many (try (string "{}")) -- see #5439
179 return $ raw <> T.pack finalbraces
180 return $ raw <> T.pack finalbraces
181−inlineCommand :: PandocMonad m => ParserT Text ParserState m Inlines
182+inlineCommand :: PandocMonad m => ParserT Sources ParserState m Inlines
182inlineCommand = do
183inlineCommand = do
183 lookAhead (try (char '\\' >> letter))
184 lookAhead (try (char '\\' >> letter))
184 inp <- getInput
185 inp <- getInput
185− let toks = tokenize "source" inp
186+ let toks = tokenizeSources inp
186 fst <$> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
187 fst <$> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
@@ -191,12 +192,6 @@ inlineCommand = do
191word :: PandocMonad m => LP m Inlines
192word :: PandocMonad m => LP m Inlines
192word = str . untoken <$> satisfyTok isWordTok
193word = str . untoken <$> satisfyTok isWordTok
194−regularSymbol :: PandocMonad m => LP m Inlines
195−regularSymbol = str . untoken <$> satisfyTok isRegularSymbol
196− where isRegularSymbol (Tok _ Symbol t) = not $ T.any isSpecial t
197− isRegularSymbol _ = False
198− isSpecial c = c `Set.member` specialChars
200inlineGroup :: PandocMonad m => LP m Inlines
195inlineGroup :: PandocMonad m => LP m Inlines
201inlineGroup = do
196inlineGroup = do
202 ils <- grouped inline
197 ils <- grouped inline
@@ -237,19 +232,6 @@ mkImage options (T.unpack -> src) = do
237 _ -> return src
232 _ -> return src
238 return $ imageWith attr (T.pack src') "" alt
233 return $ imageWith attr (T.pack src') "" alt
240−doxspace :: PandocMonad m => LP m Inlines
242− (space <$ lookAhead (satisfyTok startsWithLetter)) <|> return mempty
243− where startsWithLetter (Tok _ Word t) =
245− Just (c, _) | isLetter c -> True
247− startsWithLetter _ = False
250−lit :: Text -> LP m Inlines
253removeDoubleQuotes :: Text -> Text
235removeDoubleQuotes :: Text -> Text
254removeDoubleQuotes t =
236removeDoubleQuotes t =
255 Data.Maybe.fromMaybe t $ T.stripPrefix "\"" t >>= T.stripSuffix "\""
237 Data.Maybe.fromMaybe t $ T.stripPrefix "\"" t >>= T.stripSuffix "\""
@@ -296,23 +278,14 @@ quoted' f starter ender = do
296 cs -> cs)
278 cs -> cs)
297 else lit startchs
279 else lit startchs
299−enquote :: PandocMonad m => Bool -> Maybe Text -> LP m Inlines
281+lit :: Text -> LP m Inlines
300−enquote starred mblang = do
282+lit = pure . str
302− let lang = mblang >>= babelLangToBCP47
303− let langspan = case lang of
305− Just l -> spanWith ("",[],[("lang", renderLang l)])
306− quoteContext <- sQuoteContext <$> getState
307− if starred || quoteContext == InDoubleQuote
308− then singleQuoted . langspan <$> withQuoteContext InSingleQuote tok
309− else doubleQuoted . langspan <$> withQuoteContext InDoubleQuote tok
311blockquote :: PandocMonad m => Bool -> Maybe Text -> LP m Blocks
284blockquote :: PandocMonad m => Bool -> Maybe Text -> LP m Blocks
312blockquote cvariant mblang = do
285blockquote cvariant mblang = do
313 citepar <- if cvariant
286 citepar <- if cvariant
314 then (\xs -> para (cite xs mempty))
287 then (\xs -> para (cite xs mempty))
315− <$> cites NormalCitation False
288+ <$> cites inline NormalCitation False
316 else option mempty $ para <$> bracketed inline
289 else option mempty $ para <$> bracketed inline
317 let lang = mblang >>= babelLangToBCP47
290 let lang = mblang >>= babelLangToBCP47
318 let langdiv = case lang of
291 let langdiv = case lang of
@@ -323,224 +296,13 @@ blockquote cvariant mblang = do
323 optional $ symbolIn (".:;?!" :: [Char]) -- currently ignored
296 optional $ symbolIn (".:;?!" :: [Char]) -- currently ignored
324 return $ blockQuote . langdiv $ (bs <> citepar)
297 return $ blockQuote . langdiv $ (bs <> citepar)
326−doAcronym :: PandocMonad m => Text -> LP m Inlines
329− return . mconcat $ [spanWith ("",[],[("acronym-label", untokenize acro),
330− ("acronym-form", "singular+" <> form)])
331− $ str $ untokenize acro]
333−doAcronymPlural :: PandocMonad m => Text -> LP m Inlines
334−doAcronymPlural form = do
337− return . mconcat $ [spanWith ("",[],[("acronym-label", untokenize acro),
338− ("acronym-form", "plural+" <> form)]) $
339− mconcat [str $ untokenize acro, plural]]
341−doverb :: PandocMonad m => LP m Inlines
343− Tok _ Symbol t <- anySymbol
344− marker <- case T.uncons t of
345− Just (c, ts) | T.null ts -> return c
348− code . untokenize <$>
349− manyTill (notFollowedBy newlineTok >> verbTok marker) (symbol marker)
351−verbTok :: PandocMonad m => Char -> LP m Tok
352−verbTok stopchar = do
353− t@(Tok pos toktype txt) <- anyTok
354− case T.findIndex (== stopchar) txt of
357− let (t1, t2) = T.splitAt i txt
359− setInput $ Tok (incSourceColumn pos i) Symbol (T.singleton stopchar)
360− : totoks (incSourceColumn pos (i + 1)) (T.drop 1 t2) ++ inp
361− return $ Tok pos toktype t1
363−listingsLanguage :: [(Text, Text)] -> Maybe Text
364−listingsLanguage opts =
365− case lookup "language" opts of
367− Just l -> fromListingsLanguage l `mplus` Just l
369−dolstinline :: PandocMonad m => LP m Inlines
371− options <- option [] keyvals
372− let classes = maybeToList $ listingsLanguage options
373− doinlinecode classes
375−domintinline :: PandocMonad m => LP m Inlines
378− cls <- untokenize <$> braced
381−doinlinecode :: PandocMonad m => [Text] -> LP m Inlines
382−doinlinecode classes = do
383− Tok _ Symbol t <- anySymbol
384− marker <- case T.uncons t of
385− Just (c, ts) | T.null ts -> return c
387− let stopchar = if marker == '{' then '}' else marker
389− codeWith ("",classes,[]) . T.map nlToSpace . untokenize <$>
390− manyTill (verbTok stopchar) (symbol stopchar)
392−nlToSpace :: Char -> Char
396−mathDisplay :: Text -> Inlines
397−mathDisplay = displayMath . trimMath
399−mathInline :: Text -> Inlines
400−mathInline = math . trimMath
402−dollarsMath :: PandocMonad m => LP m Inlines
405− display <- option False (True <$ symbol '$')
406− (do contents <- try $ untokenize <$> pDollarsMath 0
408− then mathDisplay contents <$ symbol '$'
409− else return $ mathInline contents)
410− <|> (guard display >> return (mathInline ""))
412−-- Int is number of embedded groupings
413−pDollarsMath :: PandocMonad m => Int -> LP m [Tok]
415− tk@(Tok _ toktype t) <- anyTok
418− , n == 0 -> return []
421− (tk :) . (tk' :) <$> pDollarsMath n
422− | t == "{" -> (tk :) <$> pDollarsMath (n+1)
425− then (tk :) <$> pDollarsMath (n-1)
427− _ -> (tk :) <$> pDollarsMath n
431−addPrefix :: [Inline] -> [Citation] -> [Citation]
432−addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
435−addSuffix :: [Inline] -> [Citation] -> [Citation]
436−addSuffix s ks@(_:_) =
438− in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]
441−simpleCiteArgs :: PandocMonad m => LP m [Citation]
442−simpleCiteArgs = try $ do
443− first <- optionMaybe $ toList <$> opt
444− second <- optionMaybe $ toList <$> opt
445− keys <- try $ bgroup *> manyTill citationLabel egroup
446− let (pre, suf) = case (first , second ) of
447− (Just s , Nothing) -> (mempty, s )
448− (Just s , Just t ) -> (s , t )
449− _ -> (mempty, mempty)
450− conv k = Citation { citationId = k
451− , citationPrefix = []
452− , citationSuffix = []
453− , citationMode = NormalCitation
455− , citationNoteNum = 0
457− return $ addPrefix pre $ addSuffix suf $ map conv keys
459−citationLabel :: PandocMonad m => LP m Text
463− (many1 (satisfyTok isWordTok <|> symbolIn bibtexKeyChar)
465− <* optional (symbol ',')
467− where bibtexKeyChar = ".:;?!`'()/*@_+=-&[]" :: [Char]
469−cites :: PandocMonad m => CitationMode -> Bool -> LP m [Citation]
470−cites mode multi = try $ do
473− multiprenote <- optionMaybe $ toList <$> paropt
474− multipostnote <- optionMaybe $ toList <$> paropt
475− let (pre, suf) = case (multiprenote, multipostnote) of
476− (Just s , Nothing) -> (mempty, s)
477− (Nothing , Just t) -> (mempty, t)
478− (Just s , Just t ) -> (s, t)
479− _ -> (mempty, mempty)
480− tempCits <- many1 simpleCiteArgs
482− (k:ks) -> case ks of
483− (_:_) -> return $ (addMprenote pre k : init ks) ++
484− [addMpostnote suf (last ks)]
485− _ -> return [addMprenote pre (addMpostnote suf k)]
487− else count 1 simpleCiteArgs
488− let cs = concat cits
489− return $ case mode of
490− AuthorInText -> case cs of
491− (c:rest) -> c {citationMode = mode} : rest
493− _ -> map (\a -> a {citationMode = mode}) cs
494− where mprenote (k:ks) = (k:ks) ++ [Space]
496− mpostnote (k:ks) = [Str ",", Space] ++ (k:ks)
497− mpostnote _ = mempty
498− addMprenote mpn (k:ks) =
499− let mpnfinal = case citationPrefix k of
500− (_:_) -> mprenote mpn
502− in addPrefix mpnfinal (k:ks)
503− addMprenote _ _ = []
504− addMpostnote = addSuffix . mpostnote
506−citation :: PandocMonad m => Text -> CitationMode -> Bool -> LP m Inlines
507−citation name mode multi = do
508− (c,raw) <- withRaw $ cites mode multi
509− return $ cite c (rawInline "latex" $ "\\" <> name <> untokenize raw)
511−handleCitationPart :: Inlines -> [Citation]
512−handleCitationPart ils =
513− let isCite Cite{} = True
515− (pref, rest) = break isCite (toList ils)
517− (Cite cs _:suff) -> addPrefix pref $ addSuffix suff cs
520−complexNatbibCitation :: PandocMonad m => CitationMode -> LP m Inlines
521−complexNatbibCitation mode = try $ do
523− withRaw $ concat <$> do
525− items <- mconcat <$>
526− many1 (notFollowedBy (symbol ';') >> inline)
529− return $ map handleCitationPart items
532− (c:cits) -> return $ cite (c{ citationMode = mode }:cits)
533− (rawInline "latex" $ "\\citetext" <> untokenize raw)
535−inNote :: Inlines -> Inlines
537− note $ para $ ils <> str "."
539inlineCommand' :: PandocMonad m => LP m Inlines
299inlineCommand' :: PandocMonad m => LP m Inlines
540inlineCommand' = try $ do
300inlineCommand' = try $ do
541 Tok _ (CtrlSeq name) cmd <- anyControlSeq
301 Tok _ (CtrlSeq name) cmd <- anyControlSeq
542 guard $ name /= "begin" && name /= "end" && name /= "and"
302 guard $ name /= "begin" && name /= "end" && name /= "and"
543− star <- option "" ("*" <$ symbol '*' <* sp)
303+ star <- if T.all isAlphaNum name
304+ then option "" ("*" <$ symbol '*' <* sp)
544 overlay <- option "" overlaySpecification
306 overlay <- option "" overlaySpecification
545 let name' = name <> star <> overlay
307 let name' = name <> star <> overlay
546 let names = ordNub [name', name] -- check non-starred as fallback
308 let names = ordNub [name', name] -- check non-starred as fallback
@@ -551,28 +313,8 @@ inlineCommand' = try $ do
551 <|> ignore rawcommand
313 <|> ignore rawcommand
552 lookupListDefault raw names inlineCommands
314 lookupListDefault raw names inlineCommands
555tok :: PandocMonad m => LP m Inlines
316tok :: PandocMonad m => LP m Inlines
556−tok = try $ spaces >> grouped inline <|> inlineCommand' <|> singleChar'
317+tok = tokWith inline
557− where singleChar' = do
558− Tok _ _ t <- singleChar
561−opt :: PandocMonad m => LP m Inlines
563− toks <- try (sp *> bracketedToks <* sp)
564− -- now parse the toks as inlines
566− parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
568− Right result -> return result
569− Left e -> throwError $ PandocParsecError (untokenize toks) e
571−paropt :: PandocMonad m => LP m Inlines
572−paropt = parenWrapped inline
574−inBrackets :: Inlines -> Inlines
575−inBrackets x = str "[" <> x <> str "]"
577unescapeURL :: Text -> Text
319unescapeURL :: Text -> Text
578unescapeURL = T.concat . go . T.splitOn "\\"
320unescapeURL = T.concat . go . T.splitOn "\\"
@@ -585,379 +327,107 @@ unescapeURL = T.concat . go . T.splitOn "\\"
585 , isEscapable c = t
327 , isEscapable c = t
586 | otherwise = "\\" <> t
328 | otherwise = "\\" <> t
588−mathEnvWith :: PandocMonad m
589− => (Inlines -> a) -> Maybe Text -> Text -> LP m a
590−mathEnvWith f innerEnv name = f . mathDisplay . inner <$> mathEnv name
591− where inner x = case innerEnv of
593− Just y -> "\\begin{" <> y <> "}\n" <> x <>
594− "\\end{" <> y <> "}"
596−mathEnv :: PandocMonad m => Text -> LP m Text
600− res <- manyTill anyTok (end_ name)
601− return $ stripTrailingNewlines $ untokenize res
603−inlineEnvironment :: PandocMonad m => LP m Inlines
604−inlineEnvironment = try $ do
606− name <- untokenize <$> braced
607− M.findWithDefault mzero name inlineEnvironments
609−inlineEnvironments :: PandocMonad m => M.Map Text (LP m Inlines)
610−inlineEnvironments = M.fromList [
611− ("displaymath", mathEnvWith id Nothing "displaymath")
612− , ("math", math <$> mathEnv "math")
613− , ("equation", mathEnvWith id Nothing "equation")
614− , ("equation*", mathEnvWith id Nothing "equation*")
615− , ("gather", mathEnvWith id (Just "gathered") "gather")
616− , ("gather*", mathEnvWith id (Just "gathered") "gather*")
617− , ("multline", mathEnvWith id (Just "gathered") "multline")
618− , ("multline*", mathEnvWith id (Just "gathered") "multline*")
619− , ("eqnarray", mathEnvWith id (Just "aligned") "eqnarray")
620− , ("eqnarray*", mathEnvWith id (Just "aligned") "eqnarray*")
621− , ("align", mathEnvWith id (Just "aligned") "align")
622− , ("align*", mathEnvWith id (Just "aligned") "align*")
623− , ("alignat", mathEnvWith id (Just "aligned") "alignat")
624− , ("alignat*", mathEnvWith id (Just "aligned") "alignat*")
625− , ("dmath", mathEnvWith id Nothing "dmath")
626− , ("dmath*", mathEnvWith id Nothing "dmath*")
627− , ("dgroup", mathEnvWith id (Just "aligned") "dgroup")
628− , ("dgroup*", mathEnvWith id (Just "aligned") "dgroup*")
629− , ("darray", mathEnvWith id (Just "aligned") "darray")
630− , ("darray*", mathEnvWith id (Just "aligned") "darray*")
633inlineCommands :: PandocMonad m => M.Map Text (LP m Inlines)
330inlineCommands :: PandocMonad m => M.Map Text (LP m Inlines)
634−inlineCommands = M.union inlineLanguageCommands $ M.fromList
331+inlineCommands = M.unions
635− [ ("emph", extractSpaces emph <$> tok)
332+ [ accentCommands tok
636− , ("textit", extractSpaces emph <$> tok)
333+ , citationCommands inline
637− , ("textsl", extractSpaces emph <$> tok)
334+ , siunitxCommands tok
638− , ("textsc", extractSpaces smallcaps <$> tok)
335+ , acronymCommands
639− , ("textsf", extractSpaces (spanWith ("",["sans-serif"],[])) <$> tok)
336+ , refCommands
640− , ("textmd", extractSpaces (spanWith ("",["medium"],[])) <$> tok)
337+ , nameCommands
641− , ("textrm", extractSpaces (spanWith ("",["roman"],[])) <$> tok)
338+ , verbCommands
642− , ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)
339+ , charCommands
643− , ("texttt", ttfamily)
340+ , enquoteCommands tok
644− , ("sout", extractSpaces strikeout <$> tok)
341+ , inlineLanguageCommands tok
645− , ("alert", skipopts >> spanWith ("",["alert"],[]) <$> tok) -- beamer
342+ , biblatexInlineCommands tok
646− , ("lq", return (str "‘"))
343+ , rest ]
647− , ("rq", return (str "’"))
344+ where
648− , ("textquoteleft", return (str "‘"))
345+ rest = M.fromList
649− , ("textquoteright", return (str "’"))
346+ [ ("emph", extractSpaces emph <$> tok)
650− , ("textquotedblleft", return (str "“"))
347+ , ("textit", extractSpaces emph <$> tok)
651− , ("textquotedblright", return (str "”"))
348+ , ("textsl", extractSpaces emph <$> tok)
652− , ("textsuperscript", extractSpaces superscript <$> tok)
349+ , ("textsc", extractSpaces smallcaps <$> tok)
653− , ("textsubscript", extractSpaces subscript <$> tok)
350+ , ("textsf", extractSpaces (spanWith ("",["sans-serif"],[])) <$> tok)
654− , ("textbackslash", lit "\\")
351+ , ("textmd", extractSpaces (spanWith ("",["medium"],[])) <$> tok)
655− , ("backslash", lit "\\")
352+ , ("textrm", extractSpaces (spanWith ("",["roman"],[])) <$> tok)
656− , ("slash", lit "/")
353+ , ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)
657− , ("textbf", extractSpaces strong <$> tok)
354+ , ("texttt", ttfamily)
658− , ("textnormal", extractSpaces (spanWith ("",["nodecor"],[])) <$> tok)
355+ , ("sout", extractSpaces strikeout <$> tok)
659− , ("underline", underline <$> tok)
356+ , ("alert", skipopts >> spanWith ("",["alert"],[]) <$> tok) -- beamer
660− , ("ldots", lit "…")
357+ , ("textsuperscript", extractSpaces superscript <$> tok)
661− , ("vdots", lit "\8942")
358+ , ("textsubscript", extractSpaces subscript <$> tok)
662− , ("dots", lit "…")
359+ , ("textbf", extractSpaces strong <$> tok)
663− , ("mdots", lit "…")
360+ , ("textnormal", extractSpaces (spanWith ("",["nodecor"],[])) <$> tok)
664− , ("sim", lit "~")
361+ , ("underline", underline <$> tok)
665− , ("sep", lit ",")
362+ , ("mbox", rawInlineOr "mbox" $ processHBox <$> tok)
666− , ("label", rawInlineOr "label" dolabel)
363+ , ("hbox", rawInlineOr "hbox" $ processHBox <$> tok)
667− , ("ref", rawInlineOr "ref" $ doref "ref")
364+ , ("lettrine", rawInlineOr "lettrine" lettrine)
668− , ("cref", rawInlineOr "cref" $ doref "ref") -- from cleveref.sty
365+ , ("(", mathInline . untokenize <$> manyTill anyTok (controlSeq ")"))
669− , ("vref", rawInlineOr "vref" $ doref "ref+page") -- from varioref.sty
366+ , ("[", mathDisplay . untokenize <$> manyTill anyTok (controlSeq "]"))
670− , ("eqref", rawInlineOr "eqref" $ doref "eqref") -- from amsmath.sty
367+ , ("ensuremath", mathInline . untokenize <$> braced)
671− , ("mbox", rawInlineOr "mbox" $ processHBox <$> tok)
368+ , ("texorpdfstring", const <$> tok <*> tok)
672− , ("hbox", rawInlineOr "hbox" $ processHBox <$> tok)
369+ -- old TeX commands
673− , ("lettrine", rawInlineOr "lettrine" lettrine)
370+ , ("em", extractSpaces emph <$> inlines)
674− , ("(", mathInline . untokenize <$> manyTill anyTok (controlSeq ")"))
371+ , ("it", extractSpaces emph <$> inlines)
675− , ("[", mathDisplay . untokenize <$> manyTill anyTok (controlSeq "]"))
372+ , ("sl", extractSpaces emph <$> inlines)
676− , ("ensuremath", mathInline . untokenize <$> braced)
373+ , ("bf", extractSpaces strong <$> inlines)
677− , ("texorpdfstring", const <$> tok <*> tok)
374+ , ("tt", code . stringify . toList <$> inlines)
678− , ("P", lit "¶")
375+ , ("rm", inlines)
679− , ("S", lit "§")
376+ , ("itshape", extractSpaces emph <$> inlines)
680− , ("$", lit "$")
377+ , ("slshape", extractSpaces emph <$> inlines)
681− , ("%", lit "%")
378+ , ("scshape", extractSpaces smallcaps <$> inlines)
682− , ("&", lit "&")
379+ , ("bfseries", extractSpaces strong <$> inlines)
683− , ("#", lit "#")
380+ , ("MakeUppercase", makeUppercase <$> tok)
684− , ("_", lit "_")
381+ , ("MakeTextUppercase", makeUppercase <$> tok) -- textcase
685− , ("{", lit "{")
382+ , ("uppercase", makeUppercase <$> tok)
686− , ("}", lit "}")
383+ , ("MakeLowercase", makeLowercase <$> tok)
687− , ("qed", lit "\a0\x25FB")
384+ , ("MakeTextLowercase", makeLowercase <$> tok)
688− -- old TeX commands
385+ , ("lowercase", makeLowercase <$> tok)
689− , ("em", extractSpaces emph <$> inlines)
386+ , ("thanks", skipopts >> note <$> grouped block)
690− , ("it", extractSpaces emph <$> inlines)
387+ , ("footnote", skipopts >> note <$> grouped block)
691− , ("sl", extractSpaces emph <$> inlines)
388+ , ("passthrough", tok) -- \passthrough macro used by latex writer
692− , ("bf", extractSpaces strong <$> inlines)
389+ -- for listings
693− , ("tt", code . stringify . toList <$> inlines)
390+ , ("includegraphics", do options <- option [] keyvals
694− , ("rm", inlines)
391+ src <- braced
695− , ("itshape", extractSpaces emph <$> inlines)
392+ mkImage options .
696− , ("slshape", extractSpaces emph <$> inlines)
393+ unescapeURL .
697− , ("scshape", extractSpaces smallcaps <$> inlines)
394+ removeDoubleQuotes $ untokenize src)
698− , ("bfseries", extractSpaces strong <$> inlines)
395+ -- hyperref
699− , ("MakeUppercase", makeUppercase <$> tok)
396+ , ("url", (\url -> link url "" (str url)) . unescapeURL . untokenize <$>
700− , ("MakeTextUppercase", makeUppercase <$> tok) -- textcase
397+ bracedUrl)
701− , ("uppercase", makeUppercase <$> tok)
398+ , ("nolinkurl", code . unescapeURL . untokenize <$> bracedUrl)
702− , ("MakeLowercase", makeLowercase <$> tok)
399+ , ("href", do url <- bracedUrl
703− , ("MakeTextLowercase", makeLowercase <$> tok)
400+ sp
704− , ("lowercase", makeLowercase <$> tok)
401+ link (unescapeURL $ untokenize url) "" <$> tok)
705− , ("/", pure mempty) -- italic correction
402+ , ("hyperlink", hyperlink)
706− , ("aa", lit "å")
403+ , ("hyperref", hyperref)
707− , ("AA", lit "Å")
404+ , ("hypertarget", hypertargetInline)
708− , ("ss", lit "ß")
405+ -- hyphenat
709− , ("o", lit "ø")
406+ , ("nohyphens", tok)
710− , ("O", lit "Ø")
407+ , ("textnhtt", ttfamily)
711− , ("L", lit "Ł")
408+ , ("nhttfamily", ttfamily)
712− , ("l", lit "ł")
409+ -- LaTeX colors
713− , ("ae", lit "æ")
410+ , ("textcolor", coloredInline "color")
714− , ("AE", lit "Æ")
411+ , ("colorbox", coloredInline "background-color")
715− , ("oe", lit "œ")
412+ -- etoolbox
716− , ("OE", lit "Œ")
413+ , ("ifstrequal", ifstrequal)
717− , ("pounds", lit "£")
414+ , ("newtoggle", braced >>= newToggle)
718− , ("euro", lit "€")
415+ , ("toggletrue", braced >>= setToggle True)
719− , ("copyright", lit "©")
416+ , ("togglefalse", braced >>= setToggle False)
720− , ("textasciicircum", lit "^")
417+ , ("iftoggle", try $ ifToggle >> inline)
721− , ("textasciitilde", lit "~")
418+ -- include
722− , ("H", accent '\779' Nothing) -- hungarumlaut
419+ , ("input", rawInlineOr "input" $ include "input")
723− , ("`", accent '\768' (Just '`')) -- grave
420+ -- soul package
724− , ("'", accent '\769' (Just '\'')) -- acute
421+ , ("ul", underline <$> tok)
725− , ("^", accent '\770' (Just '^')) -- circ
422+ -- ulem package
726− , ("~", accent '\771' (Just '~')) -- tilde
423+ , ("uline", underline <$> tok)
727− , ("\"", accent '\776' Nothing) -- umlaut
424+ -- plain tex stuff that should just be passed through as raw tex
728− , (".", accent '\775' Nothing) -- dot
425+ , ("ifdim", ifdim)
729− , ("=", accent '\772' Nothing) -- macron
426+ ]
730− , ("|", accent '\781' Nothing) -- vertical line above
731− , ("b", accent '\817' Nothing) -- macron below
732− , ("c", accent '\807' Nothing) -- cedilla
733− , ("G", accent '\783' Nothing) -- doublegrave
734− , ("h", accent '\777' Nothing) -- hookabove
735− , ("d", accent '\803' Nothing) -- dotbelow
736− , ("f", accent '\785' Nothing) -- inverted breve
737− , ("r", accent '\778' Nothing) -- ringabove
738− , ("t", accent '\865' Nothing) -- double inverted breve
739− , ("U", accent '\782' Nothing) -- double vertical line above
740− , ("v", accent '\780' Nothing) -- hacek
741− , ("u", accent '\774' Nothing) -- breve
742− , ("k", accent '\808' Nothing) -- ogonek
743− , ("textogonekcentered", accent '\808' Nothing) -- ogonek
744− , ("i", lit "ı") -- dotless i
745− , ("j", lit "ȷ") -- dotless j
746− , ("newtie", accent '\785' Nothing) -- inverted breve
747− , ("textcircled", accent '\8413' Nothing) -- combining circle
748− , ("\\", linebreak <$ (do inTableCell <- sInTableCell <$> getState
749− guard $ not inTableCell
752− , (",", lit "\8198")
753− , ("@", pure mempty)
755− , ("ps", pure $ str "PS." <> space)
756− , ("TeX", lit "TeX")
757− , ("LaTeX", lit "LaTeX")
759− , ("textless", lit "<")
760− , ("textgreater", lit ">")
761− , ("thanks", skipopts >> note <$> grouped block)
762− , ("footnote", skipopts >> note <$> grouped block)
763− , ("passthrough", tok) -- \passthrough macro used by latex writer
766− , ("lstinline", dolstinline)
767− , ("mintinline", domintinline)
769− , ("url", (\url -> link url "" (str url)) . unescapeURL . untokenize <$>
771− , ("nolinkurl", code . unescapeURL . untokenize <$> bracedUrl)
772− , ("href", do url <- bracedUrl
774− link (unescapeURL $ untokenize url) "" <$> tok)
775− , ("includegraphics", do options <- option [] keyvals
777− mkImage options . unescapeURL . removeDoubleQuotes $
779− , ("enquote*", enquote True Nothing)
780− , ("enquote", enquote False Nothing)
781− -- foreignquote is supposed to use native quote marks
782− , ("foreignquote*", braced >>= enquote True . Just . untokenize)
783− , ("foreignquote", braced >>= enquote False . Just . untokenize)
784− -- hypehnquote uses regular quotes
785− , ("hyphenquote*", braced >>= enquote True . Just . untokenize)
786− , ("hyphenquote", braced >>= enquote False . Just . untokenize)
787− , ("figurename", doTerm Translations.Figure)
788− , ("prefacename", doTerm Translations.Preface)
789− , ("refname", doTerm Translations.References)
790− , ("bibname", doTerm Translations.Bibliography)
791− , ("chaptername", doTerm Translations.Chapter)
792− , ("partname", doTerm Translations.Part)
793− , ("contentsname", doTerm Translations.Contents)
794− , ("listfigurename", doTerm Translations.ListOfFigures)
795− , ("listtablename", doTerm Translations.ListOfTables)
796− , ("indexname", doTerm Translations.Index)
797− , ("abstractname", doTerm Translations.Abstract)
798− , ("tablename", doTerm Translations.Table)
799− , ("enclname", doTerm Translations.Encl)
800− , ("ccname", doTerm Translations.Cc)
801− , ("headtoname", doTerm Translations.To)
802− , ("pagename", doTerm Translations.Page)
803− , ("seename", doTerm Translations.See)
804− , ("seealsoname", doTerm Translations.SeeAlso)
805− , ("proofname", doTerm Translations.Proof)
806− , ("glossaryname", doTerm Translations.Glossary)
807− , ("lstlistingname", doTerm Translations.Listing)
808− , ("cite", citation "cite" NormalCitation False)
809− , ("Cite", citation "Cite" NormalCitation False)
810− , ("citep", citation "citep" NormalCitation False)
811− , ("citep*", citation "citep*" NormalCitation False)
812− , ("citeal", citation "citeal" NormalCitation False)
813− , ("citealp", citation "citealp" NormalCitation False)
814− , ("citealp*", citation "citealp*" NormalCitation False)
815− , ("autocite", citation "autocite" NormalCitation False)
816− , ("smartcite", citation "smartcite" NormalCitation False)
817− , ("footcite", inNote <$> citation "footcite" NormalCitation False)
818− , ("parencite", citation "parencite" NormalCitation False)
819− , ("supercite", citation "supercite" NormalCitation False)
820− , ("footcitetext", inNote <$> citation "footcitetext" NormalCitation False)
821− , ("citeyearpar", citation "citeyearpar" SuppressAuthor False)
822− , ("citeyear", citation "citeyear" SuppressAuthor False)
823− , ("autocite*", citation "autocite*" SuppressAuthor False)
824− , ("cite*", citation "cite*" SuppressAuthor False)
825− , ("parencite*", citation "parencite*" SuppressAuthor False)
826− , ("textcite", citation "textcite" AuthorInText False)
827− , ("citet", citation "citet" AuthorInText False)
828− , ("citet*", citation "citet*" AuthorInText False)
829− , ("citealt", citation "citealt" AuthorInText False)
830− , ("citealt*", citation "citealt*" AuthorInText False)
831− , ("textcites", citation "textcites" AuthorInText True)
832− , ("cites", citation "cites" NormalCitation True)
833− , ("autocites", citation "autocites" NormalCitation True)
834− , ("footcites", inNote <$> citation "footcites" NormalCitation True)
835− , ("parencites", citation "parencites" NormalCitation True)
836− , ("supercites", citation "supercites" NormalCitation True)
837− , ("footcitetexts", inNote <$> citation "footcitetexts" NormalCitation True)
838− , ("Autocite", citation "Autocite" NormalCitation False)
839− , ("Smartcite", citation "Smartcite" NormalCitation False)
840− , ("Footcite", inNote <$> citation "Footcite" NormalCitation False)
841− , ("Parencite", citation "Parencite" NormalCitation False)
842− , ("Supercite", citation "Supercite" NormalCitation False)
843− , ("Footcitetext", inNote <$> citation "Footcitetext" NormalCitation False)
844− , ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)
845− , ("Citeyear", citation "Citeyear" SuppressAuthor False)
846− , ("Autocite*", citation "Autocite*" SuppressAuthor False)
847− , ("Cite*", citation "Cite*" SuppressAuthor False)
848− , ("Parencite*", citation "Parencite*" SuppressAuthor False)
849− , ("Textcite", citation "Textcite" AuthorInText False)
850− , ("Textcites", citation "Textcites" AuthorInText True)
851− , ("Cites", citation "Cites" NormalCitation True)
852− , ("Autocites", citation "Autocites" NormalCitation True)
853− , ("Footcites", inNote <$> citation "Footcites" NormalCitation True)
854− , ("Parencites", citation "Parencites" NormalCitation True)
855− , ("Supercites", citation "Supercites" NormalCitation True)
856− , ("Footcitetexts", inNote <$> citation "Footcitetexts" NormalCitation True)
857− , ("citetext", complexNatbibCitation NormalCitation)
858− , ("citeauthor", (try (tok *> sp *> controlSeq "citetext") *>
859− complexNatbibCitation AuthorInText)
860− <|> citation "citeauthor" AuthorInText False)
861− , ("nocite", mempty <$ (citation "nocite" NormalCitation False >>=
863− , ("hyperlink", hyperlink)
864− , ("hypertarget", hypertargetInline)
865− -- glossaries package
866− , ("gls", doAcronym "short")
867− , ("Gls", doAcronym "short")
868− , ("glsdesc", doAcronym "long")
869− , ("Glsdesc", doAcronym "long")
870− , ("GLSdesc", doAcronym "long")
871− , ("acrlong", doAcronym "long")
872− , ("Acrlong", doAcronym "long")
873− , ("acrfull", doAcronym "full")
874− , ("Acrfull", doAcronym "full")
875− , ("acrshort", doAcronym "abbrv")
876− , ("Acrshort", doAcronym "abbrv")
877− , ("glspl", doAcronymPlural "short")
878− , ("Glspl", doAcronymPlural "short")
879− , ("glsdescplural", doAcronymPlural "long")
880− , ("Glsdescplural", doAcronymPlural "long")
881− , ("GLSdescplural", doAcronymPlural "long")
883− , ("ac", doAcronym "short")
884− , ("acf", doAcronym "full")
885− , ("acs", doAcronym "abbrv")
886− , ("acl", doAcronym "long")
887− , ("acp", doAcronymPlural "short")
888− , ("acfp", doAcronymPlural "full")
889− , ("acsp", doAcronymPlural "abbrv")
890− , ("aclp", doAcronymPlural "long")
891− , ("Ac", doAcronym "short")
892− , ("Acf", doAcronym "full")
893− , ("Acs", doAcronym "abbrv")
894− , ("Acl", doAcronym "long")
895− , ("Acp", doAcronymPlural "short")
896− , ("Acfp", doAcronymPlural "full")
897− , ("Acsp", doAcronymPlural "abbrv")
898− , ("Aclp", doAcronymPlural "long")
900− , ("si", skipopts *> dosi tok)
902− , ("SIrange", doSIrange True tok)
903− , ("numrange", doSIrange False tok)
904− , ("numlist", doSInumlist)
908− , ("bshyp", lit "\\\173")
909− , ("fshyp", lit "/\173")
910− , ("dothyp", lit ".\173")
911− , ("colonhyp", lit ":\173")
913− , ("nohyphens", tok)
914− , ("textnhtt", ttfamily)
915− , ("nhttfamily", ttfamily)
917− , ("textcolor", coloredInline "color")
918− , ("colorbox", coloredInline "background-color")
920− , ("faCheck", lit "\10003")
921− , ("faClose", lit "\10007")
923− , ("xspace", doxspace)
925− , ("ifstrequal", ifstrequal)
926− , ("newtoggle", braced >>= newToggle)
927− , ("toggletrue", braced >>= setToggle True)
928− , ("togglefalse", braced >>= setToggle False)
929− , ("iftoggle", try $ ifToggle >> inline)
931− , ("RN", romanNumeralUpper)
932− , ("Rn", romanNumeralLower)
934− , ("foreignlanguage", foreignlanguage)
936− , ("input", rawInlineOr "input" $ include "input")
938− , ("ul", underline <$> tok)
940− , ("uline", underline <$> tok)
941− -- plain tex stuff that should just be passed through as raw tex
945−accent :: PandocMonad m => Char -> Maybe Char -> LP m Inlines
946−accent combiningAccent fallBack = try $ do
949− (Str (T.uncons -> Just (x, xs)) : ys) -> return $ fromList $
950− -- try to normalize to the combined character:
951− Str (Normalize.normalize Normalize.NFC
952− (T.pack [x, combiningAccent]) <> xs) : ys
953− [Space] -> return $ str $ T.singleton $ fromMaybe combiningAccent fallBack
954− [] -> return $ str $ T.singleton $ fromMaybe combiningAccent fallBack
958lettrine :: PandocMonad m => LP m Inlines
428lettrine :: PandocMonad m => LP m Inlines
959lettrine = do
429lettrine = do
960− optional opt
430+ optional rawopt
963 return $ extractSpaces (spanWith ("",["lettrine"],[])) x <> smallcaps y
433 return $ extractSpaces (spanWith ("",["lettrine"],[])) x <> smallcaps y
@@ -977,32 +447,18 @@ alterStr :: (Text -> Text) -> Inline -> Inline
977alterStr f (Str xs) = Str (f xs)
447alterStr f (Str xs) = Str (f xs)
978alterStr _ x = x
448alterStr _ x = x
980−foreignlanguage :: PandocMonad m => LP m Inlines
982− babelLang <- untokenize <$> braced
983− case babelLangToBCP47 babelLang of
984− Just lang -> spanWith ("", [], [("lang", renderLang lang)]) <$> tok
987−inlineLanguageCommands :: PandocMonad m => M.Map Text (LP m Inlines)
988−inlineLanguageCommands = M.fromList $ mk <$> M.toList polyglossiaLangToBCP47
990− mk (polyglossia, bcp47Func) =
991− ("text" <> polyglossia, inlineLanguage bcp47Func)
993−inlineLanguage :: PandocMonad m => (Text -> Lang) -> LP m Inlines
994−inlineLanguage bcp47Func = do
995− o <- option "" $ T.filter (\c -> c /= '[' && c /= ']')
997− let lang = renderLang $ bcp47Func o
998− extractSpaces (spanWith ("", [], [("lang", lang)])) <$> tok
1000hyperlink :: PandocMonad m => LP m Inlines
450hyperlink :: PandocMonad m => LP m Inlines
1001hyperlink = try $ do
451hyperlink = try $ do
1002 src <- untokenize <$> braced
452 src <- untokenize <$> braced
1003 lab <- tok
453 lab <- tok
1004 return $ link ("#" <> src) "" lab
454 return $ link ("#" <> src) "" lab
456+hyperref :: PandocMonad m => LP m Inlines
458+ url <- (("#" <>) . untokenize <$> try (sp *> bracketedToks <* sp))
459+ <|> untokenize <$> (bracedUrl <* bracedUrl <* bracedUrl)
1006hypertargetBlock :: PandocMonad m => LP m Blocks
462hypertargetBlock :: PandocMonad m => LP m Blocks
1007hypertargetBlock = try $ do
463hypertargetBlock = try $ do
1008 ref <- untokenize <$> braced
464 ref <- untokenize <$> braced
@@ -1017,31 +473,6 @@ hypertargetInline = try $ do
1017 ils <- grouped inline
473 ils <- grouped inline
1018 return $ spanWith (ref, [], []) ils
474 return $ spanWith (ref, [], []) ils
1020−romanNumeralUpper :: (PandocMonad m) => LP m Inlines
1022− str . toRomanNumeral <$> romanNumeralArg
1024−romanNumeralLower :: (PandocMonad m) => LP m Inlines
1026− str . T.toLower . toRomanNumeral <$> romanNumeralArg
1028−romanNumeralArg :: (PandocMonad m) => LP m Int
1029−romanNumeralArg = spaces *> (parser <|> inBraces)
1039− Tok _ Word s <- satisfyTok isWordTok
1040− let (digits, rest) = T.span isDigit s
1041− unless (T.null rest) $
1042− Prelude.fail "Non-digits in argument to \\Rn or \\RN"
1045newToggle :: (Monoid a, PandocMonad m) => [Tok] -> LP m a
476newToggle :: (Monoid a, PandocMonad m) => [Tok] -> LP m a
1046newToggle name = do
477newToggle name = do
1047 updateState $ \st ->
478 updateState $ \st ->
@@ -1072,9 +503,6 @@ ifToggle = do
1072 report $ UndefinedToggle name' pos
503 report $ UndefinedToggle name' pos
1073 return ()
504 return ()
1075−doTerm :: PandocMonad m => Translations.Term -> LP m Inlines
1076−doTerm term = str <$> translateTerm term
1078ifstrequal :: (PandocMonad m, Monoid a) => LP m a
506ifstrequal :: (PandocMonad m, Monoid a) => LP m a
1079ifstrequal = do
507ifstrequal = do
1080 str1 <- tok
508 str1 <- tok
@@ -1095,13 +523,6 @@ coloredInline stylename = do
1095ttfamily :: PandocMonad m => LP m Inlines
523ttfamily :: PandocMonad m => LP m Inlines
1096ttfamily = code . stringify . toList <$> tok
524ttfamily = code . stringify . toList <$> tok
1098−rawInlineOr :: PandocMonad m => Text -> LP m Inlines -> LP m Inlines
1099−rawInlineOr name' fallback = do
1100− parseRaw <- extensionEnabled Ext_raw_tex <$> getOption readerExtensions
1102− then rawInline "latex" <$> getRawCommand name' ("\\" <> name')
1105processHBox :: Inlines -> Inlines
526processHBox :: Inlines -> Inlines
1106processHBox = walk convert
527processHBox = walk convert
@@ -1152,73 +573,74 @@ treatAsInline = Set.fromList
1152 , "pagebreak"
573 , "pagebreak"
1155−label :: PandocMonad m => LP m ()
1159− updateState $ \st -> st{ sLastLabel = Just $ untokenize t }
1161−dolabel :: PandocMonad m => LP m Inlines
1164− let refstr = untokenize v
1165− updateState $ \st ->
1166− st{ sLastLabel = Just refstr }
1167− return $ spanWith (refstr,[],[("label", refstr)])
1168− $ inBrackets $ str $ untokenize v
1170−doref :: PandocMonad m => Text -> LP m Inlines
1173− let refstr = untokenize v
1174− return $ linkWith ("",[],[ ("reference-type", cls)
1175− , ("reference", refstr)])
1178− (inBrackets $ str refstr)
1180lookupListDefault :: (Ord k) => v -> [k] -> M.Map k v -> v
576lookupListDefault :: (Ord k) => v -> [k] -> M.Map k v -> v
1181lookupListDefault d = (fromMaybe d .) . lookupList
577lookupListDefault d = (fromMaybe d .) . lookupList
1182 where lookupList l m = msum $ map (`M.lookup` m) l
578 where lookupList l m = msum $ map (`M.lookup` m) l
1184inline :: PandocMonad m => LP m Inlines
580inline :: PandocMonad m => LP m Inlines
1185−inline = (mempty <$ comment)
581+inline = do
1186− <|> (space <$ whitespace)
582+ Tok pos toktype t <- lookAhead anyTok
1187− <|> (softbreak <$ endline)
583+ let symbolAsString = str . untoken <$> anySymbol
1188− <|> word
584+ let unescapedSymbolAsString =
1189− <|> macroDef (rawInline "latex")
585+ do s <- untoken <$> anySymbol
1190− <|> inlineCommand'
586+ report $ ParsingUnescaped s pos
1191− <|> inlineEnvironment
587+ return $ str s
1192− <|> inlineGroup
588+ case toktype of
1193− <|> (symbol '-' *>
589+ Comment -> mempty <$ comment
1194− option (str "-") (symbol '-' *>
590+ Spaces -> space <$ whitespace
1195− option (str "–") (str "—" <$ symbol '-')))
591+ Newline -> softbreak <$ endline
1196− <|> doubleQuote
592+ Word -> word
1197− <|> singleQuote
593+ Esc1 -> str . T.singleton <$> primEscape
1198− <|> (str "”" <$ try (symbol '\'' >> symbol '\''))
594+ Esc2 -> str . T.singleton <$> primEscape
1199− <|> (str "”" <$ symbol '”')
595+ Symbol ->
1200− <|> (str "’" <$ symbol '\'')
596+ case t of
1201− <|> (str "’" <$ symbol '’')
597+ "-" -> symbol '-' *>
1202− <|> (str "\160" <$ symbol '~')
598+ option (str "-") (symbol '-' *>
1203− <|> dollarsMath
599+ option (str "–") (str "—" <$ symbol '-'))
1204− <|> (guardEnabled Ext_literate_haskell *> symbol '|' *> doLHSverb)
600+ "'" -> symbol '\'' *>
1205− <|> (str . T.singleton <$> primEscape)
601+ option (str "’") (str "”" <$ symbol '\'')
1206− <|> regularSymbol
602+ "~" -> str "\160" <$ symbol '~'
1207− <|> (do res <- symbolIn "#^'`\"[]&"
603+ "`" -> doubleQuote <|> singleQuote <|> symbolAsString
1208− pos <- getPosition
604+ "\"" -> doubleQuote <|> singleQuote <|> symbolAsString
1209− let s = untoken res
605+ "“" -> doubleQuote <|> symbolAsString
1210− report $ ParsingUnescaped s pos
606+ "‘" -> singleQuote <|> symbolAsString
1211− return $ str s)
607+ "$" -> dollarsMath <|> unescapedSymbolAsString
608+ "|" -> (guardEnabled Ext_literate_haskell *>
609+ symbol '|' *> doLHSverb) <|> symbolAsString
611+ "#" -> unescapedSymbolAsString
612+ "&" -> unescapedSymbolAsString
613+ "_" -> unescapedSymbolAsString
614+ "^" -> unescapedSymbolAsString
618+ CtrlSeq _ -> macroDef (rawInline "latex")
620+ <|> inlineEnvironment
1213inlines :: PandocMonad m => LP m Inlines
624inlines :: PandocMonad m => LP m Inlines
1214inlines = mconcat <$> many inline
625inlines = mconcat <$> many inline
627+opt :: PandocMonad m => LP m Inlines
629+ toks <- try (sp *> bracketedToks <* sp)
630+ -- now parse the toks as inlines
632+ parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
634+ Right result -> return result
635+ Left e -> throwError $ PandocParsecError (toSources toks) e
1216-- block elements:
637-- block elements:
1218preamble :: PandocMonad m => LP m Blocks
639preamble :: PandocMonad m => LP m Blocks
1219preamble = mconcat <$> many preambleBlock
640preamble = mconcat <$> many preambleBlock
1220 where preambleBlock = (mempty <$ spaces1)
641 where preambleBlock = (mempty <$ spaces1)
1221 <|> macroDef (rawBlock "latex")
642 <|> macroDef (rawBlock "latex")
1222 <|> (mempty <$ blockCommand)
644 <|> (mempty <$ blockCommand)
1223 <|> (mempty <$ braced)
645 <|> (mempty <$ braced)
1224 <|> (do notFollowedBy (begin_ "document")
646 <|> (do notFollowedBy (begin_ "document")
@@ -1272,6 +694,16 @@ include name = do
1272 mapM_ (insertIncluded defaultExt) fs
694 mapM_ (insertIncluded defaultExt) fs
1273 return mempty
695 return mempty
697+readFileFromTexinputs :: PandocMonad m => FilePath -> LP m (Maybe Text)
698+readFileFromTexinputs fp = do
699+ fileContentsMap <- sFileContents <$> getState
700+ case M.lookup (T.pack fp) fileContentsMap of
701+ Just t -> return (Just t)
703+ dirs <- map T.unpack . splitTextBy (==':') . fromMaybe "."
704+ <$> lookupEnv "TEXINPUTS"
705+ readFileFromDirs dirs fp
1275insertIncluded :: PandocMonad m
707insertIncluded :: PandocMonad m
1276 => FilePath
708 => FilePath
1277 -> FilePath
709 -> FilePath
@@ -1281,13 +713,12 @@ insertIncluded defaultExtension f' = do
1281 ".tex" -> f'
713 ".tex" -> f'
1282 ".sty" -> f'
714 ".sty" -> f'
1283 _ -> addExtension f' defaultExtension
715 _ -> addExtension f' defaultExtension
1284− dirs <- map T.unpack . splitTextBy (==':') . fromMaybe "." <$> lookupEnv "TEXINPUTS"
1285 pos <- getPosition
716 pos <- getPosition
1286 containers <- getIncludeFiles <$> getState
717 containers <- getIncludeFiles <$> getState
1287 when (T.pack f `elem` containers) $
718 when (T.pack f `elem` containers) $
1288 throwError $ PandocParseError $ T.pack $ "Include file loop at " ++ show pos
719 throwError $ PandocParseError $ T.pack $ "Include file loop at " ++ show pos
1289 updateState $ addIncludeFile $ T.pack f
720 updateState $ addIncludeFile $ T.pack f
1290− mbcontents <- readFileFromDirs dirs f
721+ mbcontents <- readFileFromTexinputs f
1291 contents <- case mbcontents of
722 contents <- case mbcontents of
1292 Just s -> return s
723 Just s -> return s
1293 Nothing -> do
724 Nothing -> do
@@ -1296,10 +727,6 @@ insertIncluded defaultExtension f' = do
1296 getInput >>= setInput . (tokenize f contents ++)
727 getInput >>= setInput . (tokenize f contents ++)
1297 updateState dropLatestIncludeFile
728 updateState dropLatestIncludeFile
1299−addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> LP m ()
1300−addMeta field val = updateState $ \st ->
1301− st{ sMeta = addMetaField field val $ sMeta st }
1303authors :: PandocMonad m => LP m ()
730authors :: PandocMonad m => LP m ()
1304authors = try $ do
731authors = try $ do
@@ -1308,150 +735,6 @@ authors = try $ do
1309 addMeta "author" (map trimInlines auths)
736 addMeta "author" (map trimInlines auths)
1311−macroDef :: (PandocMonad m, Monoid a) => (Text -> a) -> LP m a
1312−macroDef constructor = do
1313− (_, s) <- withRaw (commandDef <|> environmentDef)
1314− (constructor (untokenize s) <$
1315− guardDisabled Ext_latex_macros)
1317− where commandDef = do
1318− (name, macro') <- newcommand <|> letmacro <|> defmacro
1319− guardDisabled Ext_latex_macros <|>
1320− updateState (\s -> s{ sMacros = M.insert name macro' (sMacros s) })
1321− environmentDef = do
1322− mbenv <- newenvironment
1324− Nothing -> return ()
1325− Just (name, macro1, macro2) ->
1326− guardDisabled Ext_latex_macros <|>
1327− do updateState $ \s -> s{ sMacros =
1328− M.insert name macro1 (sMacros s) }
1329− updateState $ \s -> s{ sMacros =
1330− M.insert ("end" <> name) macro2 (sMacros s) }
1331− -- @\newenvironment{envname}[n-args][default]{begin}{end}@
1332− -- is equivalent to
1333− -- @\newcommand{\envname}[n-args][default]{begin}@
1334− -- @\newcommand{\endenvname}@
1336−letmacro :: PandocMonad m => LP m (Text, Macro)
1339− (name, contents) <- withVerbatimMode $ do
1340− Tok _ (CtrlSeq name) _ <- anyControlSeq
1341− optional $ symbol '='
1343− -- we first parse in verbatim mode, and then expand macros,
1344− -- because we don't want \let\foo\bar to turn into
1345− -- \let\foo hello if we have previously \def\bar{hello}
1346− contents <- bracedOrToken
1347− return (name, contents)
1348− contents' <- doMacros' 0 contents
1349− return (name, Macro ExpandWhenDefined [] Nothing contents')
1351−defmacro :: PandocMonad m => LP m (Text, Macro)
1353− -- we use withVerbatimMode, because macros are to be expanded
1354− -- at point of use, not point of definition
1355− withVerbatimMode $ do
1357− Tok _ (CtrlSeq name) _ <- anyControlSeq
1358− argspecs <- many (argspecArg <|> argspecPattern)
1359− contents <- bracedOrToken
1360− return (name, Macro ExpandWhenUsed argspecs Nothing contents)
1362−argspecArg :: PandocMonad m => LP m ArgSpec
1364− Tok _ (Arg i) _ <- satisfyTok isArgTok
1367−argspecPattern :: PandocMonad m => LP m ArgSpec
1369− Pattern <$> many1 (satisfyTok (\(Tok _ toktype' txt) ->
1370− (toktype' == Symbol || toktype' == Word) &&
1371− (txt /= "{" && txt /= "\\" && txt /= "}")))
1373−newcommand :: PandocMonad m => LP m (Text, Macro)
1376− Tok _ (CtrlSeq mtype) _ <- controlSeq "newcommand" <|>
1377− controlSeq "renewcommand" <|>
1378− controlSeq "providecommand" <|>
1379− controlSeq "DeclareMathOperator" <|>
1380− controlSeq "DeclareRobustCommand"
1381− withVerbatimMode $ do
1382− Tok _ (CtrlSeq name) txt <- do
1383− optional (symbol '*')
1385− (symbol '{' *> spaces *> anyControlSeq <* spaces <* symbol '}')
1387− numargs <- option 0 $ try bracketedNum
1388− let argspecs = map ArgNum [1..numargs]
1390− optarg <- option Nothing $ Just <$> try bracketedToks
1392− contents' <- bracedOrToken
1395− "DeclareMathOperator" ->
1396− Tok pos (CtrlSeq "mathop") "\\mathop"
1397− : Tok pos Symbol "{"
1398− : Tok pos (CtrlSeq "mathrm") "\\mathrm"
1399− : Tok pos Symbol "{"
1401− [ Tok pos Symbol "}", Tok pos Symbol "}" ])
1403− macros <- sMacros <$> getState
1404− case M.lookup name macros of
1406− | mtype == "newcommand" -> do
1407− report $ MacroAlreadyDefined txt pos
1408− return (name, macro)
1409− | mtype == "providecommand" -> return (name, macro)
1410− _ -> return (name, Macro ExpandWhenUsed argspecs optarg contents)
1412−newenvironment :: PandocMonad m => LP m (Maybe (Text, Macro, Macro))
1415− Tok _ (CtrlSeq mtype) _ <- controlSeq "newenvironment" <|>
1416− controlSeq "renewenvironment" <|>
1417− controlSeq "provideenvironment"
1418− withVerbatimMode $ do
1419− optional $ symbol '*'
1421− name <- untokenize <$> braced
1423− numargs <- option 0 $ try bracketedNum
1425− optarg <- option Nothing $ Just <$> try bracketedToks
1426− let argspecs = map (\i -> ArgNum i) [1..numargs]
1427− startcontents <- spaces >> bracedOrToken
1428− endcontents <- spaces >> bracedOrToken
1429− macros <- sMacros <$> getState
1430− case M.lookup name macros of
1432− | mtype == "newenvironment" -> do
1433− report $ MacroAlreadyDefined name pos
1435− | mtype == "provideenvironment" ->
1437− _ -> return $ Just (name,
1438− Macro ExpandWhenUsed argspecs optarg startcontents,
1439− Macro ExpandWhenUsed [] Nothing endcontents)
1441−bracketedNum :: PandocMonad m => LP m Int
1443− ds <- untokenize <$> bracketedToks
1444− case safeRead ds of
1448−setCaption :: PandocMonad m => LP m ()
1449−setCaption = try $ do
1452− optional $ try $ spaces *> label
1453− updateState $ \st -> st{ sCaption = Just ils }
1455looseItem :: PandocMonad m => LP m Blocks
738looseItem :: PandocMonad m => LP m Blocks
1456looseItem = do
739looseItem = do
1457 inListItem <- sInListItem <$> getState
740 inListItem <- sInListItem <$> getState
@@ -1465,10 +748,6 @@ epigraph = do
1465 p2 <- grouped block
748 p2 <- grouped block
1466 return $ divWith ("", ["epigraph"], []) (p1 <> p2)
749 return $ divWith ("", ["epigraph"], []) (p1 <> p2)
1468−resetCaption :: PandocMonad m => LP m ()
1469−resetCaption = updateState $ \st -> st{ sCaption = Nothing
1470− , sLastLabel = Nothing }
1472section :: PandocMonad m => Attr -> Int -> LP m Blocks
751section :: PandocMonad m => Attr -> Int -> LP m Blocks
1473section (ident, classes, kvs) lvl = do
752section (ident, classes, kvs) lvl = do
1474 skipopts
753 skipopts
@@ -1561,7 +840,7 @@ blockCommands = M.fromList
1561 , ("address", mempty <$ (skipopts *> tok >>= addMeta "address"))
840 , ("address", mempty <$ (skipopts *> tok >>= addMeta "address"))
1562 , ("signature", mempty <$ (skipopts *> authors))
841 , ("signature", mempty <$ (skipopts *> authors))
1563 , ("date", mempty <$ (skipopts *> tok >>= addMeta "date"))
842 , ("date", mempty <$ (skipopts *> tok >>= addMeta "date"))
1564− , ("newtheorem", newtheorem)
843+ , ("newtheorem", newtheorem inline)
1565 , ("theoremstyle", theoremstyle)
844 , ("theoremstyle", theoremstyle)
1566 -- KOMA-Script metadata commands
845 -- KOMA-Script metadata commands
1567 , ("extratitle", mempty <$ (skipopts *> tok >>= addMeta "extratitle"))
846 , ("extratitle", mempty <$ (skipopts *> tok >>= addMeta "extratitle"))
@@ -1609,7 +888,7 @@ blockCommands = M.fromList
1609 , ("item", looseItem)
888 , ("item", looseItem)
1610 , ("documentclass", skipopts *> braced *> preamble)
889 , ("documentclass", skipopts *> braced *> preamble)
1611 , ("centerline", para . trimInlines <$> (skipopts *> tok))
890 , ("centerline", para . trimInlines <$> (skipopts *> tok))
1612− , ("caption", mempty <$ setCaption)
891+ , ("caption", mempty <$ setCaption inline)
1613 , ("bibliography", mempty <$ (skipopts *> braced >>=
892 , ("bibliography", mempty <$ (skipopts *> braced >>=
1614 addMeta "bibliography" . splitBibs . untokenize))
893 addMeta "bibliography" . splitBibs . untokenize))
1615 , ("addbibresource", mempty <$ (skipopts *> braced >>=
894 , ("addbibresource", mempty <$ (skipopts *> braced >>=
@@ -1647,7 +926,8 @@ blockCommands = M.fromList
1649environments :: PandocMonad m => M.Map Text (LP m Blocks)
928environments :: PandocMonad m => M.Map Text (LP m Blocks)
1650−environments = M.fromList
929+environments = M.union (tableEnvironments blocks inline) $
1651 [ ("document", env "document" blocks <* skipMany anyTok)
931 [ ("document", env "document" blocks <* skipMany anyTok)
1652 , ("abstract", mempty <$ (env "abstract" blocks >>= addMeta "abstract"))
932 , ("abstract", mempty <$ (env "abstract" blocks >>= addMeta "abstract"))
1653 , ("sloppypar", env "sloppypar" blocks)
933 , ("sloppypar", env "sloppypar" blocks)
@@ -1657,13 +937,6 @@ environments = M.fromList
1657 , ("figure", env "figure" $ skipopts *> figure)
937 , ("figure", env "figure" $ skipopts *> figure)
1658 , ("subfigure", env "subfigure" $ skipopts *> tok *> figure)
938 , ("subfigure", env "subfigure" $ skipopts *> tok *> figure)
1659 , ("center", divWith ("", ["center"], []) <$> env "center" blocks)
939 , ("center", divWith ("", ["center"], []) <$> env "center" blocks)
1660− , ("longtable", env "longtable" $
1661− resetCaption *> simpTable "longtable" False >>= addTableCaption)
1662− , ("table", env "table" $
1663− skipopts *> resetCaption *> blocks >>= addTableCaption)
1664− , ("tabular*", env "tabular*" $ simpTable "tabular*" True)
1665− , ("tabularx", env "tabularx" $ simpTable "tabularx" True)
1666− , ("tabular", env "tabular" $ simpTable "tabular" False)
1667 , ("quote", blockQuote <$> env "quote" blocks)
940 , ("quote", blockQuote <$> env "quote" blocks)
1668 , ("quotation", blockQuote <$> env "quotation" blocks)
941 , ("quotation", blockQuote <$> env "quotation" blocks)
1669 , ("verse", blockQuote <$> env "verse" blocks)
942 , ("verse", blockQuote <$> env "verse" blocks)
@@ -1686,7 +959,7 @@ environments = M.fromList
1686 , ("lilypond", rawVerbEnv "lilypond")
959 , ("lilypond", rawVerbEnv "lilypond")
1687 , ("ly", rawVerbEnv "ly")
960 , ("ly", rawVerbEnv "ly")
1688 -- amsthm
961 -- amsthm
1689− , ("proof", proof)
962+ , ("proof", proof blocks opt)
1690 -- etoolbox
963 -- etoolbox
1691 , ("ifstrequal", ifstrequal)
964 , ("ifstrequal", ifstrequal)
1692 , ("newtoggle", braced >>= newToggle)
965 , ("newtoggle", braced >>= newToggle)
@@ -1695,130 +968,29 @@ environments = M.fromList
1695 , ("iftoggle", try $ ifToggle >> block)
968 , ("iftoggle", try $ ifToggle >> block)
1698−theoremstyle :: PandocMonad m => LP m Blocks
971+filecontents :: PandocMonad m => LP m Blocks
1699−theoremstyle = do
972+filecontents = try $ do
1700− stylename <- untokenize <$> braced
973+ controlSeq "begin"
1701− let mbstyle = case stylename of
1702− "plain" -> Just PlainStyle
1703− "definition" -> Just DefinitionStyle
1704− "remark" -> Just RemarkStyle
1707− Nothing -> return ()
1708− Just sty -> updateState $ \s -> s{ sLastTheoremStyle = sty }
1711−newtheorem :: PandocMonad m => LP m Blocks
1713− number <- option True (False <$ symbol '*' <* sp)
1714 name <- untokenize <$> braced
974 name <- untokenize <$> braced
1715− sp
975+ guard $ name == "filecontents" || name == "filecontents*"
1716− series <- option Nothing $ Just . untokenize <$> bracketedToks
976+ skipopts
1717− sp
977+ fp <- untokenize <$> braced
1718− showName <- tok
978+ txt <- verbEnv name
1719− sp
979+ updateState $ \st ->
1720− syncTo <- option Nothing $ Just . untokenize <$> bracketedToks
980+ st{ sFileContents = M.insert fp txt (sFileContents st) }
1721− sty <- sLastTheoremStyle <$> getState
1722− let spec = TheoremSpec { theoremName = showName
1723− , theoremStyle = sty
1724− , theoremSeries = series
1725− , theoremSyncTo = syncTo
1726− , theoremNumber = number
1727− , theoremLastNum = DottedNum [0] }
1728− tmap <- sTheoremMap <$> getState
1729− updateState $ \s -> s{ sTheoremMap =
1730− M.insert name spec tmap }
1731 return mempty
981 return mempty
1733−proof :: PandocMonad m => LP m Blocks
1735− title <- option (B.text "Proof") opt
1736− bs <- env "proof" blocks
1738− B.divWith ("", ["proof"], []) $
1739− addQed $ addTitle (B.emph (title <> ".")) bs
1741−addTitle :: Inlines -> Blocks -> Blocks
1743− case B.toList bs of
1745− -> B.fromList (Para (B.toList ils ++ (Space : xs)) : rest)
1746− _ -> B.para ils <> bs
1748−addQed :: Blocks -> Blocks
1750− case Seq.viewr (B.unMany bs) of
1752− -> B.Many (s Seq.|> Para (ils ++ B.toList qedSign))
1753− _ -> bs <> B.para qedSign
1755− qedSign = B.str "\xa0\x25FB"
1757environment :: PandocMonad m => LP m Blocks
983environment :: PandocMonad m => LP m Blocks
1758environment = try $ do
984environment = try $ do
1759 controlSeq "begin"
985 controlSeq "begin"
1760 name <- untokenize <$> braced
986 name <- untokenize <$> braced
1761 M.findWithDefault mzero name environments <|>
987 M.findWithDefault mzero name environments <|>
1762− theoremEnvironment name <|>
988+ theoremEnvironment blocks opt name <|>
1763 if M.member name (inlineEnvironments
989 if M.member name (inlineEnvironments
1764 :: M.Map Text (LP PandocPure Inlines))
990 :: M.Map Text (LP PandocPure Inlines))
1765 then mzero
991 then mzero
1766 else try (rawEnv name) <|> rawVerbEnv name
992 else try (rawEnv name) <|> rawVerbEnv name
1768−theoremEnvironment :: PandocMonad m => Text -> LP m Blocks
1769−theoremEnvironment name = do
1770− tmap <- sTheoremMap <$> getState
1771− case M.lookup name tmap of
1774− optTitle <- option mempty $ (\x -> space <> "(" <> x <> ")") <$> opt
1775− mblabel <- option Nothing $ Just . untokenize <$>
1776− try (spaces >> controlSeq "label" >> spaces >> braced)
1777− bs <- env name blocks
1779− if theoremNumber tspec
1781− let name' = fromMaybe name $ theoremSeries tspec
1782− num <- getNextNumber
1783− (maybe (DottedNum [0]) theoremLastNum .
1784− M.lookup name' . sTheoremMap)
1785− updateState $ \s ->
1788− (\spec -> spec{ theoremLastNum = num })
1795− updateState $ \s ->
1796− s{ sLabels = M.insert ident
1798− theoremName tspec <> "\160" <>
1799− str (renderDottedNum num)) (sLabels s) }
1800− Nothing -> return ()
1801− return $ space <> B.text (renderDottedNum num)
1803− let titleEmph = case theoremStyle tspec of
1804− PlainStyle -> B.strong
1805− DefinitionStyle -> B.strong
1806− RemarkStyle -> B.emph
1807− let title = titleEmph (theoremName tspec <> number)
1808− <> optTitle <> "." <> space
1809− return $ divWith (fromMaybe "" mblabel, [name], []) $ addTitle title
1810− $ case theoremStyle tspec of
1811− PlainStyle -> walk italicize bs
1814−italicize :: Block -> Block
1815−italicize (Para ils) = Para [Emph ils]
1816−italicize (Plain ils) = Plain [Emph ils]
1819−env :: PandocMonad m => Text -> LP m a -> LP m a
1820−env name p = p <* end_ name
1822rawEnv :: PandocMonad m => Text -> LP m Blocks
994rawEnv :: PandocMonad m => Text -> LP m Blocks
1823rawEnv name = do
995rawEnv name = do
1824 exts <- getOption readerExtensions
996 exts <- getOption readerExtensions
@@ -1826,15 +998,17 @@ rawEnv name = do
1826 rawOptions <- mconcat <$> many rawopt
998 rawOptions <- mconcat <$> many rawopt
1827 let beginCommand = "\\begin{" <> name <> "}" <> rawOptions
999 let beginCommand = "\\begin{" <> name <> "}" <> rawOptions
1828 pos1 <- getPosition
1000 pos1 <- getPosition
1829− (bs, raw) <- withRaw $ env name blocks
1830 if parseRaw
1001 if parseRaw
1831− then return $ rawBlock "latex"
1002+ then do
1003+ (_, raw) <- withRaw $ env name blocks
1004+ return $ rawBlock "latex"
1832 $ beginCommand <> untokenize raw
1005 $ beginCommand <> untokenize raw
1007+ bs <- env name blocks
1834 report $ SkippedContent beginCommand pos1
1008 report $ SkippedContent beginCommand pos1
1835 pos2 <- getPosition
1009 pos2 <- getPosition
1836 report $ SkippedContent ("\\end{" <> name <> "}") pos2
1010 report $ SkippedContent ("\\end{" <> name <> "}") pos2
1837− return bs
1011+ return $ divWith ("",[name],[]) bs
1839rawVerbEnv :: PandocMonad m => Text -> LP m Blocks
1013rawVerbEnv :: PandocMonad m => Text -> LP m Blocks
1840rawVerbEnv name = do
1014rawVerbEnv name = do
@@ -1893,8 +1067,7 @@ inputMinted = do
1893 pos <- getPosition
1067 pos <- getPosition
1894 attr <- mintedAttr
1068 attr <- mintedAttr
1895 f <- T.filter (/='"') . untokenize <$> braced
1069 f <- T.filter (/='"') . untokenize <$> braced
1896− dirs <- map T.unpack . splitTextBy (==':') . fromMaybe "." <$> lookupEnv "TEXINPUTS"
1070+ mbCode <- readFileFromTexinputs (T.unpack f)
1897− mbCode <- readFileFromDirs dirs (T.unpack f)
1898 rawcode <- case mbCode of
1071 rawcode <- case mbCode of
1899 Just s -> return s
1072 Just s -> return s
1900 Nothing -> do
1073 Nothing -> do
@@ -1980,8 +1153,7 @@ inputListing = do
1980 pos <- getPosition
1153 pos <- getPosition
1981 options <- option [] keyvals
1154 options <- option [] keyvals
1982 f <- T.filter (/='"') . untokenize <$> braced
1155 f <- T.filter (/='"') . untokenize <$> braced
1983− dirs <- map T.unpack . splitTextBy (==':') . fromMaybe "." <$> lookupEnv "TEXINPUTS"
1156+ mbCode <- readFileFromTexinputs (T.unpack f)
1984− mbCode <- readFileFromDirs dirs (T.unpack f)
1985 codeLines <- case mbCode of
1157 codeLines <- case mbCode of
1986 Just s -> return $ T.lines s
1158 Just s -> return $ T.lines s
1987 Nothing -> do
1159 Nothing -> do
@@ -1990,7 +1162,8 @@ inputListing = do
1990 let (ident,classes,kvs) = parseListingsOptions options
1162 let (ident,classes,kvs) = parseListingsOptions options
1991 let classes' =
1163 let classes' =
1992 (case listingsLanguage options of
1164 (case listingsLanguage options of
1993− Nothing -> (take 1 (languagesByExtension (T.pack $ takeExtension $ T.unpack f)) <>)
1165+ Nothing -> (take 1 (languagesByExtension defaultSyntaxMap
1166+ (T.pack $ takeExtension $ T.unpack f)) <>)
1994 Just _ -> id) classes
1167 Just _ -> id) classes
1995 let firstline = fromMaybe 1 $ lookup "firstline" options >>= safeRead
1168 let firstline = fromMaybe 1 $ lookup "firstline" options >>= safeRead
1996 let lastline = fromMaybe (length codeLines) $
1169 let lastline = fromMaybe (length codeLines) $
@@ -2056,358 +1229,23 @@ orderedList' = try $ do
2056 bs <- listenv "enumerate" (many item)
1229 bs <- listenv "enumerate" (many item)
2057 return $ orderedListWith (start, style, delim) bs
1230 return $ orderedListWith (start, style, delim) bs
2061−hline :: PandocMonad m => LP m ()
2064− controlSeq "hline" <|>
2066− controlSeq "toprule" <|>
2067− controlSeq "bottomrule" <|>
2068− controlSeq "midrule" <|>
2069− controlSeq "endhead" <|>
2070− controlSeq "endfirsthead"
2075−lbreak :: PandocMonad m => LP m Tok
2076−lbreak = (controlSeq "\\" <|> controlSeq "tabularnewline")
2077− <* skipopts <* spaces
2079−amp :: PandocMonad m => LP m Tok
2082−-- Split a Word into individual Symbols (for parseAligns)
2083−splitWordTok :: PandocMonad m => LP m ()
2087− (Tok spos Word t : rest) ->
2088− setInput $ map (Tok spos Symbol . T.singleton) (T.unpack t) <> rest
2091−parseAligns :: PandocMonad m => LP m [(Alignment, ColWidth, ([Tok], [Tok]))]
2092−parseAligns = try $ do
2093− let maybeBar = skipMany
2094− (try $ sp *> (() <$ symbol '|' <|> () <$ (symbol '@' >> braced)))
2095− let cAlign = AlignCenter <$ symbol 'c'
2096− let lAlign = AlignLeft <$ symbol 'l'
2097− let rAlign = AlignRight <$ symbol 'r'
2098− let parAlign = AlignLeft <$ symbol 'p'
2099− -- aligns from tabularx
2100− let xAlign = AlignLeft <$ symbol 'X'
2101− let mAlign = AlignLeft <$ symbol 'm'
2102− let bAlign = AlignLeft <$ symbol 'b'
2103− let alignChar = splitWordTok *> ( cAlign <|> lAlign <|> rAlign <|> parAlign
2104− <|> xAlign <|> mAlign <|> bAlign )
2105− let alignPrefix = symbol '>' >> braced
2106− let alignSuffix = symbol '<' >> braced
2107− let colWidth = try $ do
2109− ds <- trim . untokenize <$> manyTill anyTok (controlSeq "linewidth")
2112− return $ safeRead ds
2114− pref <- option [] alignPrefix
2117− width <- colWidth <|> option Nothing (do s <- untokenize <$> braced
2119− report $ SkippedContent s pos
2122− suff <- option [] alignSuffix
2123− return (al, width, (pref, suff))
2124− let starAlign = do -- '*{2}{r}' == 'rr', we just expand like a macro
2127− ds <- trim . untokenize <$> braced
2130− case safeRead ds of
2132− getInput >>= setInput . (mconcat (replicate n spec) ++)
2133− Nothing -> Prelude.fail $ "Could not parse " <> T.unpack ds <> " as number"
2137− aligns' <- many $ try $ spaces >> optional starAlign >>
2138− (alignSpec <* maybeBar)
2142− return $ map toSpec aligns'
2144− toColWidth (Just w) | w > 0 = ColWidth w
2145− toColWidth _ = ColWidthDefault
2146− toSpec (x, y, z) = (x, toColWidth y, z)
2148−-- N.B. this parser returns a Row that may have erroneous empty cells
2149−-- in it. See the note above fixTableHead for details.
2150−parseTableRow :: PandocMonad m
2151− => Text -- ^ table environment name
2152− -> [([Tok], [Tok])] -- ^ pref/suffixes
2154−parseTableRow envname prefsufs = do
2155− notFollowedBy (spaces *> end_ envname)
2156− -- add prefixes and suffixes in token stream:
2157− let celltoks (pref, suff) = do
2158− prefpos <- getPosition
2159− contents <- mconcat <$>
2160− many ( snd <$> withRaw (controlSeq "parbox" >> parbox) -- #5711
2162− snd <$> withRaw (inlineEnvironment <|> dollarsMath)
2165− (() <$ amp <|> () <$ lbreak <|> end_ envname)
2168− suffpos <- getPosition
2169− option [] (count 1 amp)
2170− return $ map (setpos prefpos) pref ++ contents ++ map (setpos suffpos) suff
2171− rawcells <- mapM celltoks prefsufs
2172− oldInput <- getInput
2173− cells <- mapM (\ts -> setInput ts >> parseTableCell) rawcells
2176− return $ Row nullAttr cells
2178−parseTableCell :: PandocMonad m => LP m Cell
2181− updateState $ \st -> st{ sInTableCell = True }
2182− cell' <- multicolumnCell
2184− <|> parseSimpleCell
2186− updateState $ \st -> st{ sInTableCell = False }
2190− -- The parsing of empty cells is important in LaTeX, especially when dealing
2191− -- with multirow/multicolumn. See #6603.
2192− parseEmptyCell = spaces $> emptyCell
2194−cellAlignment :: PandocMonad m => LP m Alignment
2195−cellAlignment = skipMany (symbol '|') *> alignment <* skipMany (symbol '|')
2198− c <- untoken <$> singleChar
2203− "*" -> AlignDefault
2206−plainify :: Blocks -> Blocks
2207−plainify bs = case toList bs of
2208− [Para ils] -> plain (fromList ils)
2211−multirowCell :: PandocMonad m => LP m Cell
2212−multirowCell = controlSeq "multirow" >> do
2213− -- Full prototype for \multirow macro is:
2214− -- \multirow[vpos]{nrows}[bigstruts]{width}[vmove]{text}
2215− -- However, everything except `nrows` and `text` make
2216− -- sense in the context of the Pandoc AST
2217− _ <- optional $ symbol '[' *> cellAlignment <* symbol ']' -- vertical position
2218− nrows <- fmap (fromMaybe 1 . safeRead . untokenize) braced
2219− _ <- optional $ symbol '[' *> manyTill anyTok (symbol ']') -- bigstrut-related
2220− _ <- symbol '{' *> manyTill anyTok (symbol '}') -- Cell width
2221− _ <- optional $ symbol '[' *> manyTill anyTok (symbol ']') -- Length used for fine-tuning
2222− content <- symbol '{' *> (plainify <$> blocks) <* symbol '}'
2223− return $ cell AlignDefault (RowSpan nrows) (ColSpan 1) content
2225−multicolumnCell :: PandocMonad m => LP m Cell
2226−multicolumnCell = controlSeq "multicolumn" >> do
2227− span' <- fmap (fromMaybe 1 . safeRead . untokenize) braced
2228− alignment <- symbol '{' *> cellAlignment <* symbol '}'
2230− let singleCell = do
2231− content <- plainify <$> blocks
2232− return $ cell alignment (RowSpan 1) (ColSpan span') content
2234− -- Two possible contents: either a \multirow cell, or content.
2235− -- E.g. \multicol{1}{c}{\multirow{2}{1em}{content}}
2236− -- Note that a \multirow cell can be nested in a \multicolumn,
2237− -- but not the other way around. See #6603
2238− let nestedCell = do
2239− (Cell _ _ (RowSpan rs) _ bs) <- multirowCell
2246− symbol '{' *> (nestedCell <|> singleCell) <* symbol '}'
2248−-- Parse a simple cell, i.e. not multirow/multicol
2249−parseSimpleCell :: PandocMonad m => LP m Cell
2250−parseSimpleCell = simpleCell <$> (plainify <$> blocks)
2252−-- LaTeX tables are stored with empty cells underneath multirow cells
2253−-- denoting the grid spaces taken up by them. More specifically, if a
2254−-- cell spans m rows, then it will overwrite all the cells in the
2255−-- columns it spans for (m-1) rows underneath it, requiring padding
2256−-- cells in these places. These padding cells need to be removed for
2257−-- proper table reading. See #6603.
2259−-- These fixTable functions do not otherwise fix up malformed
2260−-- input tables: that is left to the table builder.
2261−fixTableHead :: TableHead -> TableHead
2262−fixTableHead (TableHead attr rows) = TableHead attr rows'
2264− rows' = fixTableRows rows
2266−fixTableBody :: TableBody -> TableBody
2267−fixTableBody (TableBody attr rhc th tb)
2268− = TableBody attr rhc th' tb'
2270− th' = fixTableRows th
2271− tb' = fixTableRows tb
2273−fixTableRows :: [Row] -> [Row]
2274−fixTableRows = fixTableRows' $ repeat Nothing
2276− fixTableRows' oldHang (Row attr cells : rs)
2277− = let (newHang, cells') = fixTableRow oldHang cells
2278− rs' = fixTableRows' newHang rs
2279− in Row attr cells' : rs'
2280− fixTableRows' _ [] = []
2282−-- The overhang is represented as Just (relative cell dimensions) or
2283−-- Nothing for an empty grid space.
2284−fixTableRow :: [Maybe (ColSpan, RowSpan)] -> [Cell] -> ([Maybe (ColSpan, RowSpan)], [Cell])
2285−fixTableRow oldHang cells
2286− -- If there's overhang, drop cells until their total width meets the
2287− -- width of the occupied grid spaces (or we run out)
2288− | (n, prefHang, restHang) <- splitHang oldHang
2290− = let cells' = dropToWidth getCellW n cells
2291− (restHang', cells'') = fixTableRow restHang cells'
2292− in (prefHang restHang', cells'')
2293− -- Otherwise record the overhang of a pending cell and fix the rest
2295− | c@(Cell _ _ h w _):cells' <- cells
2298− oldHang' = dropToWidth getHangW w' oldHang
2299− (newHang, cells'') = fixTableRow oldHang' cells'
2300− in (toHang w' h' <> newHang, c : cells'')
2304− getCellW (Cell _ _ _ w _) = w
2305− getHangW = maybe 1 fst
2306− getCS (ColSpan n) = n
2309− | r > 1 = [Just (c, r)]
2310− | otherwise = replicate (getCS c) Nothing
2312− -- Take the prefix of the overhang list representing filled grid
2313− -- spaces. Also return the remainder and the length of this prefix.
2314− splitHang = splitHang' 0 id
2316− splitHang' !n l (Just (c, r):xs)
2317− = splitHang' (n + c) (l . (toHang c (r-1) ++)) xs
2318− splitHang' n l xs = (n, l, xs)
2320− -- Drop list items until the total width of the dropped items
2321− -- exceeds the passed width.
2322− dropToWidth _ n l | n < 1 = l
2323− dropToWidth wproj n (c:cs) = dropToWidth wproj (n - wproj c) cs
2324− dropToWidth _ _ [] = []
2326−simpTable :: PandocMonad m => Text -> Bool -> LP m Blocks
2327−simpTable envname hasWidthParameter = try $ do
2328− when hasWidthParameter $ () <$ (spaces >> tok)
2330− colspecs <- parseAligns
2331− let (aligns, widths, prefsufs) = unzip3 colspecs
2332− optional $ controlSeq "caption" *> setCaption
2340− header' <- option [] . try . fmap (:[]) $
2341− parseTableRow envname prefsufs <* lbreak <* many1 hline
2343− rows <- sepEndBy (parseTableRow envname prefsufs)
2344− (lbreak <* optional (skipMany hline))
2346− optional $ controlSeq "caption" *> setCaption
2352− lookAhead $ controlSeq "end" -- make sure we're at end
2353− let th = fixTableHead $ TableHead nullAttr header'
2354− let tbs = [fixTableBody $ TableBody nullAttr 0 [] rows]
2355− let tf = TableFoot nullAttr []
2356− return $ table emptyCaption (zip aligns widths) th tbs tf
2358−addTableCaption :: PandocMonad m => Blocks -> LP m Blocks
2359−addTableCaption = walkM go
2360− where go (Table attr c spec th tb tf) = do
2362− let mblabel = sLastLabel st
2363− capt <- case (sCaption st, mblabel) of
2364− (Just ils, Nothing) -> return $ caption Nothing (plain ils)
2365− (Just ils, Just lab) -> do
2366− num <- getNextNumber sLastTableNum
2368− st{ sLastTableNum = num
2369− , sLabels = M.insert lab
2370− [Str (renderDottedNum num)]
2372− return $ caption Nothing (plain ils) -- add number??
2373− (Nothing, _) -> return c
2374− let attr' = case (attr, mblabel) of
2375− ((_,classes,kvs), Just ident) ->
2376− (ident,classes,kvs)
2378− return $ addAttrDiv attr' $ Table nullAttr capt spec th tb tf
2381−-- TODO: For now we add a Div to contain table attributes, since
2382−-- most writers don't do anything yet with attributes on Table.
2383−-- This can be removed when that changes.
2384−addAttrDiv :: Attr -> Block -> Block
2385−addAttrDiv ("",[],[]) b = b
2386−addAttrDiv attr b = Div attr [b]
2388block :: PandocMonad m => LP m Blocks
1232block :: PandocMonad m => LP m Blocks
2389block = do
1233block = do
2390− res <- (mempty <$ spaces1)
1234+ Tok _ toktype _ <- lookAhead anyTok
2391− <|> environment
1235+ res <- (case toktype of
2392− <|> macroDef (rawBlock "latex")
1236+ Newline -> mempty <$ spaces1
2393− <|> blockCommand
1237+ Spaces -> mempty <$ spaces1
2394− <|> paragraph
1238+ Comment -> mempty <$ spaces1
2395− <|> grouped block
1239+ Word -> paragraph
1240+ CtrlSeq "begin" -> environment
1241+ CtrlSeq _ -> macroDef (rawBlock "latex")
2396 trace (T.take 60 $ tshow $ B.toList res)
1246 trace (T.take 60 $ tshow $ B.toList res)
2397 return res
1247 return res
2399blocks :: PandocMonad m => LP m Blocks
1249blocks :: PandocMonad m => LP m Blocks
2400blocks = mconcat <$> many block
1250blocks = mconcat <$> many block
2402−setDefaultLanguage :: PandocMonad m => LP m Blocks
2403−setDefaultLanguage = do
2404− o <- option "" $ T.filter (\c -> c /= '[' && c /= ']')
2406− polylang <- untokenize <$> braced
2407− case M.lookup polylang polyglossiaLangToBCP47 of
2408− Nothing -> return mempty -- TODO mzero? warning?
2409− Just langFunc -> do
2412− updateState $ setMeta "lang" $ str (renderLang l)