@@ -69,8 +69,8 @@ pandocToConTeXt options (Pandoc (Meta title authors date) blocks) = do
6969 datetext <- if null date
7070 then return ""
7171 else liftM (render colwidth) $ inlineListToConTeXt date
72− body <- blockListToConTeXt blocks
73− let main = render colwidth $ body
72+ body <- mapM (elementToConTeXt options) $ hierarchicalize blocks
73+ let main = (render colwidth . cat) body
7474 let context = writerVariables options ++
7575 [ ("toc", if writerTableOfContents options then "yes" else "")
7676 , ("body", main)
@@ -113,6 +113,14 @@ escapeCharForConTeXt ch =
113113stringToConTeXt :: String -> String
114114stringToConTeXt = concatMap escapeCharForConTeXt
115115
116+-- | Convert Elements to ConTeXt
117+elementToConTeXt :: WriterOptions -> Element -> State WriterState Doc
118+elementToConTeXt _ (Blk block) = blockToConTeXt block
119+elementToConTeXt opts (Sec level _ id' title' elements) = do
120+ header' <- sectionHeader id' level title'
121+ innerContents <- mapM (elementToConTeXt opts) elements
122+ return $ cat (header' : innerContents)
123+
116124-- | Convert Pandoc block element to ConTeXt.
117125blockToConTeXt :: Block
118126 -> State WriterState Doc
@@ -172,17 +180,8 @@ blockToConTeXt (OrderedList (start, style', delim) lst) = do
172180blockToConTeXt (DefinitionList lst) =
173181 liftM vcat $ mapM defListItemToConTeXt lst
174182blockToConTeXt HorizontalRule = return $ "\\thinrule" <> blankline
175−blockToConTeXt (Header level lst) = do
176− contents <- inlineListToConTeXt lst
177− st <- get
178− let opts = stOptions st
179− let level' = if writerChapters opts then level - 1 else level
180− return $ if level' >= 1 && level' <= 5
181− then char '\\' <> text (concat (replicate (level' - 1) "sub")) <>
182− text "section" <> char '{' <> contents <> char '}' <> blankline
183− else if level' == 0
184− then "\\chapter{" <> contents <> "}"
185− else contents <> blankline
183+-- If this is ever executed, provide a default for the reference identifier.
184+blockToConTeXt (Header level lst) = sectionHeader "" level lst
186185blockToConTeXt (Table caption aligns widths heads rows) = do
187186 let colDescriptor colWidth alignment = (case alignment of
188187 AlignLeft -> 'l'
@@ -274,20 +273,40 @@ inlineToConTeXt (LineBreak) = return $ text "\\crlf" <> cr
274273inlineToConTeXt Space = return space
275274-- ConTeXT has its own way of printing links
276275inlineToConTeXt (Link [Code _ str] (src, tit)) = inlineToConTeXt (Link [Str str] (src, tit))
276+-- Handle HTML-like internal document references to sections
277+inlineToConTeXt (Link txt (('#' : ref), _)) = do
278+ st <- get
279+ let opts = stOptions st
280+ let numberedSections = writerNumberSections opts
281+ label <- inlineListToConTeXt $ bottomUp hyphenateURL (normalize txt)
282+ let hasLabel = (not . isEmpty) label
283+ let label' = if hasLabel
284+ then label <+> text "("
285+ else if numberedSections
286+ then text "Section"
287+ else empty
288+ let label'' = braces $ if hasLabel
289+ then text ")"
290+ else empty
291+ return $ text "\\in"
292+ <> braces label'
293+ <> braces label''
294+ <> brackets (text ref)
295+
277296-- Convert link's text, hyphenating URLs when they're seen (does deep list inspection)
278297inlineToConTeXt (Link txt (src, _)) = do
279298 st <- get
280299 let next = stNextRef st
281300 put $ st {stNextRef = next + 1}
282301 let ref = "url" ++ show next
283− let hyphenateURL (Str str) | isURI str =
284− RawInline "context" ("\\hyphenatedurl{" ++ str ++ "}")
285− hyphenateURL x = x
286− label <- inlineListToConTeXt (bottomUp hyphenateURL $ normalize txt)
287− return $ "\\useURL" <> brackets (text ref) <>
288− brackets (text $ escapeStringUsing [('#',"\\#")] src) <>
289− brackets empty <> brackets label <>
290− "\\from" <> brackets (text ref)
302+ label <- inlineListToConTeXt $ bottomUp hyphenateURL (normalize txt)
303+ return $ "\\useURL"
304+ <> brackets (text ref)
305+ <> brackets (text $ escapeStringUsing [('#',"\\#")] src)
306+ <> brackets empty
307+ <> brackets label
308+ <> "\\from"
309+ <> brackets (text ref)
291310inlineToConTeXt (Image _ (src, _)) = do
292311 let src' = if isURI src
293312 then src
@@ -302,3 +321,34 @@ inlineToConTeXt (Note contents) = do
302321 then text "\\footnote{" <> nest 2 contents' <> char '}'
303322 else text "\\startbuffer " <> nest 2 contents' <>
304323 text "\\stopbuffer\\footnote{\\getbuffer}"
324+
325+-- | Craft the section header, inserting the secton reference, if supplied.
326+sectionHeader :: [Char]
327+ -> Int
328+ -> [Inline]
329+ -> State WriterState Doc
330+sectionHeader ident hdrLevel lst = do
331+ contents <- (inlineListToConTeXt . normalize) lst
332+ st <- get
333+ let opts = stOptions st
334+ let level' = if writerChapters opts then hdrLevel - 1 else hdrLevel
335+ return $ if level' >= 1 && level' <= 5
336+ then char '\\'
337+ <> text (concat (replicate (level' - 1) "sub"))
338+ <> text "section"
339+ <> (if (not . null) ident then brackets (text ident) else empty)
340+ <> braces contents
341+ <> blankline
342+ else if level' == 0
343+ then "\\chapter{" <> contents <> "}"
344+ else contents <> blankline
345+
346+-- | Convert absolute URLs/URIs to ConTeXt raw inlines so that they are hyphenated.
347+hyphenateURL :: Inline
348+ -> Inline
349+hyphenateURL x =
350+ case x of
351+ (Str str) -> if isAbsoluteURI str
352+ then (RawInline "context" ("\\hyphenatedurl{" ++ str ++ "}"))
353+ else x
354+ _otherwise -> x