summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Writers/LaTeX.hs
diff options
context:
space:
mode:
authorJohn MacFarlane <fiddlosopher@gmail.com>2011-12-30 14:30:45 -0800
committerJohn MacFarlane <fiddlosopher@gmail.com>2011-12-30 14:30:45 -0800
commite3dfb2646d950a6c468835cca5da759cf098ee75 (patch)
treef9ce0c8097586648e738bc765e35f90b1e401504 /src/Text/Pandoc/Writers/LaTeX.hs
parent209ba0fa6cfac251996bcc6e2649c38118f31c23 (diff)
Add support for internal links to LaTeX writer.
Based on a patch by B. Scott Michel.
Diffstat (limited to 'src/Text/Pandoc/Writers/LaTeX.hs')
-rw-r--r--src/Text/Pandoc/Writers/LaTeX.hs77
1 files changed, 50 insertions, 27 deletions
diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs
index fa715df25..164d350be 100644
--- a/src/Text/Pandoc/Writers/LaTeX.hs
+++ b/src/Text/Pandoc/Writers/LaTeX.hs
@@ -109,9 +109,9 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
blocks'' <- if writerBeamer options
then toSlides blocks'
else return blocks'
- body <- blockListToLaTeX blocks''
+ body <- mapM (elementToLaTeX options) $ hierarchicalize blocks''
biblioTitle <- liftM (render colwidth) $ inlineListToLaTeX lastHeader
- let main = render colwidth body
+ let main = render colwidth $ cat body
st <- get
let biblioFiles = intercalate "," $ map dropExtension $ writerBiblioFiles options
citecontext = case writerCiteMethod options of
@@ -154,8 +154,15 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
then renderTemplate context template
else main
--- escape things as needed for LaTeX
+-- | Convert Elements to LaTeX
+elementToLaTeX :: WriterOptions -> Element -> State WriterState Doc
+elementToLaTeX _ (Blk block) = blockToLaTeX block
+elementToLaTeX opts (Sec level _ id' title' elements) = do
+ header' <- sectionHeader id' level title'
+ innerContents <- mapM (elementToLaTeX opts) elements
+ return $ cat (header' : innerContents)
+-- escape things as needed for LaTeX
stringToLaTeX :: Bool -> String -> String
stringToLaTeX isUrl = escapeStringUsing latexEscapes
where latexEscapes = backslashEscapes "{}$%&_" ++
@@ -335,30 +342,7 @@ blockToLaTeX (DefinitionList lst) = do
return $ text ("\\begin{description}" ++ inc) $$ vcat items $$ "\\end{description}"
blockToLaTeX HorizontalRule = return $
"\\begin{center}\\rule{3in}{0.4pt}\\end{center}" $$ blankline
-blockToLaTeX (Header level lst) = do
- txt <- inlineListToLaTeX lst
- let noNote (Note _) = Str ""
- noNote x = x
- let lstNoNotes = bottomUp noNote lst
- -- footnotes in sections don't work unless you specify an optional
- -- argument: \section[mysec]{mysec\footnote{blah}}
- optional <- if lstNoNotes == lst
- then return empty
- else do
- res <- inlineListToLaTeX lstNoNotes
- return $ char '[' <> res <> char ']'
- let stuffing = optional <> char '{' <> txt <> char '}'
- book <- liftM stBook get
- let level' = if book then level - 1 else level
- let headerWith x y = text x <> y $$ blankline
- return $ case level' of
- 0 -> headerWith "\\chapter" stuffing
- 1 -> headerWith "\\section" stuffing
- 2 -> headerWith "\\subsection" stuffing
- 3 -> headerWith "\\subsubsection" stuffing
- 4 -> headerWith "\\paragraph" stuffing
- 5 -> headerWith "\\subparagraph" stuffing
- _ -> txt $$ blankline
+blockToLaTeX (Header level lst) = sectionHeader "" level lst
blockToLaTeX (Table caption aligns widths heads rows) = do
modify $ \s -> s{ stInTable = True, stTableNotes = [] }
headers <- if all null heads
@@ -426,6 +410,45 @@ defListItemToLaTeX (term, defs) = do
def' <- liftM vsep $ mapM blockListToLaTeX defs
return $ "\\item" <> brackets term' $$ def'
+-- | Craft the section header, inserting the secton reference, if supplied.
+sectionHeader :: [Char]
+ -> Int
+ -> [Inline]
+ -> State WriterState Doc
+sectionHeader ref level lst = do
+ txt <- inlineListToLaTeX lst
+ let noNote (Note _) = Str ""
+ noNote x = x
+ let lstNoNotes = bottomUp noNote lst
+ -- footnotes in sections don't work unless you specify an optional
+ -- argument: \section[mysec]{mysec\footnote{blah}}
+ optional <- if lstNoNotes == lst
+ then return empty
+ else do
+ res <- inlineListToLaTeX lstNoNotes
+ return $ char '[' <> res <> char ']'
+ let stuffing = optional <> char '{' <> txt <> char '}'
+ book <- liftM stBook get
+ let level' = if book then level - 1 else level
+ let refLabel lab = (if (not . null) ref
+ then text "\\hyperdef"
+ <> braces empty
+ <> braces (text ref)
+ <> braces (lab <> text "\\label"
+ <> braces (text ref))
+ else lab)
+ $$ blankline
+ let headerWith x y = refLabel $ text x <> y
+ return $ case level' of
+ 0 -> headerWith "\\chapter" stuffing
+ 1 -> headerWith "\\section" stuffing
+ 2 -> headerWith "\\subsection" stuffing
+ 3 -> headerWith "\\subsubsection" stuffing
+ 4 -> headerWith "\\paragraph" stuffing
+ 5 -> headerWith "\\subparagraph" stuffing
+ _ -> txt $$ blankline
+
+
-- | Convert list of inline elements to LaTeX.
inlineListToLaTeX :: [Inline] -- ^ Inlines to convert
-> State WriterState Doc