Fix handling of missing stylesheets. Updated and simplied tests.
[docutils.git] / test / test_writers / test_latex2e.py
blob9f04f1f33db0bf4a58ac98e5d273f19cf00bd97f
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 # compatibility module for Python 2.3
14 if not hasattr(string, 'Template'):
15 import docutils._string_template_compat
16 string.Template = docutils._string_template_compat.Template
18 from __init__ import DocutilsTestSupport
20 def suite():
21 settings = {'use_latex_toc': False}
22 s = DocutilsTestSupport.PublishTestSuite('latex', suite_settings=settings)
23 s.generateTests(totest)
24 settings['use_latex_toc'] = True
25 s.generateTests(totest_latex_toc)
26 settings['use_latex_toc'] = False
27 settings['sectnum_xform'] = False
28 s.generateTests(totest_latex_sectnum)
29 settings['sectnum_xform'] = True
30 settings['use_latex_citations'] = True
31 s.generateTests(totest_latex_citations)
32 settings['stylesheet_path'] = 'data/spam,data/ham.tex'
33 s.generateTests(totest_stylesheet)
34 settings['embed_stylesheet'] = True
35 settings['warning_stream'] = ''
36 s.generateTests(totest_stylesheet_embed)
37 return s
39 head_template = string.Template(
40 r"""$head_prefix% generated by Docutils <http://docutils.sourceforge.net/>
41 \usepackage{fixltx2e} % LaTeX patches, \textsubscript
42 \usepackage{cmap} % fix search and cut-and-paste in Acrobat
43 $requirements
44 %%% Custom LaTeX preamble
45 $latex_preamble
46 %%% User specified packages and stylesheets
47 $stylesheet
48 %%% Fallback definitions for Docutils-specific commands
49 $fallbacks$pdfsetup
50 $titledata
51 %%% Body
52 \begin{document}
53 """)
55 parts = dict(
56 head_prefix = r"""\documentclass[a4paper]{article}
57 """,
58 requirements = r"""\usepackage{ifthen}
59 \usepackage[T1]{fontenc}
60 \usepackage[utf8]{inputenc}
61 """,
62 latex_preamble = r"""% PDF Standard Fonts
63 \usepackage{mathptmx} % Times
64 \usepackage[scaled=.90]{helvet}
65 \usepackage{courier}
66 """,
67 stylesheet = '',
68 fallbacks = '',
69 pdfsetup = r"""
70 % hyperlinks:
71 \ifthenelse{\isundefined{\hypersetup}}{
72 \usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
73 \urlstyle{same} % normal text font (alternatives: tt, rm, sf)
74 }{}
75 """,
76 titledata = '')
78 head = head_template.substitute(parts)
80 head_table = head_template.substitute(
81 dict(parts, requirements = parts['requirements'] +
82 r"""\usepackage{longtable,ltcaption,array}
83 \setlength{\extrarowheight}{2pt}
84 \newlength{\DUtablewidth} % internal use in tables
85 """))
87 head_textcomp = head_template.substitute(
88 dict(parts, requirements = parts['requirements'] +
89 r"""\usepackage{textcomp} % text symbol macros
90 """))
92 totest = {}
93 totest_latex_toc = {}
94 totest_latex_sectnum = {}
95 totest_latex_citations = {}
96 totest_stylesheet = {}
97 totest_stylesheet_embed = {}
99 totest['url_chars'] = [
100 ["http://nowhere/url_with%28parens%29",
101 head + r"""
102 \url{http://nowhere/url_with\%28parens\%29}
104 \end{document}
105 """],
108 totest['textcomp'] = [
109 ["2 µm is just 2/1000000 m",
110 head_textcomp + r"""
111 2 µm is just 2/1000000 m
113 \end{document}
114 """],
117 totest['spanish quote'] = [
118 [".. role:: language-es\n\nUnd damit :language-es:`basta`!",
119 head_template.substitute(dict(parts, requirements =
120 r"""\usepackage{ifthen}
121 \usepackage[T1]{fontenc}
122 \usepackage[utf8]{inputenc}
123 \usepackage[spanish,english]{babel}
124 \addto\shorthandsspanish{\spanishdeactivate{."~<>}}
125 """)) + r"""
126 Und damit \otherlanguage{spanish}{basta}!
128 \end{document}
129 """],
132 totest['table_of_contents'] = [
133 # input
134 ["""\
135 .. contents:: Table of Contents
137 Title 1
138 =======
139 Paragraph 1.
141 Title 2
142 -------
143 Paragraph 2.
144 """,
145 ## # expected output
146 head_template.substitute(dict(parts, fallbacks = r"""
147 % title for topics, admonitions and sidebar
148 \providecommand*{\DUtitle}[2][class-arg]{%
149 % call \DUtitle#1{#2} if it exists:
150 \ifcsname DUtitle#1\endcsname%
151 \csname DUtitle#1\endcsname{#2}%
152 \else
153 \smallskip\noindent\textbf{#2}\smallskip%
156 """)) + r"""
157 \phantomsection\label{table-of-contents}
158 \pdfbookmark[1]{Table of Contents}{table-of-contents}
159 \DUtitle[contents]{Table of Contents}
161 \begin{list}{}{}
163 \item \hyperref[title-1]{Title 1}
165 \begin{list}{}{}
167 \item \hyperref[title-2]{Title 2}
169 \end{list}
171 \end{list}
174 %___________________________________________________________________________
176 \section*{\phantomsection%
177 Title 1%
178 \addcontentsline{toc}{section}{Title 1}%
179 \label{title-1}%
182 Paragraph 1.
185 %___________________________________________________________________________
187 \subsection*{\phantomsection%
188 Title 2%
189 \addcontentsline{toc}{subsection}{Title 2}%
190 \label{title-2}%
193 Paragraph 2.
195 \end{document}
196 """],
200 totest_latex_toc['no_sectnum'] = [
201 # input
202 ["""\
203 .. contents::
205 first section
206 -------------
207 """,
208 ## # expected output
209 head + r"""
210 \phantomsection\label{contents}
211 \pdfbookmark[1]{Contents}{contents}
212 \tableofcontents
216 %___________________________________________________________________________
218 \section*{\phantomsection%
219 first section%
220 \addcontentsline{toc}{section}{first section}%
221 \label{first-section}%
224 \end{document}
225 """],
228 totest_latex_toc['sectnum'] = [
229 # input
230 ["""\
231 .. contents::
232 .. sectnum::
234 first section
235 -------------
236 """,
237 ## # expected output
238 head + r"""
239 \phantomsection\label{contents}
240 \pdfbookmark[1]{Contents}{contents}
241 \tableofcontents
245 %___________________________________________________________________________
247 \section*{\phantomsection%
248 1~~~first section%
249 \addcontentsline{toc}{section}{1~~~first section}%
250 \label{first-section}%
253 \end{document}
254 """],
258 totest_latex_sectnum['no_sectnum'] = [
259 # input
260 ["""\
261 some text
263 first section
264 -------------
265 """,
266 ## # expected output
267 head_template.substitute(dict(parts, requirements = parts['requirements'] +
268 r"""\setcounter{secnumdepth}{0}
269 """)) + r"""
270 some text
273 %___________________________________________________________________________
275 \section{first section%
276 \label{first-section}%
279 \end{document}
280 """],
283 totest_latex_sectnum['sectnum'] = [
284 # input
285 ["""\
286 .. sectnum::
288 some text
290 first section
291 -------------
292 """,
293 ## # expected output
294 head + r"""
295 some text
298 %___________________________________________________________________________
300 \section{first section%
301 \label{first-section}%
304 \end{document}
305 """],
308 totest_latex_citations['citations_with_underscore'] = [
309 # input
310 ["""\
311 Just a test citation [my_cite2006]_.
313 .. [my_cite2006]
314 The underscore is mishandled.
315 """,
316 ## # expected output
317 head + r"""
318 Just a test citation \cite{my_cite2006}.
320 \begin{thebibliography}{my\_cite2006}
321 \bibitem[my\_cite2006]{my_cite2006}{
322 The underscore is mishandled.
324 \end{thebibliography}
326 \end{document}
327 """],
331 totest_latex_citations['adjacent_citations'] = [
332 # input
333 ["""\
334 Two non-citations: [MeYou2007]_[YouMe2007]_.
336 Need to be separated for grouping: [MeYou2007]_ [YouMe2007]_.
338 Two spaces (or anything else) for no grouping: [MeYou2007]_ [YouMe2007]_.
340 But a line break should work: [MeYou2007]_
341 [YouMe2007]_.
343 .. [MeYou2007] not.
344 .. [YouMe2007] important.
345 """,
346 # expected output
347 head + r"""
348 Two non-citations: {[}MeYou2007{]}\_{[}YouMe2007{]}\_.
350 Need to be separated for grouping: \cite{MeYou2007,YouMe2007}.
352 Two spaces (or anything else) for no grouping: \cite{MeYou2007} \cite{YouMe2007}.
354 But a line break should work: \cite{MeYou2007,YouMe2007}.
356 \begin{thebibliography}{MeYou2007}
357 \bibitem[MeYou2007]{MeYou2007}{
358 not.
360 \bibitem[YouMe2007]{YouMe2007}{
361 important.
363 \end{thebibliography}
365 \end{document}
366 """],
370 totest['enumerated_lists'] = [
371 # input
372 ["""\
373 1. Item 1.
374 2. Second to the previous item this one will explain
376 a) nothing.
377 b) or some other.
379 3. Third is
381 (I) having pre and postfixes
382 (II) in roman numerals.
383 """,
384 # expected output
385 head + r"""\newcounter{listcnt0}
386 \begin{list}{\arabic{listcnt0}.}
388 \usecounter{listcnt0}
389 \setlength{\rightmargin}{\leftmargin}
392 \item Item 1.
394 \item Second to the previous item this one will explain
395 \end{list}
397 \begin{quote}
398 \setcounter{listcnt0}{0}
399 \begin{list}{\alph{listcnt0})}
401 \usecounter{listcnt0}
402 \setlength{\rightmargin}{\leftmargin}
405 \item nothing.
407 \item or some other.
408 \end{list}
410 \end{quote}
411 \setcounter{listcnt0}{0}
412 \begin{list}{\arabic{listcnt0}.}
414 \usecounter{listcnt0}
415 \addtocounter{listcnt0}{2}
416 \setlength{\rightmargin}{\leftmargin}
419 \item Third is
420 \end{list}
422 \begin{quote}
423 \setcounter{listcnt0}{0}
424 \begin{list}{(\Roman{listcnt0})}
426 \usecounter{listcnt0}
427 \setlength{\rightmargin}{\leftmargin}
430 \item having pre and postfixes
432 \item in roman numerals.
433 \end{list}
435 \end{quote}
437 \end{document}
438 """],
441 # BUG: need to test for quote replacing if language is de (ngerman).
443 totest['quote_mangling'] = [
444 # input
445 ["""
446 Depending on language quotes are converted for latex.
447 Expecting "en" here.
449 Inside literal blocks quotes should be left untouched
450 (use only two quotes in test code makes life easier for
451 the python interpreter running the test)::
454 This is left "untouched" also *this*.
457 .. parsed-literal::
459 should get "quotes" and *italics*.
462 Inline ``literal "quotes"`` should be kept.
463 """,
464 head + r"""
465 Depending on language quotes are converted for latex.
466 Expecting ``en'' here.
468 Inside literal blocks quotes should be left untouched
469 (use only two quotes in test code makes life easier for
470 the python interpreter running the test):
472 \begin{quote}{\ttfamily \raggedright \noindent
473 "{}"\\
474 This~is~left~"untouched"~also~*this*.\\
475 "{}"
477 \end{quote}
479 \begin{quote}{\ttfamily \raggedright \noindent
480 should~get~"quotes"~and~\emph{italics}.
482 \end{quote}
484 Inline \texttt{literal "quotes"} should be kept.
486 \end{document}
487 """],
490 totest['table_caption'] = [
491 # input
492 ["""\
493 .. table:: Foo
495 +-----+-----+
496 | | |
497 +-----+-----+
498 | | |
499 +-----+-----+
500 """,
501 head_table + r"""
502 \setlength{\DUtablewidth}{\linewidth}
503 \begin{longtable}[c]{|p{0.075\DUtablewidth}|p{0.075\DUtablewidth}|}
504 \caption{Foo}\\
505 \hline
506 & \\
507 \hline
508 & \\
509 \hline
510 \end{longtable}
512 \end{document}
513 """],
516 totest['table_class'] = [
517 # input
518 ["""\
519 .. table::
520 :class: borderless
522 +-----+-----+
523 | 1 | 2 |
524 +-----+-----+
525 | 3 | 4 |
526 +-----+-----+
527 """,
528 head_table + r"""
529 \setlength{\DUtablewidth}{\linewidth}
530 \begin{longtable*}[c]{p{0.075\DUtablewidth}p{0.075\DUtablewidth}}
541 \end{longtable*}
543 \end{document}
544 """],
547 # The "[" needs to be protected (otherwise it will be seen as an
548 # option to "\\", "\item", etc. ).
550 totest['brackett_protection'] = [
551 # input
552 ["""\
555 something before to get a end of line.
558 the empty line gets tested too
560 """,
561 head + r"""%
562 \begin{quote}{\ttfamily \raggedright \noindent
563 something~before~to~get~a~end~of~line.\\
564 {[}\\
566 the~empty~line~gets~tested~too\\
569 \end{quote}
571 \end{document}
572 """],
575 totest['raw'] = [
576 [r""".. raw:: latex
578 $E=mc^2$
580 A paragraph.
582 .. |sub| raw:: latex
584 (some raw text)
586 Foo |sub|
587 same paragraph.
588 """,
589 head + r"""
590 $E=mc^2$
592 A paragraph.
594 Foo (some raw text)
595 same paragraph.
597 \end{document}
598 """],
601 totest['title_with_inline_markup'] = [
602 ["""\
603 This is the *Title*
604 ===================
606 This is the *Subtitle*
607 ----------------------
609 This is a *section title*
610 ~~~~~~~~~~~~~~~~~~~~~~~~~
612 This is the *document*.
613 """,
614 head_template.substitute(
615 dict(parts, pdfsetup=parts['pdfsetup'] + r"""\hypersetup{
616 pdftitle={This is the Title},
618 """, titledata=r"""%%% Title Data
619 \title{\phantomsection%
620 This is the \emph{Title}%
621 \label{this-is-the-title}%
622 \\ % subtitle%
623 \large{This is the \emph{Subtitle}}%
624 \label{this-is-the-subtitle}}
625 \author{}
626 \date{}
627 """)) + r"""\maketitle
630 %___________________________________________________________________________
632 \section*{\phantomsection%
633 This is a \emph{section title}%
634 \addcontentsline{toc}{section}{This is a section title}%
635 \label{this-is-a-section-title}%
638 This is the \emph{document}.
640 \end{document}
641 """],
644 totest_stylesheet['two-styles'] = [
645 # input
646 ["""two stylesheet links in the header""",
647 head_template.substitute(dict(parts, stylesheet =
648 r"""\usepackage{data/spam}
649 \input{data/ham.tex}
650 """)) + r"""
651 two stylesheet links in the header
653 \end{document}
654 """],
657 totest_stylesheet_embed['two-styles'] = [
658 # input
659 ["""two stylesheets embedded in the header""",
660 head_template.substitute(dict(parts, stylesheet =
661 r"""% Cannot embed stylesheet 'data/spam.sty':
662 % No such file or directory.
663 % embedded stylesheet: data/ham.tex
664 \newcommand{\ham}{wonderful ham}
666 """)) + r"""
667 two stylesheets embedded in the header
669 \end{document}
670 """],
674 if __name__ == '__main__':
675 import unittest
676 unittest.main(defaultTest='suite')