summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Writers/ConTeXt.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text/Pandoc/Writers/ConTeXt.hs')
-rw-r--r--src/Text/Pandoc/Writers/ConTeXt.hs110
1 files changed, 78 insertions, 32 deletions
diff --git a/src/Text/Pandoc/Writers/ConTeXt.hs b/src/Text/Pandoc/Writers/ConTeXt.hs
index 763f77d7c..dfdf7a140 100644
--- a/src/Text/Pandoc/Writers/ConTeXt.hs
+++ b/src/Text/Pandoc/Writers/ConTeXt.hs
@@ -31,12 +31,13 @@ Conversion of 'Pandoc' format into ConTeXt.
module Text.Pandoc.Writers.ConTeXt ( writeConTeXt ) where
import Text.Pandoc.Definition
import Text.Pandoc.Shared
+import Text.Pandoc.Generic (queryWith)
import Text.Printf ( printf )
import Data.List ( intercalate )
import Control.Monad.State
import Text.Pandoc.Pretty
import Text.Pandoc.Templates ( renderTemplate )
-import Network.URI ( isAbsoluteURI, unEscapeString )
+import Network.URI ( isURI, unEscapeString )
data WriterState =
WriterState { stNextRef :: Int -- number of next URL reference
@@ -68,13 +69,14 @@ pandocToConTeXt options (Pandoc (Meta title authors date) blocks) = do
datetext <- if null date
then return ""
else liftM (render colwidth) $ inlineListToConTeXt date
- body <- blockListToConTeXt blocks
- let main = render colwidth $ body
+ body <- mapM (elementToConTeXt options) $ hierarchicalize blocks
+ let main = (render colwidth . vcat) body
let context = writerVariables options ++
[ ("toc", if writerTableOfContents options then "yes" else "")
, ("body", main)
, ("title", titletext)
, ("date", datetext) ] ++
+ [ ("number-sections", "yes") | writerNumberSections options ] ++
[ ("author", a) | a <- authorstext ]
return $ if writerStandalone options
then renderTemplate context $ writerTemplate options
@@ -101,12 +103,24 @@ escapeCharForConTeXt ch =
']' -> "{]}"
'_' -> "\\letterunderscore{}"
'\160' -> "~"
+ '\x2014' -> "---"
+ '\x2013' -> "--"
+ '\x2019' -> "'"
+ '\x2026' -> "\\ldots{}"
x -> [x]
-- | Escape string for ConTeXt
stringToConTeXt :: String -> String
stringToConTeXt = concatMap escapeCharForConTeXt
+-- | Convert Elements to ConTeXt
+elementToConTeXt :: WriterOptions -> Element -> State WriterState Doc
+elementToConTeXt _ (Blk block) = blockToConTeXt block
+elementToConTeXt opts (Sec level _ id' title' elements) = do
+ header' <- sectionHeader id' level title'
+ innerContents <- mapM (elementToConTeXt opts) elements
+ return $ vcat (header' : innerContents)
+
-- | Convert Pandoc block element to ConTeXt.
blockToConTeXt :: Block
-> State WriterState Doc
@@ -166,18 +180,8 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
blockToConTeXt (DefinitionList lst) =
liftM vcat $ mapM defListItemToConTeXt lst
blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline
-blockToConTeXt (Header level lst) = do
- contents <- inlineListToConTeXt lst
- st <- get
- let opts = stOptions st
- let base = if writerNumberSections opts then "section" else "subject"
- let level' = if writerChapters opts then level - 1 else level
- return $ if level' >= 1 && level' <= 5
- then char '\\' <> text (concat (replicate (level' - 1) "sub")) <>
- text base <> char '{' <> contents <> char '}' <> blankline
- else if level' == 0
- then "\\chapter{" <> contents <> "}"
- else contents <> blankline
+-- If this is ever executed, provide a default for the reference identifier.
+blockToConTeXt (Header level lst) = sectionHeader "" level lst
blockToConTeXt (Table caption aligns widths heads rows) = do
let colDescriptor colWidth alignment = (case alignment of
AlignLeft -> 'l'
@@ -213,8 +217,8 @@ defListItemToConTeXt :: ([Inline], [[Block]]) -> State WriterState Doc
defListItemToConTeXt (term, defs) = do
term' <- inlineListToConTeXt term
def' <- liftM vsep $ mapM blockListToConTeXt defs
- return $ "\\startdescr" <> braces term' $$ nest 2 def' $$
- "\\stopdescr" <> blankline
+ return $ "\\startdescription" <> braces term' $$ nest 2 def' $$
+ "\\stopdescription" <> blankline
-- | Convert list of block elements to ConTeXt.
blockListToConTeXt :: [Block] -> State WriterState Doc
@@ -257,10 +261,6 @@ inlineToConTeXt (Quoted DoubleQuote lst) = do
contents <- inlineListToConTeXt lst
return $ "\\quotation" <> braces contents
inlineToConTeXt (Cite _ lst) = inlineListToConTeXt lst
-inlineToConTeXt Apostrophe = return $ char '\''
-inlineToConTeXt EmDash = return "---"
-inlineToConTeXt EnDash = return "--"
-inlineToConTeXt Ellipses = return "\\ldots{}"
inlineToConTeXt (Str str) = return $ text $ stringToConTeXt str
inlineToConTeXt (Math InlineMath str) =
return $ char '$' <> text str <> char '$'
@@ -271,23 +271,69 @@ inlineToConTeXt (RawInline "tex" str) = return $ text str
inlineToConTeXt (RawInline _ _) = return empty
inlineToConTeXt (LineBreak) = return $ text "\\crlf" <> cr
inlineToConTeXt Space = return space
-inlineToConTeXt (Link [Code _ str] (src, tit)) = -- since ConTeXt has its own
- inlineToConTeXt (Link [Str str] (src, tit)) -- way of printing links...
-inlineToConTeXt (Link txt (src, _)) = do
+-- autolink
+inlineToConTeXt (Link [Code _ str] (src, tit)) = inlineToConTeXt (Link
+ [RawInline "context" "\\hyphenatedurl{", Str str, RawInline "context" "}"]
+ (src, tit))
+-- Handle HTML-like internal document references to sections
+inlineToConTeXt (Link txt (('#' : ref), _)) = do
+ opts <- gets stOptions
+ label <- inlineListToConTeXt txt
+ return $ text "\\in"
+ <> braces (if writerNumberSections opts
+ then label <+> text "(\\S"
+ else label) -- prefix
+ <> braces (if writerNumberSections opts
+ then text ")"
+ else empty) -- suffix
+ <> brackets (text ref)
+
+inlineToConTeXt (Link txt (src, _)) = do
st <- get
let next = stNextRef st
put $ st {stNextRef = next + 1}
- let ref = show next
- label <- inlineListToConTeXt txt
- return $ "\\useURL" <> brackets (text ref) <> brackets (text src) <>
- brackets empty <> brackets label <>
- "\\from" <> brackets (text ref)
+ let ref = "url" ++ show next
+ label <- inlineListToConTeXt txt
+ return $ "\\useURL"
+ <> brackets (text ref)
+ <> brackets (text $ escapeStringUsing [('#',"\\#")] src)
+ <> brackets empty
+ <> brackets label
+ <> "\\from"
+ <> brackets (text ref)
inlineToConTeXt (Image _ (src, _)) = do
- let src' = if isAbsoluteURI src
+ let src' = if isURI src
then src
else unEscapeString src
return $ braces $ "\\externalfigure" <> brackets (text src')
inlineToConTeXt (Note contents) = do
contents' <- blockListToConTeXt contents
- return $ text "\\footnote{" <>
- nest 2 contents' <> char '}'
+ let codeBlock x@(CodeBlock _ _) = [x]
+ codeBlock _ = []
+ let codeBlocks = queryWith codeBlock contents
+ return $ if null codeBlocks
+ then text "\\footnote{" <> nest 2 contents' <> char '}'
+ else text "\\startbuffer " <> nest 2 contents' <>
+ text "\\stopbuffer\\footnote{\\getbuffer}"
+
+-- | Craft the section header, inserting the secton reference, if supplied.
+sectionHeader :: [Char]
+ -> Int
+ -> [Inline]
+ -> State WriterState Doc
+sectionHeader ident hdrLevel lst = do
+ contents <- inlineListToConTeXt lst
+ st <- get
+ let opts = stOptions st
+ let level' = if writerChapters opts then hdrLevel - 1 else hdrLevel
+ return $ if level' >= 1 && level' <= 5
+ then char '\\'
+ <> text (concat (replicate (level' - 1) "sub"))
+ <> text "section"
+ <> (if (not . null) ident then brackets (text ident) else empty)
+ <> braces contents
+ <> blankline
+ else if level' == 0
+ then "\\chapter{" <> contents <> "}"
+ else contents <> blankline
+