git.iko.soy/typeable/pandoc
on master help sign in
ConTeXt writer: Add section labels and internal links as in HTML.

Add the ability to refer to internal links to the ConTeXt writer, just like the HTML writer can. The 'hierarchicalize' function generates unique names for sections, which can be used for references in ConTeXt, just as they can be in HTML. The ConTeXt writer adds these unique identifiers to each \section and does special processing of the Link target to see if it starts with a '#' (hash symbol), which is the tip-off that the link is an internal link.

commita5ee02c659e8bc4030c9b7b5ceafb846e2bc4e77 authorB. Scott Michel <scooter.phd@gmail.com> dateTue 6 Sep 2011, 20:48 (15 years ago) parent8368043
2 files changed+77−27
README+6−6 src/Text/Pandoc/Writers/ConTeXt.hs+71−21
README+6−6
@@ -707,13 +707,13 @@ wrapping). Consider, for example:
707707 #22, for example, and #5.
708708
709709
710−### Header identifiers in HTML ###
710+### Header identifiers in HTML and ConTeXt ###
711711
712712*Pandoc extension*.
713713
714−Each header element in pandoc's HTML output is given a unique
715−identifier. This identifier is based on the text of the header. To
716−derive the identifier from the header text,
714+Each header element in pandoc's HTML and ConTeXt output is given a
715+unique identifier. This identifier is based on the text of the header.
716+To derive the identifier from the header text,
717717
718718 - Remove all formatting, links, etc.
719719 - Remove all punctuation, except underscores, hyphens, and periods.
@@ -745,10 +745,10 @@ also make it easy to provide links from one section of a document to
745745another. A link to this section, for example, might look like this:
746746
747747 See the section on
748− [header identifiers](#header-identifiers-in-html).
748+ [header identifiers][#header-identifiers-in-html].
749749
750750Note, however, that this method of providing links to sections works
751−only in HTML.
751+only in HTML and ConTeXt formats.
752752
753753If the `--section-divs` option is specified, then each section will
754754be wrapped in a `div` (or a `section`, if `--html5` was specified),
src/Text/Pandoc/Writers/ConTeXt.hs+71−21
@@ -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