@@ -30,17 +30,19 @@ Conversion of 'Pandoc' format into Texinfo.
3030module Text.Pandoc.Writers.Texinfo ( writeTexinfo ) where
3131import Text.Pandoc.Definition
3232import Text.Pandoc.Shared
33+import Text.Pandoc.Templates (renderTemplate)
3334import Text.Pandoc.Readers.TeXMath
3435import Text.Printf ( printf )
3536import Data.List ( isSuffixOf, transpose, maximumBy )
3637import Data.Ord ( comparing )
3738import Data.Char ( chr, ord )
38−import qualified Data.Set as S
3939import Control.Monad.State
4040import Text.PrettyPrint.HughesPJ hiding ( Str )
4141
4242data WriterState =
43− WriterState { stIncludes :: S.Set String -- strings to include in header
43+ WriterState { stStrikeout :: Bool -- document contains strikeout
44+ , stSuperscript :: Bool -- document contains superscript
45+ , stSubscript :: Bool -- document contains subscript
4446 }
4547
4648{- TODO:
@@ -48,81 +50,45 @@ data WriterState =
4850 - generated .texi files don't work when run through texi2dvi
4951 -}
5052
51−-- | Add line to header.
52−addToHeader :: String -> State WriterState ()
53−addToHeader str = do
54− st <- get
55− let includes = stIncludes st
56− put st {stIncludes = S.insert str includes}
57−
5853-- | Convert Pandoc to Texinfo.
5954writeTexinfo :: WriterOptions -> Pandoc -> String
6055writeTexinfo options document =
61− render $ evalState (pandocToTexinfo options $ wrapTop document) $
62− WriterState { stIncludes = S.empty }
56+ evalState (pandocToTexinfo options $ wrapTop document) $
57+ WriterState { stStrikeout = False, stSuperscript = False, stSubscript = False }
6358
6459-- | Add a "Top" node around the document, needed by Texinfo.
6560wrapTop :: Pandoc -> Pandoc
6661wrapTop (Pandoc (Meta title authors date) blocks) =
6762 Pandoc (Meta title authors date) (Header 0 title : blocks)
6863
69−pandocToTexinfo :: WriterOptions -> Pandoc -> State WriterState Doc
70−pandocToTexinfo options (Pandoc meta blocks) = do
71− return empty -- TODO
72−-- main <- blockListToTexinfo blocks
73−-- head' <- if writerStandalone options
74−-- then texinfoHeader options meta
75−-- else return empty
76−-- let before = if null (writerIncludeBefore options)
77−-- then empty
78−-- else text (writerIncludeBefore options)
79−-- let after = if null (writerIncludeAfter options)
80−-- then empty
81−-- else text (writerIncludeAfter options)
82−-- let body = before $$ main $$ after
83−-- -- XXX toc untested
84−-- let toc = if writerTableOfContents options
85−-- then text "@contents"
86−-- else empty
87−-- let foot = if writerStandalone options
88−-- then text "@bye"
89−-- else empty
90−-- return $ head' $$ toc $$ body $$ foot
91−
92−-- | Insert bibliographic information into Texinfo header.
93−texinfoHeader :: WriterOptions -- ^ Options, including Texinfo header
94− -> Meta -- ^ Meta with bibliographic information
95− -> State WriterState Doc
96−texinfoHeader options (Meta title authors date) = do
97− return empty -- TODO
98−-- titletext <- if null title
99−-- then return empty
100−-- else do
101−-- t <- inlineListToTexinfo title
102−-- return $ text "@title " <> t
103−-- headerIncludes <- get >>= return . S.toList . stIncludes
104−-- let extras = text $ unlines headerIncludes
105−-- let authorstext = map makeAuthor authors
106−-- let datetext = if date == ""
107−-- then empty
108−-- else text $ stringToTexinfo date
109−--
110−-- let baseHeader = case writerHeader options of
111−-- "" -> empty
112−-- x -> text x
113−-- let header = text "@documentencoding utf-8" $$ baseHeader $$ extras
114−-- return $ text "\\input texinfo" $$
115−-- header $$
116−-- text "@ifnottex" $$
117−-- text "@paragraphindent 0" $$
118−-- text "@end ifnottex" $$
119−-- text "@titlepage" $$
120−-- titletext $$ vcat authorstext $$
121−-- datetext $$
122−-- text "@end titlepage"
123−
124−makeAuthor :: String -> Doc
125−makeAuthor author = text $ "@author " ++ (stringToTexinfo author)
64+pandocToTexinfo :: WriterOptions -> Pandoc -> State WriterState String
65+pandocToTexinfo options (Pandoc (Meta title authors date) blocks) = do
66+ titleText <- inlineListToTexinfo title
67+ authorsText <- mapM inlineListToTexinfo authors
68+ dateText <- inlineListToTexinfo date
69+ let titlePage = not $ all null $ title : date : authors
70+ main <- blockListToTexinfo blocks
71+ st <- get
72+ let before = if null (writerIncludeBefore options)
73+ then empty
74+ else text (writerIncludeBefore options)
75+ let after = if null (writerIncludeAfter options)
76+ then empty
77+ else text (writerIncludeAfter options)
78+ let body = render $ before $$ main $$ after
79+ let context = writerVariables options ++
80+ [ ("body", body)
81+ , ("title", render titleText)
82+ , ("date", render dateText) ] ++
83+ [ ("toc", "yes") | writerTableOfContents options ] ++
84+ [ ("titlepage", "yes") | titlePage ] ++
85+ [ ("subscript", "yes") | stSubscript st ] ++
86+ [ ("superscript", "yes") | stSuperscript st ] ++
87+ [ ("strikeout", "yes") | stStrikeout st ] ++
88+ [ ("author", render a) | a <- authorsText ]
89+ if writerStandalone options
90+ then return $ renderTemplate context $ writerTemplate options
91+ else return body
12692
12793-- | Escape things as needed for Texinfo.
12894stringToTexinfo :: String -> String
@@ -397,33 +363,17 @@ inlineToTexinfo (Strong lst) =
397363 inlineListToTexinfo lst >>= return . inCmd "strong"
398364
399365inlineToTexinfo (Strikeout lst) = do
400− addToHeader $ "@macro textstrikeout{text}\n" ++
401− "~~\\text\\~~\n" ++
402− "@end macro\n"
366+ modify $ \st -> st{ stStrikeout = True }
403367 contents <- inlineListToTexinfo lst
404368 return $ text "@textstrikeout{" <> contents <> text "}"
405369
406370inlineToTexinfo (Superscript lst) = do
407− addToHeader $ "@macro textsuperscript{text}\n" ++
408− "@iftex\n" ++
409− "@textsuperscript{\\text\\}\n" ++
410− "@end iftex\n" ++
411− "@ifnottex\n" ++
412− "^@{\\text\\@}\n" ++
413− "@end ifnottex\n" ++
414− "@end macro\n"
371+ modify $ \st -> st{ stSuperscript = True }
415372 contents <- inlineListToTexinfo lst
416373 return $ text "@textsuperscript{" <> contents <> char '}'
417374
418375inlineToTexinfo (Subscript lst) = do
419− addToHeader $ "@macro textsubscript{text}\n" ++
420− "@iftex\n" ++
421− "@textsubscript{\\text\\}\n" ++
422− "@end iftex\n" ++
423− "@ifnottex\n" ++
424− "_@{\\text\\@}\n" ++
425− "@end ifnottex\n" ++
426− "@end macro\n"
376+ modify $ \st -> st{ stSubscript = True }
427377 contents <- inlineListToTexinfo lst
428378 return $ text "@textsubscript{" <> contents <> char '}'
429379