Fix literal use of babel shorthands (straight quote, tilde, ...).
[docutils.git] / test / test_writers / test_latex2e.py
blobd7b6223f8ddcfec205d05093e73455f043c9f323
1 # -*- coding: utf8 -*-
2 #! /usr/bin/env python
4 # $Id$
5 # Author: engelbert gruber <grubert@users.sourceforge.net>
6 # Copyright: This module has been placed in the public domain.
8 """
9 Tests for latex2e writer.
10 """
12 import string
13 from __init__ import DocutilsTestSupport
15 def suite():
16 settings = {'use_latex_toc': False}
17 s = DocutilsTestSupport.PublishTestSuite('latex', suite_settings=settings)
18 s.generateTests(totest)
19 settings['use_latex_toc'] = True
20 s.generateTests(totest_latex_toc)
21 settings['use_latex_toc'] = False
22 settings['sectnum_xform'] = False
23 s.generateTests(totest_latex_sectnum)
24 settings['sectnum_xform'] = True
25 settings['use_latex_citations'] = True
26 s.generateTests(totest_latex_citations)
27 settings['stylesheet_path'] = 'data/spam,data/ham.tex'
28 s.generateTests(totest_stylesheet)
29 settings['embed_stylesheet'] = True
30 settings['warning_stream'] = ''
31 s.generateTests(totest_stylesheet_embed)
32 return s
34 head_template = string.Template(
35 r"""$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
36 \usepackage{fixltx2e} % LaTeX patches, \textsubscript
37 \usepackage{cmap} % fix search and cut-and-paste in Acrobat
38 $requirements
39 %%% Custom LaTeX preamble
40 $latex_preamble
41 %%% User specified packages and stylesheets
42 $stylesheet
43 %%% Fallback definitions for Docutils-specific commands
44 $fallbacks$pdfsetup
45 $titledata
46 %%% Body
47 \begin{document}
48 """)
50 parts = dict(
51 head_prefix = r"""\documentclass[a4paper]{article}
52 """,
53 requirements = r"""\usepackage{ifthen}
54 \usepackage[T1]{fontenc}
55 \usepackage[utf8]{inputenc}
56 """,
57 latex_preamble = r"""% PDF Standard Fonts
58 \usepackage{mathptmx} % Times
59 \usepackage[scaled=.90]{helvet}
60 \usepackage{courier}
61 """,
62 stylesheet = '',
63 fallbacks = '',
64 pdfsetup = r"""
65 % hyperlinks:
66 \ifthenelse{\isundefined{\hypersetup}}{
67 \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
68 \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
69 }{}
70 """,
71 titledata = '')
73 head = head_template.substitute(parts)
75 head_table = head_template.substitute(
76 dict(parts, requirements = parts['requirements'] +
77 r"""\usepackage{longtable,ltcaption,array}
78 \setlength{\extrarowheight}{2pt}
79 \newlength{\DUtablewidth} % internal use in tables
80 """))
82 head_textcomp = head_template.substitute(
83 dict(parts, requirements = parts['requirements'] +
84 r"""\usepackage{textcomp} % text symbol macros
85 """))
87 totest = {}
88 totest_latex_toc = {}
89 totest_latex_sectnum = {}
90 totest_latex_citations = {}
91 totest_stylesheet = {}
92 totest_stylesheet_embed = {}
94 totest['url_chars'] = [
95 ["http://nowhere/url_with%28parens%29",
96 head + r"""
97 \url{http://nowhere/url_with\%28parens\%29}
99 \end{document}
100 """],
103 totest['textcomp'] = [
104 ["2 µm is just 2/1000000 m",
105 head_textcomp + r"""
106 2 µm is just 2/1000000 m
108 \end{document}
109 """],
112 totest['spanish quote'] = [
113 [".. role:: language-es\n\nUnd damit :language-es:`basta`!",
114 head_template.substitute(dict(parts, requirements =
115 r"""\usepackage{ifthen}
116 \usepackage[T1]{fontenc}
117 \usepackage[utf8]{inputenc}
118 \usepackage[spanish,english]{babel}
119 \AtBeginDocument{\shorthandoff{.<>}}
120 """)) + r"""
121 Und damit \foreignlanguage{spanish}{basta}!
123 \end{document}
124 """],
127 totest['table_of_contents'] = [
128 # input
129 ["""\
130 .. contents:: Table of Contents
132 Title 1
133 =======
134 Paragraph 1.
136 Title 2
137 -------
138 Paragraph 2.
139 """,
140 ## # expected output
141 head_template.substitute(dict(parts,
142 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n',
143 fallbacks=r"""
144 % title for topics, admonitions, unsupported section levels, and sidebar
145 \providecommand*{\DUtitle}[2][class-arg]{%
146 % call \DUtitle#1{#2} if it exists:
147 \ifcsname DUtitle#1\endcsname%
148 \csname DUtitle#1\endcsname{#2}%
149 \else
150 \smallskip\noindent\textbf{#2}\smallskip%
153 """)) + r"""
154 \phantomsection\label{table-of-contents}
155 \pdfbookmark[1]{Table of Contents}{table-of-contents}
156 \DUtitle[contents]{Table of Contents}
158 \begin{list}{}{}
160 \item \hyperref[title-1]{Title 1}
162 \begin{list}{}{}
164 \item \hyperref[title-2]{Title 2}
166 \end{list}
168 \end{list}
171 \section{Title 1%
172 \label{title-1}%
175 Paragraph 1.
178 \subsection{Title 2%
179 \label{title-2}%
182 Paragraph 2.
184 \end{document}
185 """],
189 totest_latex_toc['no_sectnum'] = [
190 # input
191 ["""\
192 .. contents::
194 first section
195 -------------
196 """,
197 ## # expected output
198 head_template.substitute(dict(parts,
199 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n'
200 )) + r"""
201 \phantomsection\label{contents}
202 \pdfbookmark[1]{Contents}{contents}
203 \tableofcontents
207 \section{first section%
208 \label{first-section}%
211 \end{document}
212 """],
215 totest_latex_toc['sectnum'] = [
216 # input
217 ["""\
218 .. contents::
219 .. sectnum::
221 first section
222 -------------
223 """,
224 ## # expected output
225 head_template.substitute(dict(parts,
226 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n'
227 )) + r"""
228 \phantomsection\label{contents}
229 \pdfbookmark[1]{Contents}{contents}
230 \tableofcontents
234 \section{1~~~first section%
235 \label{first-section}%
238 \end{document}
239 """],
243 totest_latex_sectnum['no_sectnum'] = [
244 # input
245 ["""\
246 some text
248 first section
249 -------------
250 """,
251 ## # expected output
252 head_template.substitute(dict(parts, requirements = parts['requirements'] +
253 r"""\setcounter{secnumdepth}{0}
254 """)) + r"""
255 some text
258 \section{first section%
259 \label{first-section}%
262 \end{document}
263 """],
266 totest_latex_sectnum['sectnum'] = [
267 # input
268 ["""\
269 .. sectnum::
271 some text
273 first section
274 -------------
275 """,
276 ## # expected output
277 head_template.substitute(dict(parts,
278 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n'
279 )) + r"""
280 some text
283 \section{first section%
284 \label{first-section}%
287 \end{document}
288 """],
291 totest_latex_citations['citations_with_underscore'] = [
292 # input
293 ["""\
294 Just a test citation [my_cite2006]_.
296 .. [my_cite2006]
297 The underscore is mishandled.
298 """,
299 ## # expected output
300 head + r"""
301 Just a test citation \cite{my_cite2006}.
303 \begin{thebibliography}{my\_cite2006}
304 \bibitem[my\_cite2006]{my_cite2006}{
305 The underscore is mishandled.
307 \end{thebibliography}
309 \end{document}
310 """],
314 totest_latex_citations['adjacent_citations'] = [
315 # input
316 ["""\
317 Two non-citations: [MeYou2007]_[YouMe2007]_.
319 Need to be separated for grouping: [MeYou2007]_ [YouMe2007]_.
321 Two spaces (or anything else) for no grouping: [MeYou2007]_ [YouMe2007]_.
323 But a line break should work: [MeYou2007]_
324 [YouMe2007]_.
326 .. [MeYou2007] not.
327 .. [YouMe2007] important.
328 """,
329 # expected output
330 head + r"""
331 Two non-citations: {[}MeYou2007{]}\_{[}YouMe2007{]}\_.
333 Need to be separated for grouping: \cite{MeYou2007,YouMe2007}.
335 Two spaces (or anything else) for no grouping: \cite{MeYou2007} \cite{YouMe2007}.
337 But a line break should work: \cite{MeYou2007,YouMe2007}.
339 \begin{thebibliography}{MeYou2007}
340 \bibitem[MeYou2007]{MeYou2007}{
341 not.
343 \bibitem[YouMe2007]{YouMe2007}{
344 important.
346 \end{thebibliography}
348 \end{document}
349 """],
353 totest['enumerated_lists'] = [
354 # input
355 ["""\
356 1. Item 1.
357 2. Second to the previous item this one will explain
359 a) nothing.
360 b) or some other.
362 3. Third is
364 (I) having pre and postfixes
365 (II) in roman numerals.
366 """,
367 # expected output
368 head + r"""\newcounter{listcnt0}
369 \begin{list}{\arabic{listcnt0}.}
371 \usecounter{listcnt0}
372 \setlength{\rightmargin}{\leftmargin}
375 \item Item 1.
377 \item Second to the previous item this one will explain
378 \end{list}
380 \begin{quote}
381 \setcounter{listcnt0}{0}
382 \begin{list}{\alph{listcnt0})}
384 \usecounter{listcnt0}
385 \setlength{\rightmargin}{\leftmargin}
388 \item nothing.
390 \item or some other.
391 \end{list}
393 \end{quote}
394 \setcounter{listcnt0}{0}
395 \begin{list}{\arabic{listcnt0}.}
397 \usecounter{listcnt0}
398 \addtocounter{listcnt0}{2}
399 \setlength{\rightmargin}{\leftmargin}
402 \item Third is
403 \end{list}
405 \begin{quote}
406 \setcounter{listcnt0}{0}
407 \begin{list}{(\Roman{listcnt0})}
409 \usecounter{listcnt0}
410 \setlength{\rightmargin}{\leftmargin}
413 \item having pre and postfixes
415 \item in roman numerals.
416 \end{list}
418 \end{quote}
420 \end{document}
421 """],
424 # TODO: need to test for quote replacing if the language uses "ASCII-quotes"
425 # as active character (e.g. de (ngerman)).
428 totest['table_caption'] = [
429 # input
430 ["""\
431 .. table:: Foo
433 +-----+-----+
434 | | |
435 +-----+-----+
436 | | |
437 +-----+-----+
438 """,
439 head_table + r"""
440 \setlength{\DUtablewidth}{\linewidth}
441 \begin{longtable}[c]{|p{0.075\DUtablewidth}|p{0.075\DUtablewidth}|}
442 \caption{Foo}\\
443 \hline
444 & \\
445 \hline
446 & \\
447 \hline
448 \end{longtable}
450 \end{document}
451 """],
454 totest['table_class'] = [
455 # input
456 ["""\
457 .. table::
458 :class: borderless
460 +-----+-----+
461 | 1 | 2 |
462 +-----+-----+
463 | 3 | 4 |
464 +-----+-----+
465 """,
466 head_table + r"""
467 \setlength{\DUtablewidth}{\linewidth}
468 \begin{longtable*}[c]{p{0.075\DUtablewidth}p{0.075\DUtablewidth}}
479 \end{longtable*}
481 \end{document}
482 """],
485 # The "[" needs to be protected (otherwise it will be seen as an
486 # option to "\\", "\item", etc. ).
488 totest['brackett_protection'] = [
489 # input
490 ["""\
493 something before to get a end of line.
496 the empty line gets tested too
498 """,
499 head + r"""%
500 \begin{quote}{\ttfamily \raggedright \noindent
501 something~before~to~get~a~end~of~line.\\
502 {[}\\
504 the~empty~line~gets~tested~too\\
507 \end{quote}
509 \end{document}
510 """],
513 totest['raw'] = [
514 [r""".. raw:: latex
516 $E=mc^2$
518 A paragraph.
520 .. |sub| raw:: latex
522 (some raw text)
524 Foo |sub|
525 same paragraph.
526 """,
527 head + r"""
528 $E=mc^2$
530 A paragraph.
532 Foo (some raw text)
533 same paragraph.
535 \end{document}
536 """],
539 totest['title_with_inline_markup'] = [
540 ["""\
541 This is the *Title*
542 ===================
544 This is the *Subtitle*
545 ----------------------
547 This is a *section title*
548 ~~~~~~~~~~~~~~~~~~~~~~~~~
550 This is the *document*.
551 """,
552 head_template.substitute(dict(parts,
553 requirements=parts['requirements'] + '\\setcounter{secnumdepth}{0}\n',
554 pdfsetup=parts['pdfsetup'] + r"""\hypersetup{
555 pdftitle={This is the Title},
557 """, titledata=r"""%%% Title Data
558 \title{\phantomsection%
559 This is the \emph{Title}%
560 \label{this-is-the-title}%
561 \\ % subtitle%
562 \large{This is the \emph{Subtitle}}%
563 \label{this-is-the-subtitle}}
564 \author{}
565 \date{}
566 """)) + r"""\maketitle
569 \section{This is a \emph{section title}%
570 \label{this-is-a-section-title}%
573 This is the \emph{document}.
575 \end{document}
576 """],
579 totest_stylesheet['two-styles'] = [
580 # input
581 ["""two stylesheet links in the header""",
582 head_template.substitute(dict(parts, stylesheet =
583 r"""\usepackage{data/spam}
584 \input{data/ham.tex}
585 """)) + r"""
586 two stylesheet links in the header
588 \end{document}
589 """],
592 totest_stylesheet_embed['two-styles'] = [
593 # input
594 ["""two stylesheets embedded in the header""",
595 head_template.substitute(dict(parts, stylesheet =
596 r"""% Cannot embed stylesheet 'data/spam.sty':
597 % No such file or directory.
598 % embedded stylesheet: data/ham.tex
599 \newcommand{\ham}{wonderful ham}
601 """)) + r"""
602 two stylesheets embedded in the header
604 \end{document}
605 """],
608 if __name__ == '__main__':
609 import unittest
610 unittest.main(defaultTest='suite')