git.iko.soy/typeable/pandoc
on master help sign in
Added writerTeXLigatures to WriterOptions, `--no-tex-ligatures` option.
5f889b9John MacFarlane
README+12−1
@@ -213,7 +213,7 @@ Reader options
213 abbreviations, such as "Mr." (Note: This option is significant only when
213 abbreviations, such as "Mr." (Note: This option is significant only when
214 the input format is `markdown` or `textile`. It is selected automatically
214 the input format is `markdown` or `textile`. It is selected automatically
215 when the input format is `textile` or the output format is `latex` or
215 when the input format is `textile` or the output format is `latex` or
216− `context`.)
216+ `context`, unless `--no-tex-ligatures` is used.)
217
217
218`--old-dashes`
218`--old-dashes`
219: Selects the pandoc <= 1.8.2.1 behavior for parsing smart dashes: `-` before
219: Selects the pandoc <= 1.8.2.1 behavior for parsing smart dashes: `-` before
@@ -358,6 +358,17 @@ Options affecting specific writers
358: Number section headings in LaTeX, ConTeXt, or HTML output.
358: Number section headings in LaTeX, ConTeXt, or HTML output.
359 By default, sections are not numbered.
359 By default, sections are not numbered.
360
360
361+`--no-tex-ligatures`
362+: Do not convert quotation marks, apostrophes, and dashes to
363+ the TeX ligatures when writing LaTeX or ConTeXt. Instead, just
364+ use literal unicode characters. This is needed for using advanced
365+ OpenType features with XeLaTeX and LuaLaTeX. Note: normally
366+ `--smart` is selected automatically for LaTeX and ConTeXt
367+ output, but it must be specified explicitly if `--no-tex-ligatures`
368+ is selected. If you use literal curly quotes, dashes, and ellipses
369+ in your source, then you may want to use `--no-tex-ligatures`
370+ without `--smart`.
371+
361`--listings`
372`--listings`
362: Use listings package for LaTeX code blocks
373: Use listings package for LaTeX code blocks
363
374
changelog+2
@@ -43,6 +43,8 @@ pandoc (1.9.3)
43
43
44 * LaTeX writer:
44 * LaTeX writer:
45
45
46+ + Added `--no-tex-ligatures` option to avoid replacing
47+ quotation marks and dashes with TeX ligatures.
46 + Use `fixltx2e` package to provide '\textsubscript'.
48 + Use `fixltx2e` package to provide '\textsubscript'.
47 + Improve spacing around LaTeX block environments:
49 + Improve spacing around LaTeX block environments:
48 quote, verbatim, itemize, description, enumerate.
50 quote, verbatim, itemize, description, enumerate.
src/Text/Pandoc/Shared.hs+2
@@ -520,6 +520,7 @@ data WriterOptions = WriterOptions
520 , writerHighlight :: Bool -- ^ Highlight source code
520 , writerHighlight :: Bool -- ^ Highlight source code
521 , writerHighlightStyle :: Style -- ^ Style to use for highlighting
521 , writerHighlightStyle :: Style -- ^ Style to use for highlighting
522 , writerSetextHeaders :: Bool -- ^ Use setext headers for levels 1-2 in markdown
522 , writerSetextHeaders :: Bool -- ^ Use setext headers for levels 1-2 in markdown
523+ , writerTeXLigatures :: Bool -- ^ Use tex ligatures quotes, dashes in latex
523 } deriving Show
524 } deriving Show
524
525
525{-# DEPRECATED writerXeTeX "writerXeTeX no longer does anything" #-}
526{-# DEPRECATED writerXeTeX "writerXeTeX no longer does anything" #-}
@@ -558,6 +559,7 @@ defaultWriterOptions =
558 , writerHighlight = False
559 , writerHighlight = False
559 , writerHighlightStyle = pygments
560 , writerHighlightStyle = pygments
560 , writerSetextHeaders = True
561 , writerSetextHeaders = True
562+ , writerTeXLigatures = True
561 }
563 }
562
564
563--
565--
src/Text/Pandoc/Writers/ConTeXt.hs+14−10
@@ -86,8 +86,9 @@ pandocToConTeXt options (Pandoc (Meta title authors date) blocks) = do
86
86
87-- escape things as needed for ConTeXt
87-- escape things as needed for ConTeXt
88
88
89−escapeCharForConTeXt :: Char -> String
89+escapeCharForConTeXt :: WriterOptions -> Char -> String
90−escapeCharForConTeXt ch =
90+escapeCharForConTeXt opts ch =
91+ let ligatures = writerTeXLigatures opts in
91 case ch of
92 case ch of
92 '{' -> "\\letteropenbrace{}"
93 '{' -> "\\letteropenbrace{}"
93 '}' -> "\\letterclosebrace{}"
94 '}' -> "\\letterclosebrace{}"
@@ -105,15 +106,15 @@ escapeCharForConTeXt ch =
105 ']' -> "{]}"
106 ']' -> "{]}"
106 '_' -> "\\letterunderscore{}"
107 '_' -> "\\letterunderscore{}"
107 '\160' -> "~"
108 '\160' -> "~"
108− '\x2014' -> "---"
109+ '\x2014' | ligatures -> "---"
109− '\x2013' -> "--"
110+ '\x2013' | ligatures -> "--"
110− '\x2019' -> "'"
111+ '\x2019' | ligatures -> "'"
111 '\x2026' -> "\\ldots{}"
112 '\x2026' -> "\\ldots{}"
112 x -> [x]
113 x -> [x]
113
114
114-- | Escape string for ConTeXt
115-- | Escape string for ConTeXt
115−stringToConTeXt :: String -> String
116+stringToConTeXt :: WriterOptions -> String -> String
116−stringToConTeXt = concatMap escapeCharForConTeXt
117+stringToConTeXt opts = concatMap (escapeCharForConTeXt opts)
117
118
118-- | Convert Elements to ConTeXt
119-- | Convert Elements to ConTeXt
119elementToConTeXt :: WriterOptions -> Element -> State WriterState Doc
120elementToConTeXt :: WriterOptions -> Element -> State WriterState Doc
@@ -254,8 +255,9 @@ inlineToConTeXt (SmallCaps lst) = do
254 return $ braces $ "\\sc " <> contents
255 return $ braces $ "\\sc " <> contents
255inlineToConTeXt (Code _ str) | not ('{' `elem` str || '}' `elem` str) =
256inlineToConTeXt (Code _ str) | not ('{' `elem` str || '}' `elem` str) =
256 return $ "\\type" <> braces (text str)
257 return $ "\\type" <> braces (text str)
257−inlineToConTeXt (Code _ str) =
258+inlineToConTeXt (Code _ str) = do
259+ opts <- gets stOptions
258− return $ "\\mono" <> braces (text $ stringToConTeXt str)
260+ return $ "\\mono" <> braces (text $ stringToConTeXt opts str)
259inlineToConTeXt (Quoted SingleQuote lst) = do
261inlineToConTeXt (Quoted SingleQuote lst) = do
260 contents <- inlineListToConTeXt lst
262 contents <- inlineListToConTeXt lst
261 return $ "\\quote" <> braces contents
263 return $ "\\quote" <> braces contents
@@ -263,7 +265,9 @@ inlineToConTeXt (Quoted DoubleQuote lst) = do
263 contents <- inlineListToConTeXt lst
265 contents <- inlineListToConTeXt lst
264 return $ "\\quotation" <> braces contents
266 return $ "\\quotation" <> braces contents
265inlineToConTeXt (Cite _ lst) = inlineListToConTeXt lst
267inlineToConTeXt (Cite _ lst) = inlineListToConTeXt lst
268+inlineToConTeXt (Str str) = do
269+ opts <- gets stOptions
266−inlineToConTeXt (Str str) = return $ text $ stringToConTeXt str
270+ return $ text $ stringToConTeXt opts str
267inlineToConTeXt (Math InlineMath str) =
271inlineToConTeXt (Math InlineMath str) =
268 return $ char '$' <> text str <> char '$'
272 return $ char '$' <> text str <> char '$'
269inlineToConTeXt (Math DisplayMath str) =
273inlineToConTeXt (Math DisplayMath str) =
src/Text/Pandoc/Writers/LaTeX.hs+23−24
@@ -174,9 +174,11 @@ elementToLaTeX opts (Sec level _ id' title' elements) = do
174
174
175-- escape things as needed for LaTeX
175-- escape things as needed for LaTeX
176stringToLaTeX :: Bool -> String -> State WriterState String
176stringToLaTeX :: Bool -> String -> State WriterState String
177−stringToLaTeX _ [] = return ""
177+stringToLaTeX _ [] = return ""
178−stringToLaTeX isUrl (x:xs) = do
178+stringToLaTeX isUrl (x:xs) = do
179+ opts <- gets stOptions
179 rest <- stringToLaTeX isUrl xs
180 rest <- stringToLaTeX isUrl xs
181+ let ligatures = writerTeXLigatures opts
180 when (x == '€') $
182 when (x == '€') $
181 modify $ \st -> st{ stUsesEuro = True }
183 modify $ \st -> st{ stUsesEuro = True }
182 return $
184 return $
@@ -201,13 +203,13 @@ stringToLaTeX isUrl (x:xs) = do
201 '[' -> "{[}" ++ rest -- to avoid interpretation as
203 '[' -> "{[}" ++ rest -- to avoid interpretation as
202 ']' -> "{]}" ++ rest -- optional arguments
204 ']' -> "{]}" ++ rest -- optional arguments
203 '\160' -> "~" ++ rest
205 '\160' -> "~" ++ rest
204− '\x2018' -> "`" ++ rest
205− '\x2019' -> "'" ++ rest
206− '\x201C' -> "``" ++ rest
207− '\x201D' -> "''" ++ rest
208 '\x2026' -> "\\ldots{}" ++ rest
206 '\x2026' -> "\\ldots{}" ++ rest
207+ '\x2018' | ligatures -> "`" ++ rest
208+ '\x2019' | ligatures -> "'" ++ rest
209+ '\x201C' | ligatures -> "``" ++ rest
210+ '\x201D' | ligatures -> "''" ++ rest
209− '\x2014' -> "---" ++ rest
211+ '\x2014' | ligatures -> "---" ++ rest
210− '\x2013' -> "--" ++ rest
212+ '\x2013' | ligatures -> "--" ++ rest
211 _ -> x : rest
213 _ -> x : rest
212
214
213-- | Puts contents into LaTeX command.
215-- | Puts contents into LaTeX command.
@@ -536,23 +538,11 @@ inlineToLaTeX (Code (_,classes,_) str) = do
536 Just h -> modify (\st -> st{ stHighlighting = True }) >>
538 Just h -> modify (\st -> st{ stHighlighting = True }) >>
537 return (text h)
539 return (text h)
538 rawCode = liftM (text . (\s -> "\\texttt{" ++ s ++ "}"))
540 rawCode = liftM (text . (\s -> "\\texttt{" ++ s ++ "}"))
539− $ stringToLaTeX False str
541+ $ stringToLaTeX False str
540−inlineToLaTeX (Quoted SingleQuote lst) = do
542+inlineToLaTeX (Quoted qt lst) = do
541− contents <- inlineListToLaTeX lst
542− csquotes <- liftM stCsquotes get
543− if csquotes
544− then return $ "\\enquote" <> braces contents
545− else do
546− let s1 = if (not (null lst)) && (isQuoted (head lst))
547− then "\\,"
548− else empty
549− let s2 = if (not (null lst)) && (isQuoted (last lst))
550− then "\\,"
551− else empty
552− return $ char '`' <> s1 <> contents <> s2 <> char '\''
553−inlineToLaTeX (Quoted DoubleQuote lst) = do
554 contents <- inlineListToLaTeX lst
543 contents <- inlineListToLaTeX lst
555 csquotes <- liftM stCsquotes get
544 csquotes <- liftM stCsquotes get
545+ opts <- gets stOptions
556 if csquotes
546 if csquotes
557 then return $ "\\enquote" <> braces contents
547 then return $ "\\enquote" <> braces contents
558 else do
548 else do
@@ -562,7 +552,16 @@ inlineToLaTeX (Quoted DoubleQuote lst) = do
562 let s2 = if (not (null lst)) && (isQuoted (last lst))
552 let s2 = if (not (null lst)) && (isQuoted (last lst))
563 then "\\,"
553 then "\\,"
564 else empty
554 else empty
565− return $ "``" <> s1 <> contents <> s2 <> "''"
555+ let inner = s1 <> contents <> s2
556+ return $ case qt of
557+ DoubleQuote ->
558+ if writerTeXLigatures opts
559+ then text "``" <> inner <> text "''"
560+ else char '\x201C' <> inner <> char '\x201D'
561+ SingleQuote ->
562+ if writerTeXLigatures opts
563+ then char '`' <> inner <> char '\''
564+ else char '\x2018' <> inner <> char '\x2019'
566inlineToLaTeX (Str str) = liftM text $ stringToLaTeX False str
565inlineToLaTeX (Str str) = liftM text $ stringToLaTeX False str
567inlineToLaTeX (Math InlineMath str) = return $ char '$' <> text str <> char '$'
566inlineToLaTeX (Math InlineMath str) = return $ char '$' <> text str <> char '$'
568inlineToLaTeX (Math DisplayMath str) = return $ "\\[" <> text str <> "\\]"
567inlineToLaTeX (Math DisplayMath str) = return $ "\\[" <> text str <> "\\]"
src/pandoc.hs+12−2
@@ -135,6 +135,7 @@ data Opt = Opt
135 , optSlideLevel :: Maybe Int -- ^ Header level that creates slides
135 , optSlideLevel :: Maybe Int -- ^ Header level that creates slides
136 , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2
136 , optSetextHeaders :: Bool -- ^ Use atx headers for markdown level 1-2
137 , optAscii :: Bool -- ^ Use ascii characters only in html
137 , optAscii :: Bool -- ^ Use ascii characters only in html
138+ , optTeXLigatures :: Bool -- ^ Use TeX ligatures for quotes/dashes
138 }
139 }
139
140
140-- | Defaults for command-line options.
141-- | Defaults for command-line options.
@@ -187,6 +188,7 @@ defaultOpts = Opt
187 , optSlideLevel = Nothing
188 , optSlideLevel = Nothing
188 , optSetextHeaders = True
189 , optSetextHeaders = True
189 , optAscii = False
190 , optAscii = False
191+ , optTeXLigatures = True
190 }
192 }
191
193
192-- | A list of functions, each transforming the options data structure
194-- | A list of functions, each transforming the options data structure
@@ -438,6 +440,11 @@ options =
438 (\opt -> return opt { optNumberSections = True }))
440 (\opt -> return opt { optNumberSections = True }))
439 "" -- "Number sections in LaTeX"
441 "" -- "Number sections in LaTeX"
440
442
443+ , Option "" ["no-tex-ligatures"]
444+ (NoArg
445+ (\opt -> return opt { optTeXLigatures = False }))
446+ "" -- "Don't use tex ligatures for quotes, dashes"
447+
441 , Option "" ["listings"]
448 , Option "" ["listings"]
442 (NoArg
449 (NoArg
443 (\opt -> return opt { optListings = True }))
450 (\opt -> return opt { optListings = True }))
@@ -804,6 +811,7 @@ main = do
804 , optSlideLevel = slideLevel
811 , optSlideLevel = slideLevel
805 , optSetextHeaders = setextHeaders
812 , optSetextHeaders = setextHeaders
806 , optAscii = ascii
813 , optAscii = ascii
814+ , optTeXLigatures = texLigatures
807 } = opts
815 } = opts
808
816
809 when dumpArgs $
817 when dumpArgs $
@@ -918,7 +926,8 @@ main = do
918 lhsExtension sources,
926 lhsExtension sources,
919 stateStandalone = standalone',
927 stateStandalone = standalone',
920 stateCitations = map CSL.refId refs,
928 stateCitations = map CSL.refId refs,
929+ stateSmart = smart || (texLigatures &&
921− stateSmart = smart || laTeXOutput || writerName' == "context",
930+ (laTeXOutput || writerName' == "context")),
922 stateOldDashes = oldDashes,
931 stateOldDashes = oldDashes,
923 stateColumns = columns,
932 stateColumns = columns,
924 stateStrict = strict,
933 stateStrict = strict,
@@ -961,7 +970,8 @@ main = do
961 writerSlideLevel = slideLevel,
970 writerSlideLevel = slideLevel,
962 writerHighlight = highlight,
971 writerHighlight = highlight,
963 writerHighlightStyle = highlightStyle,
972 writerHighlightStyle = highlightStyle,
964− writerSetextHeaders = setextHeaders
973+ writerSetextHeaders = setextHeaders,
974+ writerTeXLigatures = texLigatures
965 }
975 }
966
976
967 when (writerName' `elem` nonTextFormats&& outputFile == "-") $
977 when (writerName' `elem` nonTextFormats&& outputFile == "-") $