@@ -1,6 +1,3 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
41{-# LANGUAGE OverloadedStrings #-}
52{-# LANGUAGE PatternGuards #-}
63{-# LANGUAGE ScopedTypeVariables #-}
@@ -21,50 +18,58 @@ module Text.Pandoc.Readers.LaTeX ( readLaTeX,
2118 applyMacros,
2219 rawLaTeXInline,
2320 rawLaTeXBlock,
24− inlineCommand,
25− tokenize,
26− untokenize
21+ inlineCommand
2722 ) where
2823
2924import Control.Applicative (many, optional, (<|>))
3025import Control.Monad
3126import Control.Monad.Except (throwError)
32−import Data.Char (isDigit, isLetter, toUpper, chr)
27+import Data.Char (isDigit, isLetter, isAlphaNum, toUpper, chr)
3328import Data.Default
3429import Data.List (intercalate)
3530import qualified Data.Map as M
3631import Data.Maybe (fromMaybe, maybeToList)
3732import qualified Data.Set as Set
38−import qualified Data.Sequence as Seq
3933import Data.Text (Text)
4034import qualified Data.Text as T
35+import Skylighting (defaultSyntaxMap)
4136import System.FilePath (addExtension, replaceExtension, takeExtension)
42−import Text.Pandoc.BCP47 (Lang (..), renderLang)
43−import Text.Pandoc.Builder
37+import Text.Collate.Lang (renderLang)
38+import Text.Pandoc.Builder as B
4439import Text.Pandoc.Class.PandocPure (PandocPure)
4540import Text.Pandoc.Class.PandocMonad (PandocMonad (..), getResourcePath,
46− readFileFromDirs, report, setResourcePath,
47− setTranslations, translateTerm)
41+ readFileFromDirs, report,
42+ setResourcePath)
4843import Text.Pandoc.Error (PandocError (PandocParseError, PandocParsecError))
49−import Text.Pandoc.Highlighting (fromListingsLanguage, languagesByExtension)
44+import Text.Pandoc.Highlighting (languagesByExtension)
5045import Text.Pandoc.ImageSize (numUnit, showFl)
5146import Text.Pandoc.Logging
5247import Text.Pandoc.Options
5348import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
5449 optional, space, spaces, withRaw, (<|>))
55−import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
56− ArgSpec (..), Tok (..), TokType (..))
50+import Text.Pandoc.Readers.LaTeX.Types (Tok (..), TokType (..))
5751import Text.Pandoc.Readers.LaTeX.Parsing
58−import Text.Pandoc.Readers.LaTeX.Accent (accentCommands)
52+import Text.Pandoc.Readers.LaTeX.Citation (citationCommands, cites)
53+import Text.Pandoc.Readers.LaTeX.Math (dollarsMath, inlineEnvironments,
54+ inlineEnvironment,
55+ mathDisplay, mathInline,
56+ newtheorem, theoremstyle, proof,
57+ theoremEnvironment)
5958import Text.Pandoc.Readers.LaTeX.Table (tableEnvironments)
60−import Text.Pandoc.Readers.LaTeX.Lang (polyglossiaLangToBCP47,
61− babelLangToBCP47)
62−import Text.Pandoc.Readers.LaTeX.SIunitx
59+import Text.Pandoc.Readers.LaTeX.Macro (macroDef)
60+import Text.Pandoc.Readers.LaTeX.Lang (inlineLanguageCommands,
61+ enquoteCommands,
62+ babelLangToBCP47, setDefaultLanguage)
63+import Text.Pandoc.Readers.LaTeX.SIunitx (siunitxCommands)
64+import Text.Pandoc.Readers.LaTeX.Inline (acronymCommands, refCommands,
65+ nameCommands, charCommands,
66+ accentCommands,
67+ biblatexInlineCommands,
68+ verbCommands, rawInlineOr,
69+ listingsLanguage)
6370import Text.Pandoc.Shared
64−import qualified Text.Pandoc.Translations as Translations
6571import Text.Pandoc.Walk
66−import qualified Text.Pandoc.Builder as B
67−import Safe
72+import Data.List.NonEmpty (nonEmpty)
6873
6974-- for debugging:
7075-- import Text.Pandoc.Extensions (getDefaultExtensions)
@@ -72,16 +77,17 @@ import Safe
7277-- import Debug.Trace (traceShowId)
7378
7479-- | Parse LaTeX from string and return 'Pandoc' document.
75−readLaTeX :: PandocMonad m
80+readLaTeX :: (PandocMonad m, ToSources a)
7681 => ReaderOptions -- ^ Reader options
77− -> Text -- ^ String to parse (assumes @'\n'@ line endings)
82+ -> a -- ^ Input to parse
7883 -> m Pandoc
7984readLaTeX opts ltx = do
85+ let sources = toSources ltx
8086 parsed <- runParserT parseLaTeX def{ sOptions = opts } "source"
81− (tokenize "source" (crFilter ltx))
87+ (tokenizeSources sources)
8288 case parsed of
8389 Right result -> return result
84− Left e -> throwError $ PandocParsecError ltx e
90+ Left e -> throwError $ PandocParsecError sources e
8591
8692parseLaTeX :: PandocMonad m => LP m Pandoc
8793parseLaTeX = do
@@ -92,11 +98,7 @@ parseLaTeX = do
9298 let doc' = doc bs
9399 let headerLevel (Header n _ _) = [n]
94100 headerLevel _ = []
95−#if MIN_VERSION_safe(0,3,18)
96− let bottomLevel = minimumBound 1 $ query headerLevel doc'
97−#else
98− let bottomLevel = minimumDef 1 $ query headerLevel doc'
99−#endif
101+ let bottomLevel = maybe 1 minimum $ nonEmpty $ query headerLevel doc'
100102 let adjustHeaders m (Header n attr ils) = Header (n+m) attr ils
101103 adjustHeaders _ x = x
102104 let (Pandoc _ bs') =
@@ -131,11 +133,11 @@ resolveRefs _ x = x
131133
132134
133135rawLaTeXBlock :: (PandocMonad m, HasMacros s, HasReaderOptions s)
134− => ParserT Text s m Text
136+ => ParserT Sources s m Text
135137rawLaTeXBlock = do
136138 lookAhead (try (char '\\' >> letter))
137139 inp <- getInput
138− let toks = tokenize "source" inp
140+ let toks = tokenizeSources inp
139141 snd <$> (rawLaTeXParser toks False (macroDef (const mempty)) blocks
140142 <|> rawLaTeXParser toks True
141143 (do choice (map controlSeq
@@ -162,14 +164,14 @@ beginOrEndCommand = try $ do
162164 (txt <> untokenize rawargs)
163165
164166rawLaTeXInline :: (PandocMonad m, HasMacros s, HasReaderOptions s)
165− => ParserT Text s m Text
167+ => ParserT Sources s m Text
166168rawLaTeXInline = do
167169 lookAhead (try (char '\\' >> letter))
168170 inp <- getInput
169− let toks = tokenize "source" inp
171+ let toks = tokenizeSources inp
170172 raw <- snd <$>
171173 ( rawLaTeXParser toks True
172− (mempty <$ (controlSeq "input" >> skipMany opt >> braced))
174+ (mempty <$ (controlSeq "input" >> skipMany rawopt >> braced))
173175 inlines
174176 <|> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
175177 inlines
@@ -177,11 +179,11 @@ rawLaTeXInline = do
177179 finalbraces <- mconcat <$> many (try (string "{}")) -- see #5439
178180 return $ raw <> T.pack finalbraces
179181
180−inlineCommand :: PandocMonad m => ParserT Text ParserState m Inlines
182+inlineCommand :: PandocMonad m => ParserT Sources ParserState m Inlines
181183inlineCommand = do
182184 lookAhead (try (char '\\' >> letter))
183185 inp <- getInput
184− let toks = tokenize "source" inp
186+ let toks = tokenizeSources inp
185187 fst <$> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
186188 inlines
187189
@@ -190,12 +192,6 @@ inlineCommand = do
190192word :: PandocMonad m => LP m Inlines
191193word = str . untoken <$> satisfyTok isWordTok
192194
193−regularSymbol :: PandocMonad m => LP m Inlines
194−regularSymbol = str . untoken <$> satisfyTok isRegularSymbol
195− where isRegularSymbol (Tok _ Symbol t) = not $ T.any isSpecial t
196− isRegularSymbol _ = False
197− isSpecial c = c `Set.member` specialChars
198−
199195inlineGroup :: PandocMonad m => LP m Inlines
200196inlineGroup = do
201197 ils <- grouped inline
@@ -236,16 +232,6 @@ mkImage options (T.unpack -> src) = do
236232 _ -> return src
237233 return $ imageWith attr (T.pack src') "" alt
238234
239−doxspace :: PandocMonad m => LP m Inlines
240−doxspace =
241− (space <$ lookAhead (satisfyTok startsWithLetter)) <|> return mempty
242− where startsWithLetter (Tok _ Word t) =
243− case T.uncons t of
244− Just (c, _) | isLetter c -> True
245− _ -> False
246− startsWithLetter _ = False
247−
248−
249235removeDoubleQuotes :: Text -> Text
250236removeDoubleQuotes t =
251237 Data.Maybe.fromMaybe t $ T.stripPrefix "\"" t >>= T.stripSuffix "\""
@@ -295,23 +281,11 @@ quoted' f starter ender = do
295281lit :: Text -> LP m Inlines
296282lit = pure . str
297283
298−enquote :: PandocMonad m => Bool -> Maybe Text -> LP m Inlines
299−enquote starred mblang = do
300− skipopts
301− let lang = mblang >>= babelLangToBCP47
302− let langspan = case lang of
303− Nothing -> id
304− Just l -> spanWith ("",[],[("lang", renderLang l)])
305− quoteContext <- sQuoteContext <$> getState
306− if starred || quoteContext == InDoubleQuote
307− then singleQuoted . langspan <$> withQuoteContext InSingleQuote tok
308− else doubleQuoted . langspan <$> withQuoteContext InDoubleQuote tok
309−
310284blockquote :: PandocMonad m => Bool -> Maybe Text -> LP m Blocks
311285blockquote cvariant mblang = do
312286 citepar <- if cvariant
313287 then (\xs -> para (cite xs mempty))
314− <$> cites NormalCitation False
288+ <$> cites inline NormalCitation False
315289 else option mempty $ para <$> bracketed inline
316290 let lang = mblang >>= babelLangToBCP47
317291 let langdiv = case lang of
@@ -322,224 +296,13 @@ blockquote cvariant mblang = do
322296 optional $ symbolIn (".:;?!" :: [Char]) -- currently ignored
323297 return $ blockQuote . langdiv $ (bs <> citepar)
324298
325−doAcronym :: PandocMonad m => Text -> LP m Inlines
326−doAcronym form = do
327− acro <- braced
328− return . mconcat $ [spanWith ("",[],[("acronym-label", untokenize acro),
329− ("acronym-form", "singular+" <> form)])
330− $ str $ untokenize acro]
331−
332−doAcronymPlural :: PandocMonad m => Text -> LP m Inlines
333−doAcronymPlural form = do
334− acro <- braced
335− plural <- lit "s"
336− return . mconcat $ [spanWith ("",[],[("acronym-label", untokenize acro),
337− ("acronym-form", "plural+" <> form)]) $
338− mconcat [str $ untokenize acro, plural]]
339−
340−doverb :: PandocMonad m => LP m Inlines
341−doverb = do
342− Tok _ Symbol t <- anySymbol
343− marker <- case T.uncons t of
344− Just (c, ts) | T.null ts -> return c
345− _ -> mzero
346− withVerbatimMode $
347− code . untokenize <$>
348− manyTill (notFollowedBy newlineTok >> verbTok marker) (symbol marker)
349−
350−verbTok :: PandocMonad m => Char -> LP m Tok
351−verbTok stopchar = do
352− t@(Tok pos toktype txt) <- anyTok
353− case T.findIndex (== stopchar) txt of
354− Nothing -> return t
355− Just i -> do
356− let (t1, t2) = T.splitAt i txt
357− inp <- getInput
358− setInput $ Tok (incSourceColumn pos i) Symbol (T.singleton stopchar)
359− : totoks (incSourceColumn pos (i + 1)) (T.drop 1 t2) ++ inp
360− return $ Tok pos toktype t1
361−
362−listingsLanguage :: [(Text, Text)] -> Maybe Text
363−listingsLanguage opts =
364− case lookup "language" opts of
365− Nothing -> Nothing
366− Just l -> fromListingsLanguage l `mplus` Just l
367−
368−dolstinline :: PandocMonad m => LP m Inlines
369−dolstinline = do
370− options <- option [] keyvals
371− let classes = maybeToList $ listingsLanguage options
372− doinlinecode classes
373−
374−domintinline :: PandocMonad m => LP m Inlines
375−domintinline = do
376− skipopts
377− cls <- untokenize <$> braced
378− doinlinecode [cls]
379−
380−doinlinecode :: PandocMonad m => [Text] -> LP m Inlines
381−doinlinecode classes = do
382− Tok _ Symbol t <- anySymbol
383− marker <- case T.uncons t of
384− Just (c, ts) | T.null ts -> return c
385− _ -> mzero
386− let stopchar = if marker == '{' then '}' else marker
387− withVerbatimMode $
388− codeWith ("",classes,[]) . T.map nlToSpace . untokenize <$>
389− manyTill (verbTok stopchar) (symbol stopchar)
390−
391−nlToSpace :: Char -> Char
392−nlToSpace '\n' = ' '
393−nlToSpace x = x
394−
395−mathDisplay :: Text -> Inlines
396−mathDisplay = displayMath . trimMath
397−
398−mathInline :: Text -> Inlines
399−mathInline = math . trimMath
400−
401−dollarsMath :: PandocMonad m => LP m Inlines
402−dollarsMath = do
403− symbol '$'
404− display <- option False (True <$ symbol '$')
405− (do contents <- try $ untokenize <$> pDollarsMath 0
406− if display
407− then mathDisplay contents <$ symbol '$'
408− else return $ mathInline contents)
409− <|> (guard display >> return (mathInline ""))
410−
411−-- Int is number of embedded groupings
412−pDollarsMath :: PandocMonad m => Int -> LP m [Tok]
413−pDollarsMath n = do
414− tk@(Tok _ toktype t) <- anyTok
415− case toktype of
416− Symbol | t == "$"
417− , n == 0 -> return []
418− | t == "\\" -> do
419− tk' <- anyTok
420− (tk :) . (tk' :) <$> pDollarsMath n
421− | t == "{" -> (tk :) <$> pDollarsMath (n+1)
422− | t == "}" ->
423− if n > 0
424− then (tk :) <$> pDollarsMath (n-1)
425− else mzero
426− _ -> (tk :) <$> pDollarsMath n
427−
428−-- citations
429−
430−addPrefix :: [Inline] -> [Citation] -> [Citation]
431−addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
432−addPrefix _ _ = []
433−
434−addSuffix :: [Inline] -> [Citation] -> [Citation]
435−addSuffix s ks@(_:_) =
436− let k = last ks
437− in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]
438−addSuffix _ _ = []
439−
440−simpleCiteArgs :: PandocMonad m => LP m [Citation]
441−simpleCiteArgs = try $ do
442− first <- optionMaybe $ toList <$> opt
443− second <- optionMaybe $ toList <$> opt
444− keys <- try $ bgroup *> manyTill citationLabel egroup
445− let (pre, suf) = case (first , second ) of
446− (Just s , Nothing) -> (mempty, s )
447− (Just s , Just t ) -> (s , t )
448− _ -> (mempty, mempty)
449− conv k = Citation { citationId = k
450− , citationPrefix = []
451− , citationSuffix = []
452− , citationMode = NormalCitation
453− , citationHash = 0
454− , citationNoteNum = 0
455− }
456− return $ addPrefix pre $ addSuffix suf $ map conv keys
457−
458−citationLabel :: PandocMonad m => LP m Text
459−citationLabel = do
460− sp
461− untokenize <$>
462− (many1 (satisfyTok isWordTok <|> symbolIn bibtexKeyChar)
463− <* sp
464− <* optional (symbol ',')
465− <* sp)
466− where bibtexKeyChar = ".:;?!`'()/*@_+=-&[]" :: [Char]
467−
468−cites :: PandocMonad m => CitationMode -> Bool -> LP m [Citation]
469−cites mode multi = try $ do
470− cits <- if multi
471− then do
472− multiprenote <- optionMaybe $ toList <$> paropt
473− multipostnote <- optionMaybe $ toList <$> paropt
474− let (pre, suf) = case (multiprenote, multipostnote) of
475− (Just s , Nothing) -> (mempty, s)
476− (Nothing , Just t) -> (mempty, t)
477− (Just s , Just t ) -> (s, t)
478− _ -> (mempty, mempty)
479− tempCits <- many1 simpleCiteArgs
480− case tempCits of
481− (k:ks) -> case ks of
482− (_:_) -> return $ (addMprenote pre k : init ks) ++
483− [addMpostnote suf (last ks)]
484− _ -> return [addMprenote pre (addMpostnote suf k)]
485− _ -> return [[]]
486− else count 1 simpleCiteArgs
487− let cs = concat cits
488− return $ case mode of
489− AuthorInText -> case cs of
490− (c:rest) -> c {citationMode = mode} : rest
491− [] -> []
492− _ -> map (\a -> a {citationMode = mode}) cs
493− where mprenote (k:ks) = (k:ks) ++ [Space]
494− mprenote _ = mempty
495− mpostnote (k:ks) = [Str ",", Space] ++ (k:ks)
496− mpostnote _ = mempty
497− addMprenote mpn (k:ks) =
498− let mpnfinal = case citationPrefix k of
499− (_:_) -> mprenote mpn
500− _ -> mpn
501− in addPrefix mpnfinal (k:ks)
502− addMprenote _ _ = []
503− addMpostnote = addSuffix . mpostnote
504−
505−citation :: PandocMonad m => Text -> CitationMode -> Bool -> LP m Inlines
506−citation name mode multi = do
507− (c,raw) <- withRaw $ cites mode multi
508− return $ cite c (rawInline "latex" $ "\\" <> name <> untokenize raw)
509−
510−handleCitationPart :: Inlines -> [Citation]
511−handleCitationPart ils =
512− let isCite Cite{} = True
513− isCite _ = False
514− (pref, rest) = break isCite (toList ils)
515− in case rest of
516− (Cite cs _:suff) -> addPrefix pref $ addSuffix suff cs
517− _ -> []
518−
519−complexNatbibCitation :: PandocMonad m => CitationMode -> LP m Inlines
520−complexNatbibCitation mode = try $ do
521− (cs, raw) <-
522− withRaw $ concat <$> do
523− bgroup
524− items <- mconcat <$>
525− many1 (notFollowedBy (symbol ';') >> inline)
526− `sepBy1` symbol ';'
527− egroup
528− return $ map handleCitationPart items
529− case cs of
530− [] -> mzero
531− (c:cits) -> return $ cite (c{ citationMode = mode }:cits)
532− (rawInline "latex" $ "\\citetext" <> untokenize raw)
533−
534−inNote :: Inlines -> Inlines
535−inNote ils =
536− note $ para $ ils <> str "."
537−
538299inlineCommand' :: PandocMonad m => LP m Inlines
539300inlineCommand' = try $ do
540301 Tok _ (CtrlSeq name) cmd <- anyControlSeq
541302 guard $ name /= "begin" && name /= "end" && name /= "and"
542− star <- option "" ("*" <$ symbol '*' <* sp)
303+ star <- if T.all isAlphaNum name
304+ then option "" ("*" <$ symbol '*' <* sp)
305+ else pure ""
543306 overlay <- option "" overlaySpecification
544307 let name' = name <> star <> overlay
545308 let names = ordNub [name', name] -- check non-starred as fallback
@@ -553,22 +316,6 @@ inlineCommand' = try $ do
553316tok :: PandocMonad m => LP m Inlines
554317tok = tokWith inline
555318
556−opt :: PandocMonad m => LP m Inlines
557−opt = do
558− toks <- try (sp *> bracketedToks <* sp)
559− -- now parse the toks as inlines
560− st <- getState
561− parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
562− case parsed of
563− Right result -> return result
564− Left e -> throwError $ PandocParsecError (untokenize toks) e
565−
566−paropt :: PandocMonad m => LP m Inlines
567−paropt = parenWrapped inline
568−
569−inBrackets :: Inlines -> Inlines
570−inBrackets x = str "[" <> x <> str "]"
571−
572319unescapeURL :: Text -> Text
573320unescapeURL = T.concat . go . T.splitOn "\\"
574321 where
@@ -580,345 +327,107 @@ unescapeURL = T.concat . go . T.splitOn "\\"
580327 , isEscapable c = t
581328 | otherwise = "\\" <> t
582329
583−mathEnvWith :: PandocMonad m
584− => (Inlines -> a) -> Maybe Text -> Text -> LP m a
585−mathEnvWith f innerEnv name = f . mathDisplay . inner <$> mathEnv name
586− where inner x = case innerEnv of
587− Nothing -> x
588− Just y -> "\\begin{" <> y <> "}\n" <> x <>
589− "\\end{" <> y <> "}"
590−
591−mathEnv :: PandocMonad m => Text -> LP m Text
592−mathEnv name = do
593− skipopts
594− optional blankline
595− res <- manyTill anyTok (end_ name)
596− return $ stripTrailingNewlines $ untokenize res
597−
598−inlineEnvironment :: PandocMonad m => LP m Inlines
599−inlineEnvironment = try $ do
600− controlSeq "begin"
601− name <- untokenize <$> braced
602− M.findWithDefault mzero name inlineEnvironments
603−
604−inlineEnvironments :: PandocMonad m => M.Map Text (LP m Inlines)
605−inlineEnvironments = M.fromList [
606− ("displaymath", mathEnvWith id Nothing "displaymath")
607− , ("math", math <$> mathEnv "math")
608− , ("equation", mathEnvWith id Nothing "equation")
609− , ("equation*", mathEnvWith id Nothing "equation*")
610− , ("gather", mathEnvWith id (Just "gathered") "gather")
611− , ("gather*", mathEnvWith id (Just "gathered") "gather*")
612− , ("multline", mathEnvWith id (Just "gathered") "multline")
613− , ("multline*", mathEnvWith id (Just "gathered") "multline*")
614− , ("eqnarray", mathEnvWith id (Just "aligned") "eqnarray")
615− , ("eqnarray*", mathEnvWith id (Just "aligned") "eqnarray*")
616− , ("align", mathEnvWith id (Just "aligned") "align")
617− , ("align*", mathEnvWith id (Just "aligned") "align*")
618− , ("alignat", mathEnvWith id (Just "aligned") "alignat")
619− , ("alignat*", mathEnvWith id (Just "aligned") "alignat*")
620− , ("dmath", mathEnvWith id Nothing "dmath")
621− , ("dmath*", mathEnvWith id Nothing "dmath*")
622− , ("dgroup", mathEnvWith id (Just "aligned") "dgroup")
623− , ("dgroup*", mathEnvWith id (Just "aligned") "dgroup*")
624− , ("darray", mathEnvWith id (Just "aligned") "darray")
625− , ("darray*", mathEnvWith id (Just "aligned") "darray*")
626− ]
627−
628330inlineCommands :: PandocMonad m => M.Map Text (LP m Inlines)
629−inlineCommands =
630− M.union inlineLanguageCommands $
631− M.union (accentCommands tok) $
632− M.fromList
633− [ ("emph", extractSpaces emph <$> tok)
634− , ("textit", extractSpaces emph <$> tok)
635− , ("textsl", extractSpaces emph <$> tok)
636− , ("textsc", extractSpaces smallcaps <$> tok)
637− , ("textsf", extractSpaces (spanWith ("",["sans-serif"],[])) <$> tok)
638− , ("textmd", extractSpaces (spanWith ("",["medium"],[])) <$> tok)
639− , ("textrm", extractSpaces (spanWith ("",["roman"],[])) <$> tok)
640− , ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)
641− , ("texttt", ttfamily)
642− , ("sout", extractSpaces strikeout <$> tok)
643− , ("alert", skipopts >> spanWith ("",["alert"],[]) <$> tok) -- beamer
644− , ("lq", return (str "‘"))
645− , ("rq", return (str "’"))
646− , ("textquoteleft", return (str "‘"))
647− , ("textquoteright", return (str "’"))
648− , ("textquotedblleft", return (str "“"))
649− , ("textquotedblright", return (str "”"))
650− , ("textsuperscript", extractSpaces superscript <$> tok)
651− , ("textsubscript", extractSpaces subscript <$> tok)
652− , ("textbackslash", lit "\\")
653− , ("backslash", lit "\\")
654− , ("slash", lit "/")
655− , ("textbf", extractSpaces strong <$> tok)
656− , ("textnormal", extractSpaces (spanWith ("",["nodecor"],[])) <$> tok)
657− , ("underline", underline <$> tok)
658− , ("ldots", lit "…")
659− , ("vdots", lit "\8942")
660− , ("dots", lit "…")
661− , ("mdots", lit "…")
662− , ("sim", lit "~")
663− , ("sep", lit ",")
664− , ("label", rawInlineOr "label" dolabel)
665− , ("ref", rawInlineOr "ref" $ doref "ref")
666− , ("cref", rawInlineOr "cref" $ doref "ref") -- from cleveref.sty
667− , ("vref", rawInlineOr "vref" $ doref "ref+page") -- from varioref.sty
668− , ("eqref", rawInlineOr "eqref" $ doref "eqref") -- from amsmath.sty
669− , ("mbox", rawInlineOr "mbox" $ processHBox <$> tok)
670− , ("hbox", rawInlineOr "hbox" $ processHBox <$> tok)
671− , ("lettrine", rawInlineOr "lettrine" lettrine)
672− , ("(", mathInline . untokenize <$> manyTill anyTok (controlSeq ")"))
673− , ("[", mathDisplay . untokenize <$> manyTill anyTok (controlSeq "]"))
674− , ("ensuremath", mathInline . untokenize <$> braced)
675− , ("texorpdfstring", const <$> tok <*> tok)
676− , ("P", lit "¶")
677− , ("S", lit "§")
678− , ("$", lit "$")
679− , ("%", lit "%")
680− , ("&", lit "&")
681− , ("#", lit "#")
682− , ("_", lit "_")
683− , ("{", lit "{")
684− , ("}", lit "}")
685− , ("qed", lit "\a0\x25FB")
686− -- old TeX commands
687− , ("em", extractSpaces emph <$> inlines)
688− , ("it", extractSpaces emph <$> inlines)
689− , ("sl", extractSpaces emph <$> inlines)
690− , ("bf", extractSpaces strong <$> inlines)
691− , ("tt", code . stringify . toList <$> inlines)
692− , ("rm", inlines)
693− , ("itshape", extractSpaces emph <$> inlines)
694− , ("slshape", extractSpaces emph <$> inlines)
695− , ("scshape", extractSpaces smallcaps <$> inlines)
696− , ("bfseries", extractSpaces strong <$> inlines)
697− , ("MakeUppercase", makeUppercase <$> tok)
698− , ("MakeTextUppercase", makeUppercase <$> tok) -- textcase
699− , ("uppercase", makeUppercase <$> tok)
700− , ("MakeLowercase", makeLowercase <$> tok)
701− , ("MakeTextLowercase", makeLowercase <$> tok)
702− , ("lowercase", makeLowercase <$> tok)
703− , ("/", pure mempty) -- italic correction
704− , ("\\", linebreak <$ (do inTableCell <- sInTableCell <$> getState
705− guard $ not inTableCell
706− optional opt
707− spaces))
708− , (",", lit "\8198")
709− , ("@", pure mempty)
710− , (" ", lit "\160")
711− , ("ps", pure $ str "PS." <> space)
712− , ("TeX", lit "TeX")
713− , ("LaTeX", lit "LaTeX")
714− , ("bar", lit "|")
715− , ("textless", lit "<")
716− , ("textgreater", lit ">")
717− , ("thanks", skipopts >> note <$> grouped block)
718− , ("footnote", skipopts >> note <$> grouped block)
719− , ("passthrough", tok) -- \passthrough macro used by latex writer
720− -- for listings
721− , ("verb", doverb)
722− , ("lstinline", dolstinline)
723− , ("mintinline", domintinline)
724− , ("Verb", doverb)
725− , ("url", (\url -> link url "" (str url)) . unescapeURL . untokenize <$>
726− bracedUrl)
727− , ("nolinkurl", code . unescapeURL . untokenize <$> bracedUrl)
728− , ("href", do url <- bracedUrl
729− sp
730− link (unescapeURL $ untokenize url) "" <$> tok)
731− , ("includegraphics", do options <- option [] keyvals
732− src <- braced
733− mkImage options . unescapeURL . removeDoubleQuotes $
734− untokenize src)
735− , ("enquote*", enquote True Nothing)
736− , ("enquote", enquote False Nothing)
737− -- foreignquote is supposed to use native quote marks
738− , ("foreignquote*", braced >>= enquote True . Just . untokenize)
739− , ("foreignquote", braced >>= enquote False . Just . untokenize)
740− -- hypehnquote uses regular quotes
741− , ("hyphenquote*", braced >>= enquote True . Just . untokenize)
742− , ("hyphenquote", braced >>= enquote False . Just . untokenize)
743− , ("figurename", doTerm Translations.Figure)
744− , ("prefacename", doTerm Translations.Preface)
745− , ("refname", doTerm Translations.References)
746− , ("bibname", doTerm Translations.Bibliography)
747− , ("chaptername", doTerm Translations.Chapter)
748− , ("partname", doTerm Translations.Part)
749− , ("contentsname", doTerm Translations.Contents)
750− , ("listfigurename", doTerm Translations.ListOfFigures)
751− , ("listtablename", doTerm Translations.ListOfTables)
752− , ("indexname", doTerm Translations.Index)
753− , ("abstractname", doTerm Translations.Abstract)
754− , ("tablename", doTerm Translations.Table)
755− , ("enclname", doTerm Translations.Encl)
756− , ("ccname", doTerm Translations.Cc)
757− , ("headtoname", doTerm Translations.To)
758− , ("pagename", doTerm Translations.Page)
759− , ("seename", doTerm Translations.See)
760− , ("seealsoname", doTerm Translations.SeeAlso)
761− , ("proofname", doTerm Translations.Proof)
762− , ("glossaryname", doTerm Translations.Glossary)
763− , ("lstlistingname", doTerm Translations.Listing)
764− , ("cite", citation "cite" NormalCitation False)
765− , ("Cite", citation "Cite" NormalCitation False)
766− , ("citep", citation "citep" NormalCitation False)
767− , ("citep*", citation "citep*" NormalCitation False)
768− , ("citeal", citation "citeal" NormalCitation False)
769− , ("citealp", citation "citealp" NormalCitation False)
770− , ("citealp*", citation "citealp*" NormalCitation False)
771− , ("autocite", citation "autocite" NormalCitation False)
772− , ("smartcite", citation "smartcite" NormalCitation False)
773− , ("footcite", inNote <$> citation "footcite" NormalCitation False)
774− , ("parencite", citation "parencite" NormalCitation False)
775− , ("supercite", citation "supercite" NormalCitation False)
776− , ("footcitetext", inNote <$> citation "footcitetext" NormalCitation False)
777− , ("citeyearpar", citation "citeyearpar" SuppressAuthor False)
778− , ("citeyear", citation "citeyear" SuppressAuthor False)
779− , ("autocite*", citation "autocite*" SuppressAuthor False)
780− , ("cite*", citation "cite*" SuppressAuthor False)
781− , ("parencite*", citation "parencite*" SuppressAuthor False)
782− , ("textcite", citation "textcite" AuthorInText False)
783− , ("citet", citation "citet" AuthorInText False)
784− , ("citet*", citation "citet*" AuthorInText False)
785− , ("citealt", citation "citealt" AuthorInText False)
786− , ("citealt*", citation "citealt*" AuthorInText False)
787− , ("textcites", citation "textcites" AuthorInText True)
788− , ("cites", citation "cites" NormalCitation True)
789− , ("autocites", citation "autocites" NormalCitation True)
790− , ("footcites", inNote <$> citation "footcites" NormalCitation True)
791− , ("parencites", citation "parencites" NormalCitation True)
792− , ("supercites", citation "supercites" NormalCitation True)
793− , ("footcitetexts", inNote <$> citation "footcitetexts" NormalCitation True)
794− , ("Autocite", citation "Autocite" NormalCitation False)
795− , ("Smartcite", citation "Smartcite" NormalCitation False)
796− , ("Footcite", inNote <$> citation "Footcite" NormalCitation False)
797− , ("Parencite", citation "Parencite" NormalCitation False)
798− , ("Supercite", citation "Supercite" NormalCitation False)
799− , ("Footcitetext", inNote <$> citation "Footcitetext" NormalCitation False)
800− , ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)
801− , ("Citeyear", citation "Citeyear" SuppressAuthor False)
802− , ("Autocite*", citation "Autocite*" SuppressAuthor False)
803− , ("Cite*", citation "Cite*" SuppressAuthor False)
804− , ("Parencite*", citation "Parencite*" SuppressAuthor False)
805− , ("Textcite", citation "Textcite" AuthorInText False)
806− , ("Textcites", citation "Textcites" AuthorInText True)
807− , ("Cites", citation "Cites" NormalCitation True)
808− , ("Autocites", citation "Autocites" NormalCitation True)
809− , ("Footcites", inNote <$> citation "Footcites" NormalCitation True)
810− , ("Parencites", citation "Parencites" NormalCitation True)
811− , ("Supercites", citation "Supercites" NormalCitation True)
812− , ("Footcitetexts", inNote <$> citation "Footcitetexts" NormalCitation True)
813− , ("citetext", complexNatbibCitation NormalCitation)
814− , ("citeauthor", (try (tok *> sp *> controlSeq "citetext") *>
815− complexNatbibCitation AuthorInText)
816− <|> citation "citeauthor" AuthorInText False)
817− , ("nocite", mempty <$ (citation "nocite" NormalCitation False >>=
818− addMeta "nocite"))
819− , ("hyperlink", hyperlink)
820− , ("hypertarget", hypertargetInline)
821− -- glossaries package
822− , ("gls", doAcronym "short")
823− , ("Gls", doAcronym "short")
824− , ("glsdesc", doAcronym "long")
825− , ("Glsdesc", doAcronym "long")
826− , ("GLSdesc", doAcronym "long")
827− , ("acrlong", doAcronym "long")
828− , ("Acrlong", doAcronym "long")
829− , ("acrfull", doAcronym "full")
830− , ("Acrfull", doAcronym "full")
831− , ("acrshort", doAcronym "abbrv")
832− , ("Acrshort", doAcronym "abbrv")
833− , ("glspl", doAcronymPlural "short")
834− , ("Glspl", doAcronymPlural "short")
835− , ("glsdescplural", doAcronymPlural "long")
836− , ("Glsdescplural", doAcronymPlural "long")
837− , ("GLSdescplural", doAcronymPlural "long")
838− -- acronyms package
839− , ("ac", doAcronym "short")
840− , ("acf", doAcronym "full")
841− , ("acs", doAcronym "abbrv")
842− , ("acl", doAcronym "long")
843− , ("acp", doAcronymPlural "short")
844− , ("acfp", doAcronymPlural "full")
845− , ("acsp", doAcronymPlural "abbrv")
846− , ("aclp", doAcronymPlural "long")
847− , ("Ac", doAcronym "short")
848− , ("Acf", doAcronym "full")
849− , ("Acs", doAcronym "abbrv")
850− , ("Acl", doAcronym "long")
851− , ("Acp", doAcronymPlural "short")
852− , ("Acfp", doAcronymPlural "full")
853− , ("Acsp", doAcronymPlural "abbrv")
854− , ("Aclp", doAcronymPlural "long")
855− -- siuntix
856− , ("si", skipopts *> dosi tok)
857− , ("SI", doSI tok)
858− , ("SIrange", doSIrange True tok)
859− , ("numrange", doSIrange False tok)
860− , ("numlist", doSInumlist)
861− , ("num", doSInum)
862− , ("ang", doSIang)
863− -- hyphenat
864− , ("bshyp", lit "\\\173")
865− , ("fshyp", lit "/\173")
866− , ("dothyp", lit ".\173")
867− , ("colonhyp", lit ":\173")
868− , ("hyp", lit "-")
869− , ("nohyphens", tok)
870− , ("textnhtt", ttfamily)
871− , ("nhttfamily", ttfamily)
872− -- LaTeX colors
873− , ("textcolor", coloredInline "color")
874− , ("colorbox", coloredInline "background-color")
875− -- fontawesome
876− , ("faCheck", lit "\10003")
877− , ("faClose", lit "\10007")
878− -- xspace
879− , ("xspace", doxspace)
880− -- etoolbox
881− , ("ifstrequal", ifstrequal)
882− , ("newtoggle", braced >>= newToggle)
883− , ("toggletrue", braced >>= setToggle True)
884− , ("togglefalse", braced >>= setToggle False)
885− , ("iftoggle", try $ ifToggle >> inline)
886− -- biblatex misc
887− , ("RN", romanNumeralUpper)
888− , ("Rn", romanNumeralLower)
889− -- babel
890− , ("foreignlanguage", foreignlanguage)
891− -- include
892− , ("input", rawInlineOr "input" $ include "input")
893− -- soul package
894− , ("ul", underline <$> tok)
895− -- ulem package
896− , ("uline", underline <$> tok)
897− -- plain tex stuff that should just be passed through as raw tex
898− , ("ifdim", ifdim)
899− -- bibtex
900− , ("mkbibquote", spanWith nullAttr . doubleQuoted <$> tok)
901− , ("mkbibemph", spanWith nullAttr . emph <$> tok)
902− , ("mkbibitalic", spanWith nullAttr . emph <$> tok)
903− , ("mkbibbold", spanWith nullAttr . strong <$> tok)
904− , ("mkbibparens",
905− spanWith nullAttr . (\x -> str "(" <> x <> str ")") <$> tok)
906− , ("mkbibbrackets",
907− spanWith nullAttr . (\x -> str "[" <> x <> str "]") <$> tok)
908− , ("autocap", spanWith nullAttr <$> tok)
909− , ("textnormal", spanWith ("",["nodecor"],[]) <$> tok)
910− , ("bibstring",
911− (\x -> spanWith ("",[],[("bibstring",x)]) (str x)) . untokenize
912− <$> braced)
913− , ("adddot", pure (str "."))
914− , ("adddotspace", pure (spanWith nullAttr (str "." <> space)))
915− , ("addabbrvspace", pure space)
916− , ("hyphen", pure (str "-"))
917− ]
331+inlineCommands = M.unions
332+ [ accentCommands tok
333+ , citationCommands inline
334+ , siunitxCommands tok
335+ , acronymCommands
336+ , refCommands
337+ , nameCommands
338+ , verbCommands
339+ , charCommands
340+ , enquoteCommands tok
341+ , inlineLanguageCommands tok
342+ , biblatexInlineCommands tok
343+ , rest ]
344+ where
345+ rest = M.fromList
346+ [ ("emph", extractSpaces emph <$> tok)
347+ , ("textit", extractSpaces emph <$> tok)
348+ , ("textsl", extractSpaces emph <$> tok)
349+ , ("textsc", extractSpaces smallcaps <$> tok)
350+ , ("textsf", extractSpaces (spanWith ("",["sans-serif"],[])) <$> tok)
351+ , ("textmd", extractSpaces (spanWith ("",["medium"],[])) <$> tok)
352+ , ("textrm", extractSpaces (spanWith ("",["roman"],[])) <$> tok)
353+ , ("textup", extractSpaces (spanWith ("",["upright"],[])) <$> tok)
354+ , ("texttt", ttfamily)
355+ , ("sout", extractSpaces strikeout <$> tok)
356+ , ("alert", skipopts >> spanWith ("",["alert"],[]) <$> tok) -- beamer
357+ , ("textsuperscript", extractSpaces superscript <$> tok)
358+ , ("textsubscript", extractSpaces subscript <$> tok)
359+ , ("textbf", extractSpaces strong <$> tok)
360+ , ("textnormal", extractSpaces (spanWith ("",["nodecor"],[])) <$> tok)
361+ , ("underline", underline <$> tok)
362+ , ("mbox", rawInlineOr "mbox" $ processHBox <$> tok)
363+ , ("hbox", rawInlineOr "hbox" $ processHBox <$> tok)
364+ , ("lettrine", rawInlineOr "lettrine" lettrine)
365+ , ("(", mathInline . untokenize <$> manyTill anyTok (controlSeq ")"))
366+ , ("[", mathDisplay . untokenize <$> manyTill anyTok (controlSeq "]"))
367+ , ("ensuremath", mathInline . untokenize <$> braced)
368+ , ("texorpdfstring", const <$> tok <*> tok)
369+ -- old TeX commands
370+ , ("em", extractSpaces emph <$> inlines)
371+ , ("it", extractSpaces emph <$> inlines)
372+ , ("sl", extractSpaces emph <$> inlines)
373+ , ("bf", extractSpaces strong <$> inlines)
374+ , ("tt", code . stringify . toList <$> inlines)
375+ , ("rm", inlines)
376+ , ("itshape", extractSpaces emph <$> inlines)
377+ , ("slshape", extractSpaces emph <$> inlines)
378+ , ("scshape", extractSpaces smallcaps <$> inlines)
379+ , ("bfseries", extractSpaces strong <$> inlines)
380+ , ("MakeUppercase", makeUppercase <$> tok)
381+ , ("MakeTextUppercase", makeUppercase <$> tok) -- textcase
382+ , ("uppercase", makeUppercase <$> tok)
383+ , ("MakeLowercase", makeLowercase <$> tok)
384+ , ("MakeTextLowercase", makeLowercase <$> tok)
385+ , ("lowercase", makeLowercase <$> tok)
386+ , ("thanks", skipopts >> note <$> grouped block)
387+ , ("footnote", skipopts >> note <$> grouped block)
388+ , ("passthrough", tok) -- \passthrough macro used by latex writer
389+ -- for listings
390+ , ("includegraphics", do options <- option [] keyvals
391+ src <- braced
392+ mkImage options .
393+ unescapeURL .
394+ removeDoubleQuotes $ untokenize src)
395+ -- hyperref
396+ , ("url", (\url -> link url "" (str url)) . unescapeURL . untokenize <$>
397+ bracedUrl)
398+ , ("nolinkurl", code . unescapeURL . untokenize <$> bracedUrl)
399+ , ("href", do url <- bracedUrl
400+ sp
401+ link (unescapeURL $ untokenize url) "" <$> tok)
402+ , ("hyperlink", hyperlink)
403+ , ("hyperref", hyperref)
404+ , ("hypertarget", hypertargetInline)
405+ -- hyphenat
406+ , ("nohyphens", tok)
407+ , ("textnhtt", ttfamily)
408+ , ("nhttfamily", ttfamily)
409+ -- LaTeX colors
410+ , ("textcolor", coloredInline "color")
411+ , ("colorbox", coloredInline "background-color")
412+ -- etoolbox
413+ , ("ifstrequal", ifstrequal)
414+ , ("newtoggle", braced >>= newToggle)
415+ , ("toggletrue", braced >>= setToggle True)
416+ , ("togglefalse", braced >>= setToggle False)
417+ , ("iftoggle", try $ ifToggle >> inline)
418+ -- include
419+ , ("input", rawInlineOr "input" $ include "input")
420+ -- soul package
421+ , ("ul", underline <$> tok)
422+ -- ulem package
423+ , ("uline", underline <$> tok)
424+ -- plain tex stuff that should just be passed through as raw tex
425+ , ("ifdim", ifdim)
426+ ]
918427
919428lettrine :: PandocMonad m => LP m Inlines
920429lettrine = do
921− optional opt
430+ optional rawopt
922431 x <- tok
923432 y <- tok
924433 return $ extractSpaces (spanWith ("",["lettrine"],[])) x <> smallcaps y
@@ -938,32 +447,18 @@ alterStr :: (Text -> Text) -> Inline -> Inline
938447alterStr f (Str xs) = Str (f xs)
939448alterStr _ x = x
940449
941−foreignlanguage :: PandocMonad m => LP m Inlines
942−foreignlanguage = do
943− babelLang <- untokenize <$> braced
944− case babelLangToBCP47 babelLang of
945− Just lang -> spanWith ("", [], [("lang", renderLang lang)]) <$> tok
946− _ -> tok
947−
948−inlineLanguageCommands :: PandocMonad m => M.Map Text (LP m Inlines)
949−inlineLanguageCommands = M.fromList $ mk <$> M.toList polyglossiaLangToBCP47
950− where
951− mk (polyglossia, bcp47Func) =
952− ("text" <> polyglossia, inlineLanguage bcp47Func)
953−
954−inlineLanguage :: PandocMonad m => (Text -> Lang) -> LP m Inlines
955−inlineLanguage bcp47Func = do
956− o <- option "" $ T.filter (\c -> c /= '[' && c /= ']')
957− <$> rawopt
958− let lang = renderLang $ bcp47Func o
959− extractSpaces (spanWith ("", [], [("lang", lang)])) <$> tok
960−
961450hyperlink :: PandocMonad m => LP m Inlines
962451hyperlink = try $ do
963452 src <- untokenize <$> braced
964453 lab <- tok
965454 return $ link ("#" <> src) "" lab
966455
456+hyperref :: PandocMonad m => LP m Inlines
457+hyperref = try $ do
458+ url <- (("#" <>) . untokenize <$> try (sp *> bracketedToks <* sp))
459+ <|> untokenize <$> (bracedUrl <* bracedUrl <* bracedUrl)
460+ link url "" <$> tok
461+
967462hypertargetBlock :: PandocMonad m => LP m Blocks
968463hypertargetBlock = try $ do
969464 ref <- untokenize <$> braced
@@ -978,31 +473,6 @@ hypertargetInline = try $ do
978473 ils <- grouped inline
979474 return $ spanWith (ref, [], []) ils
980475
981−romanNumeralUpper :: (PandocMonad m) => LP m Inlines
982−romanNumeralUpper =
983− str . toRomanNumeral <$> romanNumeralArg
984−
985−romanNumeralLower :: (PandocMonad m) => LP m Inlines
986−romanNumeralLower =
987− str . T.toLower . toRomanNumeral <$> romanNumeralArg
988−
989−romanNumeralArg :: (PandocMonad m) => LP m Int
990−romanNumeralArg = spaces *> (parser <|> inBraces)
991− where
992− inBraces = do
993− symbol '{'
994− spaces
995− res <- parser
996− spaces
997− symbol '}'
998− return res
999− parser = do
1000− s <- untokenize <$> many1 (satisfyTok isWordTok)
1001− let (digits, rest) = T.span isDigit s
1002− unless (T.null rest) $
1003− Prelude.fail "Non-digits in argument to \\Rn or \\RN"
1004− safeRead digits
1005−
1006476newToggle :: (Monoid a, PandocMonad m) => [Tok] -> LP m a
1007477newToggle name = do
1008478 updateState $ \st ->
@@ -1033,9 +503,6 @@ ifToggle = do
1033503 report $ UndefinedToggle name' pos
1034504 return ()
1035505
1036−doTerm :: PandocMonad m => Translations.Term -> LP m Inlines
1037−doTerm term = str <$> translateTerm term
1038−
1039506ifstrequal :: (PandocMonad m, Monoid a) => LP m a
1040507ifstrequal = do
1041508 str1 <- tok
@@ -1056,13 +523,6 @@ coloredInline stylename = do
1056523ttfamily :: PandocMonad m => LP m Inlines
1057524ttfamily = code . stringify . toList <$> tok
1058525
1059−rawInlineOr :: PandocMonad m => Text -> LP m Inlines -> LP m Inlines
1060−rawInlineOr name' fallback = do
1061− parseRaw <- extensionEnabled Ext_raw_tex <$> getOption readerExtensions
1062− if parseRaw
1063− then rawInline "latex" <$> getRawCommand name' ("\\" <> name')
1064− else fallback
1065−
1066526processHBox :: Inlines -> Inlines
1067527processHBox = walk convert
1068528 where
@@ -1113,61 +573,67 @@ treatAsInline = Set.fromList
1113573 , "pagebreak"
1114574 ]
1115575
1116−dolabel :: PandocMonad m => LP m Inlines
1117−dolabel = do
1118− v <- braced
1119− let refstr = untokenize v
1120− updateState $ \st ->
1121− st{ sLastLabel = Just refstr }
1122− return $ spanWith (refstr,[],[("label", refstr)])
1123− $ inBrackets $ str $ untokenize v
1124−
1125−doref :: PandocMonad m => Text -> LP m Inlines
1126−doref cls = do
1127− v <- braced
1128− let refstr = untokenize v
1129− return $ linkWith ("",[],[ ("reference-type", cls)
1130− , ("reference", refstr)])
1131− ("#" <> refstr)
1132− ""
1133− (inBrackets $ str refstr)
1134−
1135576lookupListDefault :: (Ord k) => v -> [k] -> M.Map k v -> v
1136577lookupListDefault d = (fromMaybe d .) . lookupList
1137578 where lookupList l m = msum $ map (`M.lookup` m) l
1138579
1139580inline :: PandocMonad m => LP m Inlines
1140−inline = (mempty <$ comment)
1141− <|> (space <$ whitespace)
1142− <|> (softbreak <$ endline)
1143− <|> word
1144− <|> macroDef (rawInline "latex")
1145− <|> inlineCommand'
1146− <|> inlineEnvironment
1147− <|> inlineGroup
1148− <|> (symbol '-' *>
1149− option (str "-") (symbol '-' *>
1150− option (str "–") (str "—" <$ symbol '-')))
1151− <|> doubleQuote
1152− <|> singleQuote
1153− <|> (str "”" <$ try (symbol '\'' >> symbol '\''))
1154− <|> (str "”" <$ symbol '”')
1155− <|> (str "’" <$ symbol '\'')
1156− <|> (str "’" <$ symbol '’')
1157− <|> (str "\160" <$ symbol '~')
1158− <|> dollarsMath
1159− <|> (guardEnabled Ext_literate_haskell *> symbol '|' *> doLHSverb)
1160− <|> (str . T.singleton <$> primEscape)
1161− <|> regularSymbol
1162− <|> (do res <- symbolIn "#^'`\"[]&"
1163− pos <- getPosition
1164− let s = untoken res
1165− report $ ParsingUnescaped s pos
1166− return $ str s)
581+inline = do
582+ Tok pos toktype t <- lookAhead anyTok
583+ let symbolAsString = str . untoken <$> anySymbol
584+ let unescapedSymbolAsString =
585+ do s <- untoken <$> anySymbol
586+ report $ ParsingUnescaped s pos
587+ return $ str s
588+ case toktype of
589+ Comment -> mempty <$ comment
590+ Spaces -> space <$ whitespace
591+ Newline -> softbreak <$ endline
592+ Word -> word
593+ Esc1 -> str . T.singleton <$> primEscape
594+ Esc2 -> str . T.singleton <$> primEscape
595+ Symbol ->
596+ case t of
597+ "-" -> symbol '-' *>
598+ option (str "-") (symbol '-' *>
599+ option (str "–") (str "—" <$ symbol '-'))
600+ "'" -> symbol '\'' *>
601+ option (str "’") (str "”" <$ symbol '\'')
602+ "~" -> str "\160" <$ symbol '~'
603+ "`" -> doubleQuote <|> singleQuote <|> symbolAsString
604+ "\"" -> doubleQuote <|> singleQuote <|> symbolAsString
605+ "“" -> doubleQuote <|> symbolAsString
606+ "‘" -> singleQuote <|> symbolAsString
607+ "$" -> dollarsMath <|> unescapedSymbolAsString
608+ "|" -> (guardEnabled Ext_literate_haskell *>
609+ symbol '|' *> doLHSverb) <|> symbolAsString
610+ "{" -> inlineGroup
611+ "#" -> unescapedSymbolAsString
612+ "&" -> unescapedSymbolAsString
613+ "_" -> unescapedSymbolAsString
614+ "^" -> unescapedSymbolAsString
615+ "\\" -> mzero
616+ "}" -> mzero
617+ _ -> symbolAsString
618+ CtrlSeq _ -> macroDef (rawInline "latex")
619+ <|> inlineCommand'
620+ <|> inlineEnvironment
621+ <|> inlineGroup
622+ _ -> mzero
1167623
1168624inlines :: PandocMonad m => LP m Inlines
1169625inlines = mconcat <$> many inline
1170626
627+opt :: PandocMonad m => LP m Inlines
628+opt = do
629+ toks <- try (sp *> bracketedToks <* sp)
630+ -- now parse the toks as inlines
631+ st <- getState
632+ parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
633+ case parsed of
634+ Right result -> return result
635+ Left e -> throwError $ PandocParsecError (toSources toks) e
636+
1171637-- block elements:
1172638
1173639preamble :: PandocMonad m => LP m Blocks
@@ -1261,10 +727,6 @@ insertIncluded defaultExtension f' = do
1261727 getInput >>= setInput . (tokenize f contents ++)
1262728 updateState dropLatestIncludeFile
1263729
1264−addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> LP m ()
1265−addMeta field val = updateState $ \st ->
1266− st{ sMeta = addMetaField field val $ sMeta st }
1267−
1268730authors :: PandocMonad m => LP m ()
1269731authors = try $ do
1270732 bgroup
@@ -1273,143 +735,6 @@ authors = try $ do
1273735 egroup
1274736 addMeta "author" (map trimInlines auths)
1275737
1276−macroDef :: (PandocMonad m, Monoid a) => (Text -> a) -> LP m a
1277−macroDef constructor = do
1278− (_, s) <- withRaw (commandDef <|> environmentDef)
1279− (constructor (untokenize s) <$
1280− guardDisabled Ext_latex_macros)
1281− <|> return mempty
1282− where commandDef = do
1283− (name, macro') <- newcommand <|> letmacro <|> defmacro
1284− guardDisabled Ext_latex_macros <|>
1285− updateState (\s -> s{ sMacros = M.insert name macro' (sMacros s) })
1286− environmentDef = do
1287− mbenv <- newenvironment
1288− case mbenv of
1289− Nothing -> return ()
1290− Just (name, macro1, macro2) ->
1291− guardDisabled Ext_latex_macros <|>
1292− do updateState $ \s -> s{ sMacros =
1293− M.insert name macro1 (sMacros s) }
1294− updateState $ \s -> s{ sMacros =
1295− M.insert ("end" <> name) macro2 (sMacros s) }
1296− -- @\newenvironment{envname}[n-args][default]{begin}{end}@
1297− -- is equivalent to
1298− -- @\newcommand{\envname}[n-args][default]{begin}@
1299− -- @\newcommand{\endenvname}@
1300−
1301−letmacro :: PandocMonad m => LP m (Text, Macro)
1302−letmacro = do
1303− controlSeq "let"
1304− (name, contents) <- withVerbatimMode $ do
1305− Tok _ (CtrlSeq name) _ <- anyControlSeq
1306− optional $ symbol '='
1307− spaces
1308− -- we first parse in verbatim mode, and then expand macros,
1309− -- because we don't want \let\foo\bar to turn into
1310− -- \let\foo hello if we have previously \def\bar{hello}
1311− contents <- bracedOrToken
1312− return (name, contents)
1313− contents' <- doMacros' 0 contents
1314− return (name, Macro ExpandWhenDefined [] Nothing contents')
1315−
1316−defmacro :: PandocMonad m => LP m (Text, Macro)
1317−defmacro = try $
1318− -- we use withVerbatimMode, because macros are to be expanded
1319− -- at point of use, not point of definition
1320− withVerbatimMode $ do
1321− controlSeq "def"
1322− Tok _ (CtrlSeq name) _ <- anyControlSeq
1323− argspecs <- many (argspecArg <|> argspecPattern)
1324− contents <- bracedOrToken
1325− return (name, Macro ExpandWhenUsed argspecs Nothing contents)
1326−
1327−argspecArg :: PandocMonad m => LP m ArgSpec
1328−argspecArg = do
1329− Tok _ (Arg i) _ <- satisfyTok isArgTok
1330− return $ ArgNum i
1331−
1332−argspecPattern :: PandocMonad m => LP m ArgSpec
1333−argspecPattern =
1334− Pattern <$> many1 (satisfyTok (\(Tok _ toktype' txt) ->
1335− (toktype' == Symbol || toktype' == Word) &&
1336− (txt /= "{" && txt /= "\\" && txt /= "}")))
1337−
1338−newcommand :: PandocMonad m => LP m (Text, Macro)
1339−newcommand = do
1340− pos <- getPosition
1341− Tok _ (CtrlSeq mtype) _ <- controlSeq "newcommand" <|>
1342− controlSeq "renewcommand" <|>
1343− controlSeq "providecommand" <|>
1344− controlSeq "DeclareMathOperator" <|>
1345− controlSeq "DeclareRobustCommand"
1346− withVerbatimMode $ do
1347− Tok _ (CtrlSeq name) txt <- do
1348− optional (symbol '*')
1349− anyControlSeq <|>
1350− (symbol '{' *> spaces *> anyControlSeq <* spaces <* symbol '}')
1351− spaces
1352− numargs <- option 0 $ try bracketedNum
1353− let argspecs = map ArgNum [1..numargs]
1354− spaces
1355− optarg <- option Nothing $ Just <$> try bracketedToks
1356− spaces
1357− contents' <- bracedOrToken
1358− let contents =
1359− case mtype of
1360− "DeclareMathOperator" ->
1361− Tok pos (CtrlSeq "mathop") "\\mathop"
1362− : Tok pos Symbol "{"
1363− : Tok pos (CtrlSeq "mathrm") "\\mathrm"
1364− : Tok pos Symbol "{"
1365− : (contents' ++
1366− [ Tok pos Symbol "}", Tok pos Symbol "}" ])
1367− _ -> contents'
1368− macros <- sMacros <$> getState
1369− case M.lookup name macros of
1370− Just macro
1371− | mtype == "newcommand" -> do
1372− report $ MacroAlreadyDefined txt pos
1373− return (name, macro)
1374− | mtype == "providecommand" -> return (name, macro)
1375− _ -> return (name, Macro ExpandWhenUsed argspecs optarg contents)
1376−
1377−newenvironment :: PandocMonad m => LP m (Maybe (Text, Macro, Macro))
1378−newenvironment = do
1379− pos <- getPosition
1380− Tok _ (CtrlSeq mtype) _ <- controlSeq "newenvironment" <|>
1381− controlSeq "renewenvironment" <|>
1382− controlSeq "provideenvironment"
1383− withVerbatimMode $ do
1384− optional $ symbol '*'
1385− spaces
1386− name <- untokenize <$> braced
1387− spaces
1388− numargs <- option 0 $ try bracketedNum
1389− spaces
1390− optarg <- option Nothing $ Just <$> try bracketedToks
1391− let argspecs = map (\i -> ArgNum i) [1..numargs]
1392− startcontents <- spaces >> bracedOrToken
1393− endcontents <- spaces >> bracedOrToken
1394− macros <- sMacros <$> getState
1395− case M.lookup name macros of
1396− Just _
1397− | mtype == "newenvironment" -> do
1398− report $ MacroAlreadyDefined name pos
1399− return Nothing
1400− | mtype == "provideenvironment" ->
1401− return Nothing
1402− _ -> return $ Just (name,
1403− Macro ExpandWhenUsed argspecs optarg startcontents,
1404− Macro ExpandWhenUsed [] Nothing endcontents)
1405−
1406−bracketedNum :: PandocMonad m => LP m Int
1407−bracketedNum = do
1408− ds <- untokenize <$> bracketedToks
1409− case safeRead ds of
1410− Just i -> return i
1411− _ -> return 0
1412−
1413738looseItem :: PandocMonad m => LP m Blocks
1414739looseItem = do
1415740 inListItem <- sInListItem <$> getState
@@ -1515,7 +840,7 @@ blockCommands = M.fromList
1515840 , ("address", mempty <$ (skipopts *> tok >>= addMeta "address"))
1516841 , ("signature", mempty <$ (skipopts *> authors))
1517842 , ("date", mempty <$ (skipopts *> tok >>= addMeta "date"))
1518− , ("newtheorem", newtheorem)
843+ , ("newtheorem", newtheorem inline)
1519844 , ("theoremstyle", theoremstyle)
1520845 -- KOMA-Script metadata commands
1521846 , ("extratitle", mempty <$ (skipopts *> tok >>= addMeta "extratitle"))
@@ -1634,7 +959,7 @@ environments = M.union (tableEnvironments blocks inline) $
1634959 , ("lilypond", rawVerbEnv "lilypond")
1635960 , ("ly", rawVerbEnv "ly")
1636961 -- amsthm
1637− , ("proof", proof)
962+ , ("proof", proof blocks opt)
1638963 -- etoolbox
1639964 , ("ifstrequal", ifstrequal)
1640965 , ("newtoggle", braced >>= newToggle)
@@ -1655,128 +980,17 @@ filecontents = try $ do
1655980 st{ sFileContents = M.insert fp txt (sFileContents st) }
1656981 return mempty
1657982
1658−theoremstyle :: PandocMonad m => LP m Blocks
1659−theoremstyle = do
1660− stylename <- untokenize <$> braced
1661− let mbstyle = case stylename of
1662− "plain" -> Just PlainStyle
1663− "definition" -> Just DefinitionStyle
1664− "remark" -> Just RemarkStyle
1665− _ -> Nothing
1666− case mbstyle of
1667− Nothing -> return ()
1668− Just sty -> updateState $ \s -> s{ sLastTheoremStyle = sty }
1669− return mempty
1670−
1671−newtheorem :: PandocMonad m => LP m Blocks
1672−newtheorem = do
1673− number <- option True (False <$ symbol '*' <* sp)
1674− name <- untokenize <$> braced
1675− sp
1676− series <- option Nothing $ Just . untokenize <$> bracketedToks
1677− sp
1678− showName <- tok
1679− sp
1680− syncTo <- option Nothing $ Just . untokenize <$> bracketedToks
1681− sty <- sLastTheoremStyle <$> getState
1682− let spec = TheoremSpec { theoremName = showName
1683− , theoremStyle = sty
1684− , theoremSeries = series
1685− , theoremSyncTo = syncTo
1686− , theoremNumber = number
1687− , theoremLastNum = DottedNum [0] }
1688− tmap <- sTheoremMap <$> getState
1689− updateState $ \s -> s{ sTheoremMap =
1690− M.insert name spec tmap }
1691− return mempty
1692−
1693−proof :: PandocMonad m => LP m Blocks
1694−proof = do
1695− title <- option (B.text "Proof") opt
1696− bs <- env "proof" blocks
1697− return $
1698− B.divWith ("", ["proof"], []) $
1699− addQed $ addTitle (B.emph (title <> ".")) bs
1700−
1701−addTitle :: Inlines -> Blocks -> Blocks
1702−addTitle ils bs =
1703− case B.toList bs of
1704− (Para xs : rest)
1705− -> B.fromList (Para (B.toList ils ++ (Space : xs)) : rest)
1706− _ -> B.para ils <> bs
1707−
1708−addQed :: Blocks -> Blocks
1709−addQed bs =
1710− case Seq.viewr (B.unMany bs) of
1711− s Seq.:> Para ils
1712− -> B.Many (s Seq.|> Para (ils ++ B.toList qedSign))
1713− _ -> bs <> B.para qedSign
1714− where
1715− qedSign = B.str "\xa0\x25FB"
1716−
1717983environment :: PandocMonad m => LP m Blocks
1718984environment = try $ do
1719985 controlSeq "begin"
1720986 name <- untokenize <$> braced
1721987 M.findWithDefault mzero name environments <|>
1722− theoremEnvironment name <|>
988+ theoremEnvironment blocks opt name <|>
1723989 if M.member name (inlineEnvironments
1724990 :: M.Map Text (LP PandocPure Inlines))
1725991 then mzero
1726992 else try (rawEnv name) <|> rawVerbEnv name
1727993
1728−theoremEnvironment :: PandocMonad m => Text -> LP m Blocks
1729−theoremEnvironment name = do
1730− tmap <- sTheoremMap <$> getState
1731− case M.lookup name tmap of
1732− Nothing -> mzero
1733− Just tspec -> do
1734− optTitle <- option mempty $ (\x -> space <> "(" <> x <> ")") <$> opt
1735− mblabel <- option Nothing $ Just . untokenize <$>
1736− try (spaces >> controlSeq "label" >> spaces >> braced)
1737− bs <- env name blocks
1738− number <-
1739− if theoremNumber tspec
1740− then do
1741− let name' = fromMaybe name $ theoremSeries tspec
1742− num <- getNextNumber
1743− (maybe (DottedNum [0]) theoremLastNum .
1744− M.lookup name' . sTheoremMap)
1745− updateState $ \s ->
1746− s{ sTheoremMap =
1747− M.adjust
1748− (\spec -> spec{ theoremLastNum = num })
1749− name'
1750− (sTheoremMap s)
1751− }
1752−
1753− case mblabel of
1754− Just ident ->
1755− updateState $ \s ->
1756− s{ sLabels = M.insert ident
1757− (B.toList $
1758− theoremName tspec <> "\160" <>
1759− str (renderDottedNum num)) (sLabels s) }
1760− Nothing -> return ()
1761− return $ space <> B.text (renderDottedNum num)
1762− else return mempty
1763− let titleEmph = case theoremStyle tspec of
1764− PlainStyle -> B.strong
1765− DefinitionStyle -> B.strong
1766− RemarkStyle -> B.emph
1767− let title = titleEmph (theoremName tspec <> number)
1768− <> optTitle <> "." <> space
1769− return $ divWith (fromMaybe "" mblabel, [name], []) $ addTitle title
1770− $ case theoremStyle tspec of
1771− PlainStyle -> walk italicize bs
1772− _ -> bs
1773−
1774−italicize :: Block -> Block
1775−italicize x@(Para [Image{}]) = x -- see #6925
1776−italicize (Para ils) = Para [Emph ils]
1777−italicize (Plain ils) = Plain [Emph ils]
1778−italicize x = x
1779−
1780994rawEnv :: PandocMonad m => Text -> LP m Blocks
1781995rawEnv name = do
1782996 exts <- getOption readerExtensions
@@ -1948,7 +1162,8 @@ inputListing = do
19481162 let (ident,classes,kvs) = parseListingsOptions options
19491163 let classes' =
19501164 (case listingsLanguage options of
1951− Nothing -> (take 1 (languagesByExtension (T.pack $ takeExtension $ T.unpack f)) <>)
1165+ Nothing -> (take 1 (languagesByExtension defaultSyntaxMap
1166+ (T.pack $ takeExtension $ T.unpack f)) <>)
19521167 Just _ -> id) classes
19531168 let firstline = fromMaybe 1 $ lookup "firstline" options >>= safeRead
19541169 let lastline = fromMaybe (length codeLines) $
@@ -2016,27 +1231,21 @@ orderedList' = try $ do
20161231
20171232block :: PandocMonad m => LP m Blocks
20181233block = do
2019− res <- (mempty <$ spaces1)
2020− <|> environment
2021− <|> macroDef (rawBlock "latex")
2022− <|> blockCommand
2023− <|> paragraph
2024− <|> grouped block
1234+ Tok _ toktype _ <- lookAhead anyTok
1235+ res <- (case toktype of
1236+ Newline -> mempty <$ spaces1
1237+ Spaces -> mempty <$ spaces1
1238+ Comment -> mempty <$ spaces1
1239+ Word -> paragraph
1240+ CtrlSeq "begin" -> environment
1241+ CtrlSeq _ -> macroDef (rawBlock "latex")
1242+ <|> blockCommand
1243+ _ -> mzero)
1244+ <|> paragraph
1245+ <|> grouped block
20251246 trace (T.take 60 $ tshow $ B.toList res)
20261247 return res
20271248
20281249blocks :: PandocMonad m => LP m Blocks
20291250blocks = mconcat <$> many block
20301251
2031−setDefaultLanguage :: PandocMonad m => LP m Blocks
2032−setDefaultLanguage = do
2033− o <- option "" $ T.filter (\c -> c /= '[' && c /= ']')
2034− <$> rawopt
2035− polylang <- untokenize <$> braced
2036− case M.lookup polylang polyglossiaLangToBCP47 of
2037− Nothing -> return mempty -- TODO mzero? warning?
2038− Just langFunc -> do
2039− let l = langFunc o
2040− setTranslations l
2041− updateState $ setMeta "lang" $ str (renderLang l)
2042− return mempty