Skip to content

Commit

Permalink
LaTeX reader: support theorem environments and \newtheorem.
Browse files Browse the repository at this point in the history
Includes numbering and labels and refs.

Note that numbering support is not complete; we don't
reset numbers with sections for example.
  • Loading branch information
jgm committed Jul 22, 2020
1 parent 65865b3 commit 9d07d18
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
66 changes: 63 additions & 3 deletions src/Text/Pandoc/Readers/LaTeX.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,7 @@ blockCommands = M.fromList
, ("address", mempty <$ (skipopts *> tok >>= addMeta "address"))
, ("signature", mempty <$ (skipopts *> authors))
, ("date", mempty <$ (skipopts *> tok >>= addMeta "date"))
, ("newtheorem", newtheorem)
-- KOMA-Script metadata commands
, ("extratitle", mempty <$ (skipopts *> tok >>= addMeta "extratitle"))
, ("frontispiece", mempty <$ (skipopts *> tok >>= addMeta "frontispiece"))
Expand Down Expand Up @@ -1847,7 +1848,7 @@ environments = M.fromList
, ("lilypond", rawVerbEnv "lilypond")
, ("ly", rawVerbEnv "ly")
-- amsthm
, ("proof", amsProof)
, ("proof", proof)
-- etoolbox
, ("ifstrequal", ifstrequal)
, ("newtoggle", braced >>= newToggle)
Expand All @@ -1856,8 +1857,25 @@ environments = M.fromList
, ("iftoggle", try $ ifToggle >> block)
]

amsProof :: PandocMonad m => LP m Blocks
amsProof = do
newtheorem :: PandocMonad m => LP m Blocks
newtheorem = do
number <- option True (False <$ symbol '*' <* sp)
name <- untokenize <$> braced
series <- option Nothing $ Just <$> rawopt
showName <- untokenize <$> braced
syncTo <- option Nothing $ Just <$> rawopt
let spec = TheoremSpec { theoremName = showName
, theoremSeries = series
, theoremSyncTo = syncTo
, theoremNumber = number
, theoremLastNum = DottedNum [0] }
tmap <- sTheoremMap <$> getState
updateState $ \s -> s{ sTheoremMap =
M.insert name spec tmap }
return mempty

proof :: PandocMonad m => LP m Blocks
proof = do
title <- option (B.text "Proof") opt
bs <- env "proof" blocks
return $
Expand Down Expand Up @@ -1885,11 +1903,53 @@ environment = try $ do
controlSeq "begin"
name <- untokenize <$> braced
M.findWithDefault mzero name environments <|>
lookupTheoremEnvironment name <|>
if M.member name (inlineEnvironments
:: M.Map Text (LP PandocPure Inlines))
then mzero
else try (rawEnv name) <|> rawVerbEnv name

lookupTheoremEnvironment :: PandocMonad m => Text -> LP m Blocks
lookupTheoremEnvironment name = do
tmap <- sTheoremMap <$> getState
case M.lookup name tmap of
Nothing -> mzero
Just tspec -> do
optTitle <- option mempty $ (\x -> space <> "(" <> x <> ")") <$> opt
mblabel <- option Nothing $ Just . untokenize <$>
try (spaces >> controlSeq "label" >> spaces >> braced)
bs <- env name blocks
number <- if theoremNumber tspec
then do
num <- getNextNumber
(fromMaybe (DottedNum [0]) .
fmap theoremLastNum .
M.lookup name . sTheoremMap)
updateState $ \s ->
s{ sTheoremMap =
M.insert name
tspec{ theoremLastNum = num }
(sTheoremMap s)
}
case mblabel of
Just ident ->
updateState $ \s ->
s{ sLabels = M.insert ident
[Str (theoremName tspec), Str "\160",
Str (renderDottedNum num)] (sLabels s) }
Nothing -> return ()
return $ space <> B.text (renderDottedNum num)
else return mempty
let title = B.strong (B.text (theoremName tspec) <> number
<> optTitle) <> space
return $ divWith ("", [name], []) $ addTitle title $
walk italicize bs

italicize :: Block -> Block
italicize (Para ils) = Para [Emph ils]
italicize (Plain ils) = Plain [Emph ils]
italicize x = x

env :: PandocMonad m => Text -> LP m a -> LP m a
env name p = p <* end_ name

Expand Down
2 changes: 2 additions & 0 deletions src/Text/Pandoc/Readers/LaTeX/Parsing.hs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ data TheoremSpec =
TheoremSpec
{ theoremName :: Text
, theoremSeries :: Maybe Text
, theoremSyncTo :: Maybe Text
, theoremNumber :: Bool
, theoremLastNum :: DottedNum }
deriving (Show)

Expand Down

0 comments on commit 9d07d18

Please sign in to comment.