@@ -193,7 +193,7 @@ stringToLaTeX _ [] = return ""
193193stringToLaTeX ctx (x:xs) = do
194194 opts <- gets stOptions
195195 rest <- stringToLaTeX ctx xs
196− let ligatures = writerTeXLigatures opts && (ctx /= CodeString)
196+ let ligatures = writerTeXLigatures opts && ctx == TextString
197197 let isUrl = ctx == URLString
198198 when (x == '€') $
199199 modify $ \st -> st{ stUsesEuro = True }
@@ -207,7 +207,8 @@ stringToLaTeX ctx (x:xs) = do
207207 '&' -> "\\&" ++ rest
208208 '_' | not isUrl -> "\\_" ++ rest
209209 '#' -> "\\#" ++ rest
210− '-' -> case xs of -- prevent adjacent hyphens from forming ligatures
210+ '-' | not isUrl -> case xs of
211+ -- prevent adjacent hyphens from forming ligatures
211212 ('-':_) -> "-\\/" ++ rest
212213 _ -> '-' : rest
213214 '~' | not isUrl -> "\\textasciitilde{}" ++ rest
@@ -229,12 +230,13 @@ stringToLaTeX ctx (x:xs) = do
229230 '\x2013' | ligatures -> "--" ++ rest
230231 _ -> x : rest
231232
232−toLabel :: String -> String
233−toLabel [] = ""
234−toLabel (x:xs)
235− | (isLetter x || isDigit x) && isAscii x = x:toLabel xs
236− | elem x "-+=:;." = x:toLabel xs
237− | otherwise = "ux" ++ printf "%x" (ord x) ++ toLabel xs
233+toLabel :: String -> State WriterState String
234+toLabel z = go `fmap` stringToLaTeX URLString z
235+ where go [] = ""
236+ go (x:xs)
237+ | (isLetter x || isDigit x) && isAscii x = x:go xs
238+ | elem x "-+=:;." = x:go xs
239+ | otherwise = "ux" ++ printf "%x" (ord x) ++ go xs
238240
239241-- | Puts contents into LaTeX command.
240242inCmd :: String -> Doc -> Doc
@@ -340,57 +342,57 @@ blockToLaTeX (BlockQuote lst) = do
340342 return $ "\\begin{quote}" $$ contents $$ "\\end{quote}"
341343blockToLaTeX (CodeBlock (identifier,classes,keyvalAttr) str) = do
342344 opts <- gets stOptions
345+ ref <- toLabel identifier
346+ let linkAnchor = if null identifier
347+ then empty
348+ else "\\hyperdef{}" <> braces (text ref) <>
349+ braces ("\\label" <> braces (text ref))
350+ let lhsCodeBlock = do
351+ modify $ \s -> s{ stLHS = True }
352+ return $ flush (linkAnchor $$ "\\begin{code}" $$ text str $$
353+ "\\end{code}") $$ cr
354+ let rawCodeBlock = do
355+ st <- get
356+ env <- if stInNote st
357+ then modify (\s -> s{ stVerbInNote = True }) >>
358+ return "Verbatim"
359+ else return "verbatim"
360+ return $ flush (linkAnchor $$ text ("\\begin{" ++ env ++ "}") $$
361+ text str $$ text ("\\end{" ++ env ++ "}")) <> cr
362+ let listingsCodeBlock = do
363+ st <- get
364+ let params = if writerListings (stOptions st)
365+ then (case getListingsLanguage classes of
366+ Just l -> [ "language=" ++ l ]
367+ Nothing -> []) ++
368+ [ "numbers=left" | "numberLines" `elem` classes
369+ || "number" `elem` classes
370+ || "number-lines" `elem` classes ] ++
371+ [ (if key == "startFrom"
372+ then "firstnumber"
373+ else key) ++ "=" ++ attr |
374+ (key,attr) <- keyvalAttr ] ++
375+ (if identifier == ""
376+ then []
377+ else [ "label=" ++ ref ])
378+
379+ else []
380+ printParams
381+ | null params = empty
382+ | otherwise = brackets $ hcat (intersperse ", " (map text params))
383+ return $ flush ("\\begin{lstlisting}" <> printParams $$ text str $$
384+ "\\end{lstlisting}") $$ cr
385+ let highlightedCodeBlock =
386+ case highlight formatLaTeXBlock ("",classes,keyvalAttr) str of
387+ Nothing -> rawCodeBlock
388+ Just h -> modify (\st -> st{ stHighlighting = True }) >>
389+ return (flush $ linkAnchor $$ text h)
343390 case () of
344391 _ | isEnabled Ext_literate_haskell opts && "haskell" `elem` classes &&
345392 "literate" `elem` classes -> lhsCodeBlock
346393 | writerListings opts -> listingsCodeBlock
347394 | writerHighlight opts && not (null classes) -> highlightedCodeBlock
348395 | otherwise -> rawCodeBlock
349− where ref = text $ toLabel identifier
350− linkAnchor = if null identifier
351− then empty
352− else "\\hyperdef{}" <> braces ref <>
353− braces ("\\label" <> braces ref)
354− lhsCodeBlock = do
355− modify $ \s -> s{ stLHS = True }
356− return $ flush (linkAnchor $$ "\\begin{code}" $$ text str $$
357− "\\end{code}") $$ cr
358− rawCodeBlock = do
359− st <- get
360− env <- if stInNote st
361− then modify (\s -> s{ stVerbInNote = True }) >>
362− return "Verbatim"
363− else return "verbatim"
364− return $ flush (linkAnchor $$ text ("\\begin{" ++ env ++ "}") $$
365− text str $$ text ("\\end{" ++ env ++ "}")) <> cr
366− listingsCodeBlock = do
367− st <- get
368− let params = if writerListings (stOptions st)
369− then (case getListingsLanguage classes of
370− Just l -> [ "language=" ++ l ]
371− Nothing -> []) ++
372− [ "numbers=left" | "numberLines" `elem` classes
373− || "number" `elem` classes
374− || "number-lines" `elem` classes ] ++
375− [ (if key == "startFrom"
376− then "firstnumber"
377− else key) ++ "=" ++ attr |
378− (key,attr) <- keyvalAttr ] ++
379− (if identifier == ""
380− then []
381− else [ "label=" ++ toLabel identifier ])
382−
383− else []
384− printParams
385− | null params = empty
386− | otherwise = brackets $ hcat (intersperse ", " (map text params))
387− return $ flush ("\\begin{lstlisting}" <> printParams $$ text str $$
388− "\\end{lstlisting}") $$ cr
389− highlightedCodeBlock =
390− case highlight formatLaTeXBlock ("",classes,keyvalAttr) str of
391− Nothing -> rawCodeBlock
392− Just h -> modify (\st -> st{ stHighlighting = True }) >>
393− return (flush $ linkAnchor $$ text h)
394396blockToLaTeX (RawBlock f x)
395397 | f == Format "latex" || f == Format "tex"
396398 = return $ text x
@@ -579,6 +581,7 @@ sectionHeader :: Bool -- True for unnumbered
579581 -> State WriterState Doc
580582sectionHeader unnumbered ref level lst = do
581583 txt <- inlineListToLaTeX lst
584+ lab <- text `fmap` toLabel ref
582585 let noNote (Note _) = Str ""
583586 noNote x = x
584587 let lstNoNotes = walk noNote lst
@@ -599,13 +602,13 @@ sectionHeader unnumbered ref level lst = do
599602 let refLabel x = (if ref `elem` internalLinks
600603 then text "\\hyperdef"
601604 <> braces empty
602− <> braces (text $ toLabel ref)
605+ <> braces lab
603606 <> braces x
604607 else x)
605− let headerWith x y r = refLabel $ text x <> y <>
606− if null r
608+ let headerWith x y = refLabel $ text x <> y <>
609+ if null ref
607610 then empty
608− else text "\\label" <> braces (text $ toLabel r)
611+ else text "\\label" <> braces lab
609612 let sectionType = case level' of
610613 0 | writerBeamer opts -> "part"
611614 | otherwise -> "chapter"
@@ -624,7 +627,7 @@ sectionHeader unnumbered ref level lst = do
624627 return $ if level' > 5
625628 then txt
626629 else prefix $$
627− headerWith ('\\':sectionType) stuffing ref
630+ headerWith ('\\':sectionType) stuffing
628631 $$ if unnumbered
629632 then "\\addcontentsline{toc}" <>
630633 braces (text sectionType) <>
@@ -659,9 +662,10 @@ inlineToLaTeX (Span (id',classes,_) ils) = do
659662 let noEmph = "csl-no-emph" `elem` classes
660663 let noStrong = "csl-no-strong" `elem` classes
661664 let noSmallCaps = "csl-no-smallcaps" `elem` classes
662− let label' = if (null id')
663− then empty
664− else text "\\label" <> braces (text $ toLabel id')
665+ label' <- if null id'
666+ then return empty
667+ else toLabel id' >>= \x ->
668+ return (text "\\label" <> braces (text x))
665669 fmap (label' <>)
666670 ((if noEmph then inCmd "textup" else id) .
667671 (if noStrong then inCmd "textnormal" else id) .
@@ -745,9 +749,8 @@ inlineToLaTeX (LineBreak) = return "\\\\"
745749inlineToLaTeX Space = return space
746750inlineToLaTeX (Link txt ('#':ident, _)) = do
747751 contents <- inlineListToLaTeX txt
748− ident' <- stringToLaTeX URLString ident
749− return $ text "\\hyperref" <> brackets (text $ toLabel ident') <>
750− braces contents
752+ lab <- toLabel ident
753+ return $ text "\\hyperref" <> brackets (text lab) <> braces contents
751754inlineToLaTeX (Link txt (src, _)) =
752755 case txt of
753756 [Str x] | x == src -> -- autolink