diff options
Diffstat (limited to 'src/Text/Pandoc/Writers/ConTeXt.hs')
-rw-r--r-- | src/Text/Pandoc/Writers/ConTeXt.hs | 110 |
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 + |